diff options
author | Mike Frysinger <vapier@google.com> | 2023-07-06 22:54:13 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2023-07-06 22:54:13 +0000 |
commit | 5ee5135be0ad8f5276a8e8d5c179eee09dc41d08 (patch) | |
tree | 352683ba9007342f2e9c9bfc5120c55e044de670 | |
parent | fb4456e8112d0f62397b3447a92eb2373acdc66f (diff) | |
parent | 338af8dede21fe6cfec1b6020ba2a8f5e4b354d7 (diff) | |
download | repohooks-5ee5135be0ad8f5276a8e8d5c179eee09dc41d08.tar.gz |
pre-upload: allow user to run any/all of the fixups am: 338af8dede
Original change: https://android-review.googlesource.com/c/platform/tools/repohooks/+/2621055
Change-Id: I987c446c1533f85d38d5fb39cbb50f0e7d929853
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rwxr-xr-x | pre-upload.py | 98 |
1 files changed, 61 insertions, 37 deletions
diff --git a/pre-upload.py b/pre-upload.py index bdb5b36..59b601a 100755 --- a/pre-upload.py +++ b/pre-upload.py @@ -264,46 +264,70 @@ def _get_project_config(from_git=False): return rh.config.PreUploadSettings(paths=paths, global_paths=global_paths) -def _attempt_fixes(project_results, commit_list): +def _attempt_fixes(projects_results: List[rh.results.ProjectResults]) -> None: """Attempts to fix fixable results.""" - cwd = project_results.workdir - fixup_list = [(x.hook, x.commit, x.fixup_cmd, x.files) - for x in project_results.fixups] - if len(fixup_list) != 1: - # Only single fixes will be attempted, since various fixes might - # interact with each other. + # Filter out any result that has a fixup. + fixups = [] + for project_results in projects_results: + fixups.extend((project_results.workdir, x) + for x in project_results.fixups) + if not fixups: return - hook_name, commit, fixup_cmd, fixup_files = fixup_list[0] - - if commit != commit_list[0]: - # If the commit is not at the top of the stack, git operations might be - # needed and might leave the working directory in a tricky state if the - # fix is attempted to run automatically (e.g. it might require manual - # merge conflict resolution). Refuse to run the fix in those cases. - return - - prompt = (f'An automatic fix can be attempted for the "{hook_name}" hook. ' - 'Do you want to run it?') - if not rh.terminal.boolean_prompt(prompt): - return - - result = rh.utils.run( - fixup_cmd + list(fixup_files), - cwd=cwd, - combine_stdout_stderr=True, - capture_output=True, - check=False, - input='', - ) - if result.returncode: - print(f'Attempt to fix "{hook_name}" for commit "{commit}" failed: ' - f'{result.stdout}', - file=sys.stderr) + if len(fixups) > 1: + banner = f'Multiple fixups ({len(fixups)}) are available.' else: - print('Fix successfully applied. Amend the current commit before ' - 'attempting to upload again.\n', file=sys.stderr) + banner = 'Automated fixups are available.' + print(Output.COLOR.color(Output.COLOR.MAGENTA, banner), file=sys.stderr) + + # If there's more than one fixup available, ask if they want to blindly run + # them all, or prompt for them one-by-one. + mode = None + if len(fixups) > 1: + while True: + response = rh.terminal.str_prompt( + 'What would you like to do', + ('Run (A)ll', 'Run (S)ome', '(D)ry-run', '(N)othing [default]')) + if not response: + print('', file=sys.stderr) + return + if response.startswith('a') or response.startswith('y'): + mode = 'all' + break + elif response.startswith('s'): + mode = 'some' + break + elif response.startswith('d'): + mode = 'dry-run' + break + elif response.startswith('n'): + print('', file=sys.stderr) + return + + # Walk all the fixups and run them one-by-one. + for workdir, result in fixups: + if mode == 'some': + if not rh.terminal.boolean_prompt( + f'Run {result.hook} fixup for {result.commit}' + ): + continue + + cmd = tuple(result.fixup_cmd) + tuple(result.files) + print( + f'\n[{Output.RUNNING}] cd {rh.shell.quote(workdir)} && ' + f'{rh.shell.cmd_to_str(cmd)}', file=sys.stderr) + if mode == 'dry-run': + continue + + cmd_result = rh.utils.run(cmd, cwd=workdir, check=False) + if cmd_result.returncode: + print(f'[{Output.WARNING}] command exited {cmd_result.returncode}', + file=sys.stderr) + else: + print(f'[{Output.PASSED}] great success', file=sys.stderr) + print(f'\n[{Output.FIXUP}] Please amend & rebase your tree before ' + 'attempting to upload again.\n', file=sys.stderr) def _run_project_hooks_in_cwd( project_name: str, @@ -410,8 +434,6 @@ def _run_project_hooks_in_cwd( output.hook_fixups(ret, hook_results) output.hook_finish(hook, duration) - _attempt_fixes(ret, commit_list) - return ret @@ -505,6 +527,8 @@ def _run_projects_hooks( # output. If there were no failures, then the output should be # very minimal, so we don't add it then. print('', file=sys.stderr) + + _attempt_fixes(results) return not any(results) |