Trent Apted | cdc39e3 | 2023-06-15 15:40:53 +1000 | [diff] [blame^] | 1 | # Copyright 2023 The ChromiumOS Authors |
| 2 | # Use of this source code is governed by a BSD-style license that can be |
| 3 | # found in the LICENSE file. |
| 4 | |
| 5 | """Shared helpers for cros analyzer commands (fix, lint, format).""" |
| 6 | |
| 7 | from abc import ABC |
| 8 | import logging |
| 9 | from pathlib import Path |
| 10 | from typing import List |
| 11 | |
| 12 | from chromite.cli import command |
| 13 | from chromite.lib import commandline |
| 14 | from chromite.lib import git |
| 15 | |
| 16 | |
| 17 | def _GetFilesFromCommit(commit: str) -> List[str]: |
| 18 | """Returns ths files changed in the provided git `commit`.""" |
| 19 | return git.RunGit( |
| 20 | None, |
| 21 | ["diff-tree", "--no-commit-id", "--name-only", "-r", commit], |
| 22 | ).stdout.splitlines()[:-1] |
| 23 | |
| 24 | |
| 25 | class AnalyzerCommand(ABC, command.CliCommand): |
| 26 | """Shared argument parsing for cros analyzers (fix, lint, format).""" |
| 27 | |
| 28 | use_dryrun_options = True |
| 29 | # Override base class property to use path filter options. |
| 30 | use_filter_options = True |
| 31 | |
| 32 | @classmethod |
| 33 | def AddParser(cls, parser): |
| 34 | super().AddParser(parser) |
| 35 | parser.add_argument( |
| 36 | "--check", |
| 37 | dest="dryrun", |
| 38 | action="store_true", |
| 39 | help="Display files with errors & exit non-zero", |
| 40 | ) |
| 41 | parser.add_argument( |
| 42 | "--diff", |
| 43 | action="store_true", |
| 44 | help="Display diff instead of fixed content", |
| 45 | ) |
| 46 | parser.add_argument( |
| 47 | "--stdout", |
| 48 | dest="inplace", |
| 49 | action="store_false", |
| 50 | help="Write to stdout", |
| 51 | ) |
| 52 | parser.add_argument( |
| 53 | "-i", |
| 54 | "--inplace", |
| 55 | default=True, |
| 56 | action="store_true", |
| 57 | help="Fix files inplace (default)", |
| 58 | ) |
| 59 | parser.add_argument( |
| 60 | "--commit", |
| 61 | type=str, |
| 62 | help=( |
| 63 | "Use files from git commit instead of on disk. If no files are" |
| 64 | " provided, the list will be obtained from git diff-tree." |
| 65 | ), |
| 66 | ) |
| 67 | parser.add_argument( |
| 68 | "--head", |
| 69 | dest="commit", |
| 70 | action="store_const", |
| 71 | const="HEAD", |
| 72 | help="Alias for --commit HEAD.", |
| 73 | ) |
| 74 | parser.add_argument( |
| 75 | "files", |
| 76 | nargs="*", |
| 77 | type=Path, |
| 78 | help=( |
| 79 | "Files to fix. Directories will be expanded, and if in a git" |
| 80 | " repository, the .gitignore will be respected." |
| 81 | ), |
| 82 | ) |
| 83 | |
| 84 | @classmethod |
| 85 | def ProcessOptions( |
| 86 | cls, |
| 87 | parser: commandline.ArgumentParser, |
| 88 | options: commandline.ArgumentNamespace, |
| 89 | ) -> None: |
| 90 | """Validate & post-process options before freezing.""" |
| 91 | if options.commit and not options.files: |
| 92 | options.files = _GetFilesFromCommit(options.commit) |
| 93 | |
| 94 | if not options.files: |
| 95 | # Running with no arguments is allowed to make the repo upload hook |
| 96 | # simple, but print a warning so that if someone runs this manually |
| 97 | # they are aware that nothing was changed. |
| 98 | logging.warning("No files provided. Doing nothing.") |