-
Notifications
You must be signed in to change notification settings - Fork 3.5k
Expand file tree
/
Copy pathbootstrap.py
More file actions
executable file
·157 lines (127 loc) · 4.63 KB
/
Copy pathbootstrap.py
File metadata and controls
executable file
·157 lines (127 loc) · 4.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#!/usr/bin/env python3
"""Bootstrap script for emscripten developers / git users.
After checking out emscripten there are certain steps that need to be
taken before it can be used. This script enumerates and automates
these steps and is able to run just the steps that are needed based
on the timestamps of various input files (kind of like a dumb version
of a Makefile).
"""
import argparse
import os
import shutil
import subprocess
import sys
__rootdir__ = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, __rootdir__)
STAMP_DIR = os.path.join(__rootdir__, 'out')
# N.b. This script bootstrap.py cannot use 'from tools import shared',
# because shared.py requires that a valid .emscripten config is already
# created. Bootstrap.py needs to be run before an .emscripten config exists.
from tools import utils
def get_stamp_file(action_name):
return os.path.join(STAMP_DIR, action_name.replace(' ', '_') + '.stamp')
def check_deps(name, deps):
stamp_file = get_stamp_file(name)
if not os.path.exists(stamp_file):
return False
for dep in deps:
dep = utils.path_from_root(dep)
if os.path.getmtime(dep) > os.path.getmtime(stamp_file):
return False
return True
def check():
for name, deps, _ in actions:
if not check_deps(name, deps):
utils.exit_with_error(f'emscripten setup is not complete ("{name}" is out-of-date). Run `bootstrap.py` to update')
def ask_yes_no(question):
while True:
try:
reply = input(f"{question} (y/n): ").strip().lower()
except EOFError:
return False
if reply in {'y', 'yes'}:
return True
if reply in {'n', 'no'}:
return False
print("Invalid input. Please enter 'y' or 'n'.")
def maybe_install_hooks():
if os.path.exists('.git/hooks/pre-push'):
print('git hooks already installed; skipping')
return
if os.environ.get('CI') or not sys.stdin.isatty():
# Do nothing when running in CI or non-interactive shell
return
if ask_yes_no('Install emscripten git hooks (see tools/maint/git-hooks)?'):
install_hooks()
def install_hooks():
if not os.path.exists(utils.path_from_root('.git')):
print('--install-git-hooks requires a git checkout')
return 1
dst = utils.path_from_root('.git/hooks')
if not os.path.exists(dst):
os.mkdir(dst)
for src in ('tools/maint/git-hooks/post-checkout', 'tools/maint/git-hooks/pre-push'):
shutil.copy(utils.path_from_root(src), dst)
return 0
def run_cmd(cmd):
orig_exe = cmd[0]
if not os.path.isabs(orig_exe):
cmd[0] = shutil.which(orig_exe)
if not cmd[0]:
utils.exit_with_error(f'command not found: {orig_exe}')
print(' -> %s' % ' '.join(cmd))
subprocess.run(cmd, check=True, text=True, encoding='utf-8', cwd=utils.path_from_root())
actions = [
('npm packages', [
'package.json',
'package-lock.json',
], ['npm', 'ci']),
('create entry points', [
'tools/maint/create_entry_points.py',
'tools/pylauncher/pylauncher.exe',
'tools/maint/run_python.bat',
'tools/maint/run_python.sh',
'tools/maint/run_python.ps1',
], [sys.executable, 'tools/maint/create_entry_points.py']),
('git submodules', [
'test/third_party/posixtestsuite/',
'test/third_party/googletest',
'test/third_party/wasi-test-suite',
], ['git', 'submodule', 'update', '--init']),
('install hooks', [
'tools/maint/git-hooks/post-checkout',
'tools/maint/git-hooks/pre-push',
], maybe_install_hooks),
]
def main(args):
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('-v', '--verbose', action='store_true', help='verbose', default=False)
parser.add_argument('-f', '--force', action='store_true', help='force all actions to run', default=False)
parser.add_argument('-n', '--dry-run', action='store_true', help='dry run', default=False)
parser.add_argument('-i', '--install-git-hooks', action='store_true', help='install emscripten git hooks', default=False)
args = parser.parse_args()
if args.install_git_hooks:
return install_hooks()
for name, deps, action in actions:
if not args.force:
if check_deps(name, deps):
print('Up-to-date: %s' % name)
continue
print('Out-of-date: %s' % name)
if args.dry_run:
if type(action) == list:
action_str = ' '.join(action)
else:
action_str = action.__name__
print(f' (skipping: dry run) -> {action_str}')
continue
if type(action) == list:
run_cmd(action)
else:
action()
utils.safe_ensure_dirs(STAMP_DIR)
stamp_file = get_stamp_file(name)
utils.write_file(stamp_file, 'Timestamp file created by bootstrap.py')
return 0
if __name__ == '__main__':
main(sys.argv[1:])