Ejemplo n.º 1
0
def update_status(paths: Iterable[Path]) -> None:
    if not paths:
        paths = [Path.cwd()]

    for path in paths:
        if git_repo.has_uncommitted_changes(path):
            raise RuntimeError('There are pending changes in the Git repo!')

        updated = 0

        for file in git_repo.list_files(pathspecs=('*.h', '*.cc', '*.cpp'),
                                        repo_path=path):
            orig = file.read_bytes()

            # Replace StatusWithSize constructor
            text = _STATUS_WITH_SIZE_CTOR.sub(_remap_status_with_size, orig)

            # Replace Status and StatusWithSize
            text = _STATUS.sub(_remap_codes, text)

            text = _STATUS_EQUALITY.sub(_remap_equality, text)

            if orig != text:
                updated += 1
                file.write_bytes(text)

    print('Updated', updated, 'files.')
    print('Manually inspect the changes! This script is not perfect.')
Ejemplo n.º 2
0
def source_is_in_build_files(ctx: PresubmitContext):
    """Checks that source files are in the GN and Bazel builds."""
    missing = build.check_builds_for_files(
        _SOURCES_IN_BUILD,
        ctx.paths,
        bazel_dirs=[ctx.root],
        gn_build_files=git_repo.list_files(
            pathspecs=['BUILD.gn', '*BUILD.gn']))

    if missing:
        _LOG.warning(
            'All source files must appear in BUILD and BUILD.gn files')
        raise PresubmitFailure
def _find_package_files(root_dir: Path) -> PackageFiles:
    files = git_repo.list_files(pathspecs=('*.py', '*.toml', '*.cfg'),
                                repo_path=root_dir)

    package_files = PackageFiles([], [], [], [])

    for file in files:
        if file.parent == root_dir:
            if file.name == 'setup.py' or file.suffix != '.py':
                package_files.setup.append(file)
            elif file.stem.startswith('test_') or file.stem.endswith('_test'):
                package_files.tests.append(file)
            else:
                package_files.other.append(file)
        else:
            package_files.sources.append(file)

    return package_files
Ejemplo n.º 4
0
def test_python_packages(ctx: pw_presubmit.PresubmitContext,
                         patterns: Iterable[str] = TEST_PATTERNS) -> None:
    """Finds and runs test files in Python package directories.

    Finds the Python packages containing the affected paths, then searches
    within that package for test files. All files matching the provided patterns
    are executed with Python.
    """
    packages: List[PythonPackage] = []
    for repo in ctx.repos:
        packages += python_packages_containing(ctx.paths, repo=repo)[0]

    if not packages:
        _LOG.info('No Python packages were found.')
        return

    for package in packages:
        for test in list_files(pathspecs=tuple(patterns),
                               repo_path=package.root):
            call('python', test)
Ejemplo n.º 5
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)
Ejemplo n.º 6
0
def source_is_in_build_files(ctx: PresubmitContext):
    """Checks that source files are in the GN and Bazel builds."""
    missing = build.check_builds_for_files(
        _BAZEL_SOURCES_IN_BUILD,
        _GN_SOURCES_IN_BUILD,
        ctx.paths,
        bazel_dirs=[ctx.root],
        gn_build_files=git_repo.list_files(
            pathspecs=['BUILD.gn', '*BUILD.gn']))

    if missing:
        _LOG.warning(
            'All source files must appear in BUILD and BUILD.gn files')
        raise PresubmitFailure

    _run_cmake(ctx)
    cmake_missing = build.check_compile_commands_for_files(
        ctx.output_dir / 'compile_commands.json',
        (f for f in ctx.paths if f.suffix in ('.c', '.cc')))
    if cmake_missing:
        _LOG.warning('The CMake build is missing %d files', len(cmake_missing))
        _LOG.warning('Files missing from CMake:\n%s',
                     '\n'.join(str(f) for f in cmake_missing))
Ejemplo n.º 7
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)