def paths_by_repo(self) -> Dict[Path, List[Path]]: repos = collections.defaultdict(list) for path in self.paths: repos[git_repo.root(path)].append(path) return repos
def run( program: Sequence[Callable], output_directory: Optional[Path], package_root: Path, clear: bool, root: Path = None, repositories: Collection[Path] = (), **other_args, ) -> int: """Processes arguments from add_arguments and runs the presubmit. Args: root: base path from which to run presubmit checks; defaults to the root of the current directory's repository repositories: roots of Git repositories on which to run presubmit checks; defaults to the root of the current directory's repository program: from the --program option output_directory: from --output-directory option package_root: from --package-root option clear: from the --clear option **other_args: remaining arguments defined by by add_arguments Returns: exit code for sys.exit; 0 if succesful, 1 if an error occurred """ if root is None: root = git_repo.root() if not repositories: repositories = [root] if output_directory is None: output_directory = root / '.presubmit' if not package_root: package_root = output_directory / 'packages' _LOG.debug('Using environment at %s', output_directory) if clear: _LOG.info('Clearing presubmit output directory') if output_directory.exists(): shutil.rmtree(output_directory) _LOG.info('Deleted %s', output_directory) return 0 if presubmit.run(program, root, repositories, output_directory=output_directory, package_root=package_root, **other_args): return 0 return 1
def format_paths_in_repo(paths: Collection[Path], exclude: Collection[Pattern[str]], fix: bool, base: str) -> int: """Checks or fixes formatting for files in a Git repo.""" files = [path.resolve() for path in paths if path.is_file()] repo = git_repo.root() if git_repo.is_repo() else None # If this is a Git repo, list the original paths with git ls-files or diff. if repo: _LOG.info( 'Formatting %s', git_repo.describe_files(repo, Path.cwd(), base, paths, exclude)) # Add files from Git and remove duplicates. files = sorted( set(git_repo.list_files(base, paths, exclude)) | set(files)) elif base: _LOG.critical( 'A base commit may only be provided if running from a Git repo') return 1 return format_files(files, fix, repo=repo)
def run(program: Sequence[Callable], root: Path, repos: Collection[Path] = (), base: Optional[str] = None, paths: Sequence[str] = (), exclude: Sequence[Pattern] = (), output_directory: Optional[Path] = None, package_root: Path = None, keep_going: bool = False) -> bool: """Lists files in the current Git repo and runs a Presubmit with them. This changes the directory to the root of the Git repository after listing paths, so all presubmit checks can assume they run from there. The paths argument contains Git pathspecs. If no pathspecs are provided, all paths in all repos are included. If paths to files or directories are provided, only files within those repositories are searched. Patterns are searched across all repositories. For example, if the pathspecs "my_module/" and "*.h", paths under "my_module/" in the containing repo and paths in all repos matching "*.h" will be included in the presubmit. Args: program: list of presubmit check functions to run root: root path of the project repos: paths to the roots of Git repositories to check name: name to use to refer to this presubmit check run base: optional base Git commit to list files against paths: optional list of Git pathspecs to run the checks against exclude: regular expressions for Posix-style paths to exclude output_directory: where to place output files package_root: where to place package files keep_going: whether to continue running checks if an error occurs Returns: True if all presubmit checks succeeded """ repos = [repo.resolve() for repo in repos] for repo in repos: if git_repo.root(repo) != repo: raise ValueError(f'{repo} is not the root of a Git repo; ' 'presubmit checks must be run from a Git repo') pathspecs_by_repo = _process_pathspecs(repos, paths) files: List[Path] = [] for repo, pathspecs in pathspecs_by_repo.items(): files += tools.exclude_paths( exclude, git_repo.list_files(base, pathspecs, repo), root) _LOG.info( 'Checking %s', git_repo.describe_files(repo, repo, base, pathspecs, exclude)) if output_directory is None: output_directory = root / '.presubmit' if package_root is None: package_root = output_directory / 'packages' presubmit = Presubmit( root=root, repos=repos, output_directory=output_directory, paths=files, package_root=package_root, ) if not isinstance(program, Program): program = Program('', program) return presubmit.run(program, keep_going)