TMP / Minor fixes for embed.py and pre-commit.py

- embed.py: fixed --help output
- pre-commit.py: removed whitespace in blank lines
This commit is contained in:
OLEGSHA 2023-04-05 00:24:11 +02:00
parent a227556ae3
commit 2f57a06ebd
2 changed files with 45 additions and 44 deletions

View File

@ -1,7 +1,7 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
usage = \ usage = \
'''Usage: embed.py --cpp OUT_CPP --header OUT_H [--] [INPUT as PATH]... '''Usage: %(me)s --cpp OUT_CPP --header OUT_H [--] [INPUT as PATH]...
Generate C++ source code that includes binary contents of INPUT files. Generate C++ source code that includes binary contents of INPUT files.
Each file in INPUT is stored as a resource: a static array of unsigned char. Each file in INPUT is stored as a resource: a static array of unsigned char.
@ -79,6 +79,7 @@ def main():
fail(f"Unknown option '{arg}'") fail(f"Unknown option '{arg}'")
elif considerOptions and (arg == '-h' or arg == '--help'): elif considerOptions and (arg == '-h' or arg == '--help'):
print(usage % {'me': os.path.basename(sys.argv[0])})
sys.exit(0) sys.exit(0)
elif considerOptions and arg == '--': elif considerOptions and arg == '--':

View File

@ -69,7 +69,7 @@ def long_print_iter(title, it):
print the string (nothing) instead. print the string (nothing) instead.
""" """
print(title + ':') print(title + ':')
if len(it) > 0: if len(it) > 0:
print('\t' + '\n\t'.join(it) + '\n') print('\t' + '\n\t'.join(it) + '\n')
else: else:
@ -79,11 +79,11 @@ def long_print_iter(title, it):
def invoke(*cmd, result_when_dry=None, quiet=True, text=True, stdin=None): def invoke(*cmd, result_when_dry=None, quiet=True, text=True, stdin=None):
"""Execute given system command and return its stdout. If command fails, """Execute given system command and return its stdout. If command fails,
throw CalledProcessError. throw CalledProcessError.
When in verbose mode, log command before execution. If in dry-run mode and When in verbose mode, log command before execution. If in dry-run mode and
result_when_dry is not None, skip execution and return result_when_dry result_when_dry is not None, skip execution and return result_when_dry
instead. instead.
Keyword arguments: Keyword arguments:
result_when_dry -- unless None (default), skip execution and return this result_when_dry -- unless None (default), skip execution and return this
quiet -- if False, print stdout (default True) quiet -- if False, print stdout (default True)
@ -95,15 +95,15 @@ def invoke(*cmd, result_when_dry=None, quiet=True, text=True, stdin=None):
if dry_run and result_when_dry is not None: if dry_run and result_when_dry is not None:
print(my_name + ': skipped: --dry-run') print(my_name + ': skipped: --dry-run')
return result_when_dry return result_when_dry
popen = subprocess.Popen(cmd, popen = subprocess.Popen(cmd,
stdout=subprocess.PIPE, stdout=subprocess.PIPE,
text=text, text=text,
universal_newlines=text, universal_newlines=text,
stdin=subprocess.PIPE if stdin else subprocess.DEVNULL) stdin=subprocess.PIPE if stdin else subprocess.DEVNULL)
stdout, _ = popen.communicate(input=stdin) stdout, _ = popen.communicate(input=stdin)
if text and not quiet: if text and not quiet:
print(stdout, end='') print(stdout, end='')
@ -119,11 +119,11 @@ def get_file_sets():
def git_z(*cmd): def git_z(*cmd):
raw = invoke(*git, *cmd, '-z', text=False) raw = invoke(*git, *cmd, '-z', text=False)
return set(f.decode() for f in raw.split(b'\x00') if len(f) != 0) return set(f.decode() for f in raw.split(b'\x00') if len(f) != 0)
indexed = git_z('diff', '--name-only', '--cached') indexed = git_z('diff', '--name-only', '--cached')
unindexed = git_z('diff', '--name-only') | \ unindexed = git_z('diff', '--name-only') | \
git_z('ls-files', '--other', '--exclude-standard') git_z('ls-files', '--other', '--exclude-standard')
return indexed, unindexed return indexed, unindexed
@ -145,9 +145,9 @@ def run_safety_checks(indexed, unindexed):
def do_restore(): def do_restore():
"""Restore repository and filesystem. Fail if stash not found.""" """Restore repository and filesystem. Fail if stash not found."""
print('Redoing rolled back changes') print('Redoing rolled back changes')
git_list = invoke(*git, 'stash', 'list', '--grep', f"\\b{STASH_NAME}$") git_list = invoke(*git, 'stash', 'list', '--grep', f"\\b{STASH_NAME}$")
if len(git_list) == 0: if len(git_list) == 0:
if dry_run: if dry_run:
stash_name = 'stash@{0}' stash_name = 'stash@{0}'
@ -155,7 +155,7 @@ def do_restore():
fail(f"Cannot restore repository: stash {STASH_NAME} not found") fail(f"Cannot restore repository: stash {STASH_NAME} not found")
else: else:
stash_name, _, _ = git_list.partition(':') stash_name, _, _ = git_list.partition(':')
invoke(*git, 'stash', 'pop', '--index', '--quiet', stash_name, invoke(*git, 'stash', 'pop', '--index', '--quiet', stash_name,
result_when_dry='', quiet=False) result_when_dry='', quiet=False)
@ -164,7 +164,7 @@ def format_project():
"""Format staged files with clang-format-diff.""" """Format staged files with clang-format-diff."""
diff = invoke(*git, 'diff', '-U0', '--no-color', '--relative', 'HEAD', diff = invoke(*git, 'diff', '-U0', '--no-color', '--relative', 'HEAD',
*(f"{d}/*.{e}" for d in src_dirs for e in exts)) *(f"{d}/*.{e}" for d in src_dirs for e in exts))
invoke(*clang_format_diff, '-p1', '-i', '--verbose', invoke(*clang_format_diff, '-p1', '-i', '--verbose',
stdin=diff, result_when_dry='', quiet=False) stdin=diff, result_when_dry='', quiet=False)
@ -172,11 +172,11 @@ def format_project():
def unformat_project(indexed_existing): def unformat_project(indexed_existing):
"""Undo formatting changes introduced by format_project().""" """Undo formatting changes introduced by format_project()."""
print('Undoing formatting changes') print('Undoing formatting changes')
if len(indexed_existing) == 0: if len(indexed_existing) == 0:
print('Nothing to do: all indexed changes are deletions') print('Nothing to do: all indexed changes are deletions')
return return
invoke(*git, 'restore', '--', *indexed_existing) invoke(*git, 'restore', '--', *indexed_existing)
@ -188,39 +188,39 @@ def build_project():
'--parallel', str(parallelism), '--parallel', str(parallelism),
result_when_dry=CLANG_TIDY_CHECK_MARKER, result_when_dry=CLANG_TIDY_CHECK_MARKER,
quiet=False) quiet=False)
if CLANG_TIDY_CHECK_MARKER not in build_log.splitlines(): if CLANG_TIDY_CHECK_MARKER not in build_log.splitlines():
fail('Project build was successful, but clang-tidy did not run. ' fail('Project build was successful, but clang-tidy did not run. '
'Please make sure DEV_MODE is ON and regenerate CMake cache.') 'Please make sure DEV_MODE is ON and regenerate CMake cache.')
print('Success') print('Success')
def pre_commit(): def pre_commit():
"""Run pre-commit checks.""" """Run pre-commit checks."""
if build_root is None: if build_root is None:
fail(f"build-root is not set in {SETTINGS_PATH}. Compile project " fail(f"build-root is not set in {SETTINGS_PATH}. Compile project "
'manually to set this variable properly.') 'manually to set this variable properly.')
if not os.path.exists(build_root): if not os.path.exists(build_root):
fail(f"build-root {build_root} does not exist. Compile project " fail(f"build-root {build_root} does not exist. Compile project "
'manually to set this variable properly.') 'manually to set this variable properly.')
cmakeCache = os.path.join(build_root, 'CMakeCache.txt') cmakeCache = os.path.join(build_root, 'CMakeCache.txt')
if not os.path.exists(cmakeCache): if not os.path.exists(cmakeCache):
fail(f"{cmakeCache} does not exist. build-root is likely invalid. " fail(f"{cmakeCache} does not exist. build-root is likely invalid. "
'Compile project manually to set this variable properly.') 'Compile project manually to set this variable properly.')
indexed, unindexed = get_file_sets() indexed, unindexed = get_file_sets()
indexed_existing = [f for f in indexed if os.path.exists(f)] indexed_existing = [f for f in indexed if os.path.exists(f)]
if verbose_mode: if verbose_mode:
long_print_iter('Indexed changes', indexed) long_print_iter('Indexed changes', indexed)
long_print_iter('Unindexed changes', unindexed) long_print_iter('Unindexed changes', unindexed)
long_print_iter('Indexed changes without deletions', indexed_existing) long_print_iter('Indexed changes without deletions', indexed_existing)
if len(indexed) == 0: if len(indexed) == 0:
fail('No indexed changes. You probably forgot to run `git add .`') fail('No indexed changes. You probably forgot to run `git add .`')
run_safety_checks(indexed, unindexed) run_safety_checks(indexed, unindexed)
undo_formatting = False undo_formatting = False
@ -236,27 +236,27 @@ def pre_commit():
'--message', STASH_NAME, '--message', STASH_NAME,
result_when_dry='', quiet=False) result_when_dry='', quiet=False)
restore = True restore = True
format_project() format_project()
undo_formatting = True undo_formatting = True
build_project() build_project()
undo_formatting = False undo_formatting = False
finally: finally:
if undo_formatting: if undo_formatting:
unformat_project(indexed_existing) unformat_project(indexed_existing)
if restore: if restore:
do_restore() do_restore()
print('Staging formatting changes') print('Staging formatting changes')
if len(indexed_existing) == 0: if len(indexed_existing) == 0:
print('Nothing to do: all indexed changes are deletions') print('Nothing to do: all indexed changes are deletions')
else: else:
invoke(*git, 'add', '--', *indexed_existing, invoke(*git, 'add', '--', *indexed_existing,
result_when_dry='', quiet=False) result_when_dry='', quiet=False)
def get_settings_path(): def get_settings_path():
return os.path.abspath(os.path.join(os.path.dirname(__file__), return os.path.abspath(os.path.join(os.path.dirname(__file__),
SETTINGS_PATH)) SETTINGS_PATH))
@ -288,12 +288,12 @@ def parse_args():
global verbose_mode global verbose_mode
global dry_run global dry_run
global allow_update global allow_update
consider_options = True consider_options = True
action = None action = None
arg_cmake_executable = None arg_cmake_executable = None
arg_build_root = None arg_build_root = None
for arg in sys.argv[1:]: for arg in sys.argv[1:]:
if arg == 'restore' or arg == 'set-build-info' or arg == 'run': if arg == 'restore' or arg == 'set-build-info' or arg == 'run':
if action is not None: if action is not None:
@ -321,23 +321,23 @@ def parse_args():
arg_build_root = arg arg_build_root = arg
else: else:
fail(f"Unknown or unexpected argument '{arg}'") fail(f"Unknown or unexpected argument '{arg}'")
if action is None: if action is None:
fail('No action specified') fail('No action specified')
if action == 'set-build-info' and arg_cmake_executable is None: if action == 'set-build-info' and arg_cmake_executable is None:
fail('No CMake executable given') fail('No CMake executable given')
if action == 'set-build-info' and arg_build_root is None: if action == 'set-build-info' and arg_build_root is None:
fail('No build root given') fail('No build root given')
return action, arg_build_root, arg_cmake_executable return action, arg_build_root, arg_cmake_executable
def load_settings(): def load_settings():
"""Ensure pre-commit-settings.json exists and is loaded into memory.""" """Ensure pre-commit-settings.json exists and is loaded into memory."""
global settings global settings
path = get_settings_path() path = get_settings_path()
if os.path.exists(path): if os.path.exists(path):
with open(path, mode='r') as f: with open(path, mode='r') as f:
@ -362,22 +362,22 @@ def parse_settings():
global cmake global cmake
global clang_format_diff global clang_format_diff
global parallelism global parallelism
build_root = settings['build_root'] build_root = settings['build_root']
parallelism = settings['parallelism'] parallelism = settings['parallelism']
def find_command(hints, settings_name): def find_command(hints, settings_name):
if settings[settings_name] is not None: if settings[settings_name] is not None:
hints = [settings[settings_name]] hints = [settings[settings_name]]
cmds = (hint.split(';') for hint in hints) cmds = (hint.split(';') for hint in hints)
res = next((cmd for cmd in cmds if shutil.which(cmd[0])), None) \ res = next((cmd for cmd in cmds if shutil.which(cmd[0])), None) \
or fail(f"Command {hints[0]} not found. Set {settings_name} " + or fail(f"Command {hints[0]} not found. Set {settings_name} " +
f"in {path} or check PATH") f"in {path} or check PATH")
verbose(f"Found command {hints[0]}:", *(repr(c) for c in res)) verbose(f"Found command {hints[0]}:", *(repr(c) for c in res))
return res return res
git = find_command(['git'], 'git') git = find_command(['git'], 'git')
cmake = find_command(['cmake'], 'cmake') cmake = find_command(['cmake'], 'cmake')
clang_format_diff = find_command(['clang-format-diff-13', clang_format_diff = find_command(['clang-format-diff-13',
@ -391,14 +391,14 @@ if __name__ == '__main__':
verbose_mode = False verbose_mode = False
dry_run = False dry_run = False
allow_update = True allow_update = True
action, arg_build_root, arg_cmake_executable = parse_args() action, arg_build_root, arg_cmake_executable = parse_args()
load_settings() load_settings()
if dry_run: if dry_run:
print('Running in dry mode: no changes to filesystem or git will ' print('Running in dry mode: no changes to filesystem or git will '
'actually be performed') 'actually be performed')
try: try:
if action == 'set-build-info': if action == 'set-build-info':
set_build_info() set_build_info()