-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathvalidate-generated-files.py
More file actions
executable file
·97 lines (77 loc) · 2.43 KB
/
validate-generated-files.py
File metadata and controls
executable file
·97 lines (77 loc) · 2.43 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
#!/usr/bin/env python3
"""
Utility to validate that generated files are up to date.
This is typically useful in contexts where, for one reason or another, generated
files are stored in a version control repository alongside their inputs.
"""
from __future__ import annotations
import sys
import difflib
import argparse
import subprocess
from pathlib import Path
def print_banner(text: str) -> None:
print("--" * 25)
print(text)
print("--" * 25)
def main(args: argparse.Namespace) -> None:
files: list[Path] = args.files
originals = []
for path in files:
try:
originals.append(path.read_bytes())
except IOError:
print(f"{path} could not be read.", file=sys.stderr)
continue
if len(originals) != len(files):
exit(2)
result = subprocess.run(args.command)
if result.returncode:
print("Command failed", file=sys.stderr)
exit(2)
mismatches = False
for path, original_bytes in zip(files, originals):
try:
actual_bytes = path.read_bytes()
except IOError:
mismatches = True
print_banner(f"{path} is missing after running command")
continue
try:
original = original_bytes.decode()
actual = actual_bytes.decode()
diff = ''.join(difflib.unified_diff(
original.splitlines(keepends=True),
actual.splitlines(keepends=True),
fromfile=f"{path} : original",
tofile=f"{path} : generated",
))
if diff:
mismatches = True
print_banner(str(path))
print(diff, end='')
except UnicodeDecodeError:
if actual_bytes != original_bytes:
mismatches = True
print(f"Binary file {path} has changes")
continue
exit(1 if mismatches else 0)
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser()
parser.add_argument(
'--files',
type=Path,
nargs=argparse.ONE_OR_MORE,
required=True,
help="The files to validate.",
)
parser.add_argument(
'command',
metavar='COMMAND_PART',
type=Path,
nargs=argparse.ONE_OR_MORE,
help="The command to run which will produce the files.",
)
return parser.parse_args()
if __name__ == '__main__':
main(parse_args())