aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Frysinger <vapier@google.com>2023-07-06 22:54:13 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2023-07-06 22:54:13 +0000
commit5ee5135be0ad8f5276a8e8d5c179eee09dc41d08 (patch)
tree352683ba9007342f2e9c9bfc5120c55e044de670
parentfb4456e8112d0f62397b3447a92eb2373acdc66f (diff)
parent338af8dede21fe6cfec1b6020ba2a8f5e4b354d7 (diff)
downloadrepohooks-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-xpre-upload.py98
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)