Esempio n. 1
0
    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
Esempio n. 2
0
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
Esempio n. 3
0
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)
Esempio n. 4
0
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)