forked from streamlit/component-template
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdev.py
executable file
·119 lines (96 loc) · 4.22 KB
/
dev.py
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
#!/usr/bin/env python3
"""
A tool to support the maintenance of templates and examples in this repository.
Something like a Makefile but written in Python for easier maintenance.
To list the available commands, run ./dev.py --help.
"""
import argparse
from glob import glob
import shlex
import subprocess
from pathlib import Path
import json
import sys
import shutil
THIS_DIRECTORY = Path(__file__).parent.absolute()
EXAMPLE_DIRECTORIES = (d for d in (THIS_DIRECTORY / 'examples').iterdir() if d.is_dir())
# Utilities function
def run_verbose(cmd_args, *args, **kwargs):
kwargs.setdefault("check", True)
cwd = kwargs.get('cwd')
message_suffix = f" [CWD: {Path(cwd).relative_to(THIS_DIRECTORY)}]" if cwd else ''
print(f"$ {shlex.join(cmd_args)}{message_suffix}", flush=True)
subprocess.run(cmd_args, *args, **kwargs)
# Commands
def cmd_example_npm_install(args):
""""Install all node dependencies for all examples"""
for example_dir in EXAMPLE_DIRECTORIES:
frontend_dir = next(example_dir.glob("*/frontend/"))
run_verbose(["npm", "install"], cwd=str(frontend_dir))
def cmd_example_npm_build(args):
""""Build javascript code for all examples"""
for example_dir in EXAMPLE_DIRECTORIES:
frontend_dir = next(example_dir.glob("*/frontend/"))
run_verbose(["npm", "run", "build"], cwd=str(frontend_dir))
def check_deps(template_package_json, current_package_json):
return (
check_deps_section(template_package_json, current_package_json, 'dependencies') +
check_deps_section(template_package_json, current_package_json, 'devDependencies')
)
def check_deps_section(template_package_json, current_package_json, section_name):
current_package_deps = current_package_json.get(section_name, dict())
template_package_deps = template_package_json.get(section_name, dict())
errors = []
for k, v in template_package_deps.items():
if k not in current_package_deps:
errors.append(f'Missing [{k}:{v}] in {section_name!r} section')
continue
current_version = current_package_deps[k]
if current_version != v:
errors.append(f'Invalid version of {k!r}. Expected: {v!r}. Current: {current_version!r}')
return errors
def cmd_example_check_deps(args):
"""Checks that dependencies of examples match the template"""
tempalte_deps = json.loads((THIS_DIRECTORY / "template" / "my_component" / "frontend" / "package.json").read_text())
examples_package_jsons = sorted(next(d.glob("*/frontend/package.json")) for d in EXAMPLE_DIRECTORIES)
exit_code = 0
for examples_package_json in examples_package_jsons:
example_deps = json.loads(examples_package_json.read_text())
errors = check_deps(tempalte_deps, example_deps)
if errors:
print(f"Found erorr in {examples_package_json.relative_to(THIS_DIRECTORY)!s}")
print("\n".join(errors))
print()
exit_code = 1
if exit_code == 0:
print("No errors")
sys.exit(exit_code)
def cmd_example_python_build_package(args):
"""Build wheeel packages for all examples"""
final_dist_directory = (THIS_DIRECTORY / "dist")
final_dist_directory.mkdir(exist_ok=True)
for example_dir in EXAMPLE_DIRECTORIES:
run_verbose([sys.executable, "setup.py", "bdist_wheel", "--universal", "sdist"], cwd=str(example_dir))
wheel_file = next(example_dir.glob("dist/*.whl"))
shutil.copy(wheel_file, final_dist_directory)
COMMMANDS = {
"examples-npm-install": cmd_example_npm_install,
"examples-npm-build": cmd_example_npm_build,
"examples-check-deps": cmd_example_check_deps,
"examples-python-build-package": cmd_example_python_build_package
}
# Parser
def get_parser():
parser = argparse.ArgumentParser(prog=__file__, description=__doc__)
subparsers = parser.add_subparsers(dest="subcommand", metavar="COMMAND")
subparsers.required = True
for commmand_name, command_fn in COMMMANDS.items():
subparsers.add_parser(commmand_name, help=command_fn.__doc__).set_defaults(func=command_fn)
return parser
# Main function
def main():
parser = get_parser()
args = parser.parse_args()
args.func(args)
if __name__ == "__main__":
main()