diff options
Diffstat (limited to 'Tools')
-rw-r--r-- | Tools/scripts/freeze_modules.py | 58 | ||||
-rw-r--r-- | Tools/scripts/update_file.py | 50 |
2 files changed, 76 insertions, 32 deletions
diff --git a/Tools/scripts/freeze_modules.py b/Tools/scripts/freeze_modules.py index b3ae5c72a9a..aa799d763a5 100644 --- a/Tools/scripts/freeze_modules.py +++ b/Tools/scripts/freeze_modules.py @@ -11,8 +11,9 @@ import posixpath import subprocess import sys import textwrap +import time -from update_file import updating_file_with_tmpfile +from update_file import updating_file_with_tmpfile, update_file_with_tmpfile ROOT_DIR = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) @@ -272,7 +273,7 @@ def resolve_frozen_file(frozenid, destdir=MODULES_DIR): except AttributeError: raise ValueError(f'unsupported frozenid {frozenid!r}') # We use a consistent naming convention for all frozen modules. - frozenfile = frozenid.replace('.', '_') + '.h' + frozenfile = f'{frozenid}.h' if not destdir: return frozenfile return os.path.join(destdir, frozenfile) @@ -542,6 +543,7 @@ def regen_frozen(modules): def regen_makefile(modules): + pyfiles = [] frozenfiles = [] rules = [''] for src in _iter_sources(modules): @@ -549,14 +551,16 @@ def regen_makefile(modules): frozenfiles.append(f'\t\t{header} \\') pyfile = relpath_for_posix_display(src.pyfile, ROOT_DIR) - # Note that we freeze the module to the target .h file - # instead of going through an intermediate file like we used to. - rules.append(f'{header}: Programs/_freeze_module {pyfile}') - rules.append( - (f'\tPrograms/_freeze_module {src.frozenid} ' - f'$(srcdir)/{pyfile} $(srcdir)/{header}')) - rules.append('') - + pyfiles.append(f'\t\t{pyfile} \\') + + freeze = (f'Programs/_freeze_module {src.frozenid} ' + f'$(srcdir)/{pyfile} $(srcdir)/{header}') + rules.extend([ + f'{header}: Programs/_freeze_module {pyfile}', + f'\t{freeze}', + '', + ]) + pyfiles[-1] = pyfiles[-1].rstrip(" \\") frozenfiles[-1] = frozenfiles[-1].rstrip(" \\") print(f'# Updating {os.path.relpath(MAKEFILE)}') @@ -564,8 +568,15 @@ def regen_makefile(modules): lines = infile.readlines() lines = replace_block( lines, - "FROZEN_FILES =", - "# End FROZEN_FILES", + "FROZEN_FILES_IN =", + "# End FROZEN_FILES_IN", + pyfiles, + MAKEFILE, + ) + lines = replace_block( + lines, + "FROZEN_FILES_OUT =", + "# End FROZEN_FILES_OUT", frozenfiles, MAKEFILE, ) @@ -625,13 +636,15 @@ def regen_pcbuild(modules): def freeze_module(modname, pyfile=None, destdir=MODULES_DIR): """Generate the frozen module .h file for the given module.""" + tmpsuffix = f'.{int(time.time())}' for modname, pyfile, ispkg in resolve_modules(modname, pyfile): frozenfile = resolve_frozen_file(modname, destdir) - _freeze_module(modname, pyfile, frozenfile) + _freeze_module(modname, pyfile, frozenfile, tmpsuffix) -def _freeze_module(frozenid, pyfile, frozenfile): - tmpfile = frozenfile + '.new' +def _freeze_module(frozenid, pyfile, frozenfile, tmpsuffix): + tmpfile = f'{frozenfile}.{int(time.time())}' + print(tmpfile) argv = [TOOL, frozenid, pyfile, tmpfile] print('#', ' '.join(os.path.relpath(a) for a in argv), flush=True) @@ -642,7 +655,7 @@ def _freeze_module(frozenid, pyfile, frozenfile): sys.exit(f'ERROR: missing {TOOL}; you need to run "make regen-frozen"') raise # re-raise - os.replace(tmpfile, frozenfile) + update_file_with_tmpfile(frozenfile, tmpfile, create=True) ####################################### @@ -652,15 +665,18 @@ def main(): # Expand the raw specs, preserving order. modules = list(parse_frozen_specs(destdir=MODULES_DIR)) + # Regen build-related files. + regen_makefile(modules) + regen_pcbuild(modules) + # Freeze the target modules. + tmpsuffix = f'.{int(time.time())}' for src in _iter_sources(modules): - _freeze_module(src.frozenid, src.pyfile, src.frozenfile) + _freeze_module(src.frozenid, src.pyfile, src.frozenfile, tmpsuffix) - # Regen build-related files. - regen_manifest(modules) + # Regen files dependent of frozen file details. regen_frozen(modules) - regen_makefile(modules) - regen_pcbuild(modules) + regen_manifest(modules) if __name__ == '__main__': diff --git a/Tools/scripts/update_file.py b/Tools/scripts/update_file.py index 5e22486ec09..b4182c1d0cb 100644 --- a/Tools/scripts/update_file.py +++ b/Tools/scripts/update_file.py @@ -46,19 +46,47 @@ def updating_file_with_tmpfile(filename, tmpfile=None): update_file_with_tmpfile(filename, tmpfile) -def update_file_with_tmpfile(filename, tmpfile): - with open(filename, 'rb') as f: - old_contents = f.read() - with open(tmpfile, 'rb') as f: - new_contents = f.read() - if old_contents != new_contents: +def update_file_with_tmpfile(filename, tmpfile, *, create=False): + try: + targetfile = open(filename, 'rb') + except FileNotFoundError: + if not create: + raise # re-raise + outcome = 'created' os.replace(tmpfile, filename) else: - os.unlink(tmpfile) + with targetfile: + old_contents = targetfile.read() + with open(tmpfile, 'rb') as f: + new_contents = f.read() + # Now compare! + if old_contents != new_contents: + outcome = 'updated' + os.replace(tmpfile, filename) + else: + outcome = 'same' + os.unlink(tmpfile) + return outcome if __name__ == '__main__': - if len(sys.argv) != 3: - print("Usage: %s <path to be updated> <path with new contents>" % (sys.argv[0],)) - sys.exit(1) - update_file_with_tmpfile(sys.argv[1], sys.argv[2]) + import argparse + parser = argparse.ArgumentParser() + parser.add_argument('--create', action='store_true') + parser.add_argument('--exitcode', action='store_true') + parser.add_argument('filename', help='path to be updated') + parser.add_argument('tmpfile', help='path with new contents') + args = parser.parse_args() + kwargs = vars(args) + setexitcode = kwargs.pop('exitcode') + + outcome = update_file_with_tmpfile(**kwargs) + if setexitcode: + if outcome == 'same': + sys.exit(0) + elif outcome == 'updated': + sys.exit(1) + elif outcome == 'created': + sys.exit(2) + else: + raise NotImplementedError |