2
"""Generate code for wandb SDK.
5
./tools/generate-tool.py --generate
6
./tools/generate-tool.py --check
7
./tools/generate-tool.py --generate --check
8
./tools/generate-tool.py --generate --check wandb/sdk/lib/_wburls_generated.py
17
from pathlib import Path, PurePath
18
from typing import Iterator, List
20
parser = argparse.ArgumentParser()
21
parser.add_argument("--generate", action="store_true", help="generate files")
30
"--check", action="store_true", help="check if generated files are up-to-date"
32
parser.add_argument("files", nargs="*")
33
args = parser.parse_args()
36
GENERATE_SUFFIX = "_generate.py"
37
GENERATED_SUFFIX = "_generated.py"
40
def get_paths() -> List[PurePath]:
41
paths: List[PurePath] = []
43
exclude_dirs = {"vendor", "__pycache__"}
44
root_dir = Path(__file__).resolve().parent.parent / "wandb"
45
for base, subdirs, files in os.walk(root_dir):
46
# Don't walk into excluded subdirectories
47
subdirs[:] = list(set(subdirs) - exclude_dirs)
49
if fname.endswith(GENERATE_SUFFIX):
50
paths.append(PurePath(base, fname))
56
def generate_file(generate_path: Path, output_path: Path) -> None:
57
status, output = subprocess.getstatusoutput(f"python {generate_path}")
58
assert status == 0, f"Error: {output}"
59
with open(output_path, "w") as f:
60
f.write("# DO NOT EDIT -- GENERATED BY: `generate-tool.py --generate`")
64
def generate_files(paths: List[PurePath]) -> None:
66
output_path = p.parent / str(p).replace(GENERATE_SUFFIX, GENERATED_SUFFIX)
67
print(f"INFO: Generating {output_path}...")
68
generate_file(p, output_path)
71
def format_file(filename: Path) -> None:
72
status, output = subprocess.getstatusoutput(f"black {filename}")
73
assert status == 0, f"Error: {output}"
76
def format_files(paths: List[PurePath]) -> None:
78
output_path = p.parent / str(p).replace(GENERATE_SUFFIX, GENERATED_SUFFIX)
79
print(f"INFO: Formatting {output_path}...")
80
format_file(output_path)
83
@contextlib.contextmanager
84
def temp_fname() -> Iterator[PurePath]:
86
f = tempfile.NamedTemporaryFile(delete=False)
94
def check_files(paths: List[PurePath]) -> None:
96
generated_path = p.parent / str(p).replace(GENERATE_SUFFIX, GENERATED_SUFFIX)
97
print(f"INFO: Checking {generated_path}...")
98
with temp_fname() as temp_file:
99
generate_file(p, temp_file)
100
format_file(temp_file)
102
generated_path, temp_file
103
), f"expected: {open(temp_file).read()}"
107
path_list = get_paths()
110
generate_files(path_list)
112
format_files(path_list)
115
check_files(path_list)
118
if __name__ == "__main__":