Пример #1
0
def try_repo(args):
    with tmpdir() as tempdir:
        repo, ref = _repo_ref(tempdir, args.repo, args.ref)

        store = Store(tempdir)
        if args.hook:
            hooks = [{'id': args.hook}]
        else:
            repo_path = store.clone(repo, ref)
            manifest = load_manifest(os.path.join(repo_path, C.MANIFEST_FILE))
            manifest = sorted(manifest, key=lambda hook: hook['id'])
            hooks = [{'id': hook['id']} for hook in manifest]

        items = (('repo', repo), ('rev', ref), ('hooks', hooks))
        config = {'repos': [collections.OrderedDict(items)]}
        config_s = ordered_dump(config, **C.YAML_DUMP_KWARGS)

        config_filename = os.path.join(tempdir, C.CONFIG_FILE)
        with open(config_filename, 'w') as cfg:
            cfg.write(config_s)

        output.write_line('=' * 79)
        output.write_line('Using config:')
        output.write_line('=' * 79)
        output.write(config_s)
        output.write_line('=' * 79)

        return run(config_filename, store, args)
Пример #2
0
def try_repo(args):
    ref = args.ref or git.head_rev(args.repo)

    with tmpdir() as tempdir:
        if args.hook:
            hooks = [{'id': args.hook}]
        else:
            repo_path = Store(tempdir).clone(args.repo, ref)
            manifest = load_manifest(os.path.join(repo_path, C.MANIFEST_FILE))
            manifest = sorted(manifest, key=lambda hook: hook['id'])
            hooks = [{'id': hook['id']} for hook in manifest]

        items = (('repo', args.repo), ('rev', ref), ('hooks', hooks))
        config = {'repos': [collections.OrderedDict(items)]}
        config_s = ordered_dump(config, **C.YAML_DUMP_KWARGS)

        config_filename = os.path.join(tempdir, C.CONFIG_FILE)
        with open(config_filename, 'w') as cfg:
            cfg.write(config_s)

        output.write_line('=' * 79)
        output.write_line('Using config:')
        output.write_line('=' * 79)
        output.write(config_s)
        output.write_line('=' * 79)

        runner = Runner('.', config_filename, store_dir=tempdir)
        return run(runner, args)
Пример #3
0
def try_repo(args: argparse.Namespace) -> int:
    with tmpdir() as tempdir:
        repo, ref = _repo_ref(tempdir, args.repo, args.ref)

        store = Store(tempdir)
        if args.hook:
            hooks = [{'id': args.hook}]
        else:
            repo_path = store.clone(repo, ref)
            manifest = load_manifest(os.path.join(repo_path, C.MANIFEST_FILE))
            manifest = sorted(manifest, key=lambda hook: hook['id'])
            hooks = [{'id': hook['id']} for hook in manifest]

        config = {'repos': [{'repo': repo, 'rev': ref, 'hooks': hooks}]}
        config_s = yaml_dump(config)

        config_filename = os.path.join(tempdir, C.CONFIG_FILE)
        with open(config_filename, 'w') as cfg:
            cfg.write(config_s)

        output.write_line('=' * 79)
        output.write_line('Using config:')
        output.write_line('=' * 79)
        output.write(config_s)
        output.write_line('=' * 79)

        return run(config_filename, store, args)
Пример #4
0
def try_repo(args):
    ref = args.ref or git.head_sha(args.repo)

    with tmpdir() as tempdir:
        if args.hook:
            hooks = [{'id': args.hook}]
        else:
            manifest = Manifest(Store(tempdir).clone(args.repo, ref))
            hooks = [{'id': hook_id} for hook_id in sorted(manifest.hooks)]

        items = (('repo', args.repo), ('sha', ref), ('hooks', hooks))
        config = {'repos': [collections.OrderedDict(items)]}
        config_s = ordered_dump(config, **C.YAML_DUMP_KWARGS)

        config_filename = os.path.join(tempdir, C.CONFIG_FILE)
        with open(config_filename, 'w') as cfg:
            cfg.write(config_s)

        output.write_line('=' * 79)
        output.write_line('Using config:')
        output.write_line('=' * 79)
        output.write(config_s)
        output.write_line('=' * 79)

        runner = Runner('.', config_filename, store_dir=tempdir)
        return run(runner, args)
Пример #5
0
def try_repo(args: argparse.Namespace) -> int:
    with tmpdir() as tempdir:
        repo, ref = _repo_ref(tempdir, args.repo, args.ref)

        store = Store(tempdir)
        if args.hook:
            hooks = [{"id": args.hook}]
        else:
            repo_path = store.clone(repo, ref)
            manifest = load_manifest(os.path.join(repo_path, C.MANIFEST_FILE))
            manifest = sorted(manifest, key=lambda hook: hook["id"])
            hooks = [{"id": hook["id"]} for hook in manifest]

        config = {"repos": [{"repo": repo, "rev": ref, "hooks": hooks}]}
        config_s = yaml_dump(config)

        config_filename = os.path.join(tempdir, C.CONFIG_FILE)
        with open(config_filename, "w") as cfg:
            cfg.write(config_s)

        output.write_line("=" * 79)
        output.write_line("Using config:")
        output.write_line("=" * 79)
        output.write(config_s)
        output.write_line("=" * 79)

        return run(config_filename, store, args)
Пример #6
0
def _process_filename_by_line(pattern: Pattern[bytes], filename: str) -> int:
    retv = 0
    with open(filename, "rb") as f:
        for line_no, line in enumerate(f, start=1):
            if pattern.search(line):
                retv = 1
                output.write(f"{filename}:{line_no}:")
                output.write_line_b(line.rstrip(b"\r\n"))
    return retv
Пример #7
0
def _process_filename_by_line(pattern, filename):
    retv = 0
    with open(filename, 'rb') as f:
        for line_no, line in enumerate(f, start=1):
            if pattern.search(line):
                retv = 1
                output.write('{}:{}:'.format(filename, line_no))
                output.write_line(line.rstrip(b'\r\n'))
    return retv
Пример #8
0
def _process_filename_by_line(pattern, filename):
    retv = 0
    with open(filename, 'rb') as f:
        for line_no, line in enumerate(f, start=1):
            if pattern.search(line):
                retv = 1
                output.write('{}:{}:'.format(filename, line_no))
                output.write_line(line.rstrip(b'\r\n'))
    return retv
Пример #9
0
def _log_and_exit(msg, exc, formatted):
    error_msg = b''.join((
        five.to_bytes(msg), b': ',
        five.to_bytes(type(exc).__name__), b': ',
        _to_bytes(exc), b'\n',
    ))
    output.write(error_msg)
    output.write_line('Check the log at ~/.pre-commit/pre-commit.log')
    store = Store()
    store.require_created()
    with open(os.path.join(store.directory, 'pre-commit.log'), 'wb') as log:
        output.write(error_msg, stream=log)
        output.write_line(formatted, stream=log)
    raise PreCommitSystemExit(1)
Пример #10
0
def autoupdate(
        config_file: str,
        store: Store,
        tags_only: bool,
        freeze: bool,
        repos: Sequence[str] = (),
) -> int:
    """Auto-update the pre-commit config to the latest versions of repos."""
    migrate_config(config_file, quiet=True)
    retv = 0
    rev_infos: List[Optional[RevInfo]] = []
    changed = False

    config = load_config(config_file)
    for repo_config in config['repos']:
        if repo_config['repo'] in {LOCAL, META}:
            continue

        info = RevInfo.from_config(repo_config)
        if repos and info.repo not in repos:
            rev_infos.append(None)
            continue

        output.write(f'Updating {info.repo} ... ')
        new_info = info.update(tags_only=tags_only, freeze=freeze)
        try:
            _check_hooks_still_exist_at_rev(repo_config, new_info, store)
        except RepositoryCannotBeUpdatedError as error:
            output.write_line(error.args[0])
            rev_infos.append(None)
            retv = 1
            continue

        if new_info.rev != info.rev:
            changed = True
            if new_info.frozen:
                updated_to = f'{new_info.frozen} (frozen)'
            else:
                updated_to = new_info.rev
            msg = f'updating {info.rev} -> {updated_to}.'
            output.write_line(msg)
            rev_infos.append(new_info)
        else:
            output.write_line('already up to date.')
            rev_infos.append(None)

    if changed:
        _write_new_config(config_file, rev_infos)

    return retv
Пример #11
0
def _log_and_exit(msg, exc, formatted):
    error_msg = b''.join((
        five.to_bytes(msg), b': ',
        five.to_bytes(type(exc).__name__), b': ',
        _to_bytes(exc), b'\n',
    ))
    output.write(error_msg)
    store = Store()
    log_path = os.path.join(store.directory, 'pre-commit.log')
    output.write_line('Check the log at {}'.format(log_path))
    with open(log_path, 'wb') as log:
        output.write(error_msg, stream=log)
        output.write_line(formatted, stream=log)
    raise SystemExit(1)
Пример #12
0
def _log_and_exit(msg, exc, formatted):
    error_msg = b''.join((
        five.to_bytes(msg), b': ',
        five.to_bytes(type(exc).__name__), b': ',
        _to_bytes(exc), b'\n',
    ))
    output.write(error_msg)
    output.write_line('Check the log at ~/.pre-commit/pre-commit.log')
    store = Store()
    store.require_created()
    with io.open(os.path.join(store.directory, 'pre-commit.log'), 'wb') as log:
        output.write(error_msg, stream=log)
        output.write_line(formatted, stream=log)
    raise PreCommitSystemExit(1)
Пример #13
0
def _process_filename_at_once(pattern: Pattern[bytes], filename: str) -> int:
    retv = 0
    with open(filename, "rb") as f:
        contents = f.read()
        match = pattern.search(contents)
        if match:
            retv = 1
            line_no = contents[: match.start()].count(b"\n")
            output.write(f"{filename}:{line_no + 1}:")

            matched_lines = match[0].split(b"\n")
            matched_lines[0] = contents.split(b"\n")[line_no]

            output.write_line_b(b"\n".join(matched_lines))
    return retv
Пример #14
0
def _process_filename_at_once(pattern, filename):
    retv = 0
    with open(filename, 'rb') as f:
        contents = f.read()
        match = pattern.search(contents)
        if match:
            retv = 1
            line_no = contents[:match.start()].count(b'\n')
            output.write('{}:{}:'.format(filename, line_no + 1))

            matched_lines = match.group().split(b'\n')
            matched_lines[0] = contents.split(b'\n')[line_no]

            output.write_line(b'\n'.join(matched_lines))
    return retv
Пример #15
0
def _process_filename_at_once(pattern, filename):
    retv = 0
    with open(filename, 'rb') as f:
        contents = f.read()
        match = pattern.search(contents)
        if match:
            retv = 1
            line_no = contents[:match.start()].count(b'\n')
            output.write('{}:{}:'.format(filename, line_no + 1))

            matched_lines = match.group().split(b'\n')
            matched_lines[0] = contents.split(b'\n')[line_no]

            output.write_line(b'\n'.join(matched_lines))
    return retv
Пример #16
0
def autoupdate(config_file, store, tags_only, repos=()):
    """Auto-update the pre-commit config to the latest versions of repos."""
    migrate_config(config_file, quiet=True)
    retv = 0
    output_repos = []
    changed = False

    input_config = load_config(config_file)

    for repo_config in input_config['repos']:
        if (
            repo_config['repo'] in {LOCAL, META} or
            # Skip updating any repo_configs that aren't for the specified repo
            repos and repo_config['repo'] not in repos
        ):
            output_repos.append(repo_config)
            continue
        output.write('Updating {}...'.format(repo_config['repo']))
        try:
            new_repo_config = _update_repo(repo_config, store, tags_only)
        except RepositoryCannotBeUpdatedError as error:
            output.write_line(error.args[0])
            output_repos.append(repo_config)
            retv = 1
            continue

        if new_repo_config['rev'] != repo_config['rev']:
            changed = True
            output.write_line(
                'updating {} -> {}.'.format(
                    repo_config['rev'], new_repo_config['rev'],
                ),
            )
            output_repos.append(new_repo_config)
        else:
            output.write_line('already up to date.')
            output_repos.append(repo_config)

    if changed:
        output_config = input_config.copy()
        output_config['repos'] = output_repos
        _write_new_config_file(config_file, output_config)

    return retv
Пример #17
0
def autoupdate(runner):
    """Auto-update the pre-commit config to the latest versions of repos."""
    retv = 0
    output_configs = []
    changed = False

    input_configs = load_config(
        runner.config_file_path,
        load_strategy=ordered_load,
    )

    for repo_config in input_configs:
        if is_local_hooks(repo_config):
            output_configs.append(repo_config)
            continue
        output.write('Updating {}...'.format(repo_config['repo']))
        try:
            new_repo_config = _update_repository(repo_config, runner)
        except RepositoryCannotBeUpdatedError as error:
            output.write_line(error.args[0])
            output_configs.append(repo_config)
            retv = 1
            continue

        if new_repo_config['sha'] != repo_config['sha']:
            changed = True
            output.write_line('updating {} -> {}.'.format(
                repo_config['sha'], new_repo_config['sha'],
            ))
            output_configs.append(new_repo_config)
        else:
            output.write_line('already up to date.')
            output_configs.append(repo_config)

    if changed:
        with open(runner.config_file_path, 'w') as config_file:
            config_file.write(
                ordered_dump(
                    remove_defaults(output_configs, CONFIG_JSON_SCHEMA),
                    **C.YAML_DUMP_KWARGS
                )
            )

    return retv
Пример #18
0
def autoupdate(config_file, store, tags_only, freeze, repos=()):
    """Auto-update the pre-commit config to the latest versions of repos."""
    migrate_config(config_file, quiet=True)
    retv = 0
    rev_infos = []
    changed = False

    config = load_config(config_file)
    for repo_config in config['repos']:
        if repo_config['repo'] in {LOCAL, META}:
            continue

        info = RevInfo.from_config(repo_config)
        if repos and info.repo not in repos:
            rev_infos.append(None)
            continue

        output.write('Updating {} ... '.format(info.repo))
        new_info = info.update(tags_only=tags_only, freeze=freeze)
        try:
            _check_hooks_still_exist_at_rev(repo_config, new_info, store)
        except RepositoryCannotBeUpdatedError as error:
            output.write_line(error.args[0])
            rev_infos.append(None)
            retv = 1
            continue

        if new_info.rev != info.rev:
            changed = True
            if new_info.frozen:
                updated_to = '{} (frozen)'.format(new_info.frozen)
            else:
                updated_to = new_info.rev
            msg = 'updating {} -> {}.'.format(info.rev, updated_to)
            output.write_line(msg)
            rev_infos.append(new_info)
        else:
            output.write_line('already up to date.')
            rev_infos.append(None)

    if changed:
        _write_new_config(config_file, rev_infos)

    return retv
Пример #19
0
def autoupdate(config_file, store, tags_only, repos=()):
    """Auto-update the pre-commit config to the latest versions of repos."""
    migrate_config(config_file, quiet=True)
    retv = 0
    output_repos = []
    changed = False

    input_config = load_config(config_file)

    for repo_config in input_config['repos']:
        if (
            repo_config['repo'] in {LOCAL, META} or
            # Skip updating any repo_configs that aren't for the specified repo
            repos and repo_config['repo'] not in repos
        ):
            output_repos.append(repo_config)
            continue
        output.write('Updating {}...'.format(repo_config['repo']))
        try:
            new_repo_config = _update_repo(repo_config, store, tags_only)
        except RepositoryCannotBeUpdatedError as error:
            output.write_line(error.args[0])
            output_repos.append(repo_config)
            retv = 1
            continue

        if new_repo_config['rev'] != repo_config['rev']:
            changed = True
            output.write_line(
                'updating {} -> {}.'.format(
                    repo_config['rev'], new_repo_config['rev'],
                ),
            )
            output_repos.append(new_repo_config)
        else:
            output.write_line('already up to date.')
            output_repos.append(repo_config)

    if changed:
        output_config = input_config.copy()
        output_config['repos'] = output_repos
        _write_new_config_file(config_file, output_config)

    return retv
Пример #20
0
def autoupdate(runner):
    """Auto-update the pre-commit config to the latest versions of repos."""
    retv = 0
    output_configs = []
    changed = False

    input_configs = load_config(
        runner.config_file_path,
        load_strategy=ordered_load,
    )

    for repo_config in input_configs:
        if is_local_hooks(repo_config):
            output_configs.append(repo_config)
            continue
        output.write('Updating {}...'.format(repo_config['repo']))
        try:
            new_repo_config = _update_repository(repo_config, runner)
        except RepositoryCannotBeUpdatedError as error:
            output.write_line(error.args[0])
            output_configs.append(repo_config)
            retv = 1
            continue

        if new_repo_config['sha'] != repo_config['sha']:
            changed = True
            output.write_line('updating {} -> {}.'.format(
                repo_config['sha'],
                new_repo_config['sha'],
            ))
            output_configs.append(new_repo_config)
        else:
            output.write_line('already up to date.')
            output_configs.append(repo_config)

    if changed:
        with open(runner.config_file_path, 'w') as config_file:
            config_file.write(
                ordered_dump(
                    remove_defaults(output_configs, CONFIG_JSON_SCHEMA),
                    **C.YAML_DUMP_KWARGS))

    return retv
Пример #21
0
def autoupdate(runner, tags_only, repo=None):
    """Auto-update the pre-commit config to the latest versions of repos."""
    migrate_config(runner, quiet=True)
    retv = 0
    output_repos = []
    changed = False

    input_config = load_config(runner.config_file_path)

    for repo_config in input_config['repos']:
        if (is_local_repo(repo_config) or is_meta_repo(repo_config) or
                # Skip updating any repo_configs that aren't for the specified repo
                repo and repo != repo_config['repo']):
            output_repos.append(repo_config)
            continue
        output.write('Updating {}...'.format(repo_config['repo']))
        try:
            new_repo_config = _update_repo(repo_config, runner, tags_only)
        except RepositoryCannotBeUpdatedError as error:
            output.write_line(error.args[0])
            output_repos.append(repo_config)
            retv = 1
            continue

        if new_repo_config['sha'] != repo_config['sha']:
            changed = True
            output.write_line('updating {} -> {}.'.format(
                repo_config['sha'],
                new_repo_config['sha'],
            ))
            output_repos.append(new_repo_config)
        else:
            output.write_line('already up to date.')
            output_repos.append(repo_config)

    if changed:
        output_config = input_config.copy()
        output_config['repos'] = output_repos
        _write_new_config_file(runner.config_file_path, output_config)

    return retv
Пример #22
0
def autoupdate(runner, tags_only):
    """Auto-update the pre-commit config to the latest versions of repos."""
    retv = 0
    output_configs = []
    changed = False

    input_configs = load_config(
        runner.config_file_path,
        load_strategy=ordered_load,
    )

    for repo_config in input_configs:
        if is_local_repo(repo_config):
            output_configs.append(repo_config)
            continue
        output.write('Updating {}...'.format(repo_config['repo']))
        try:
            new_repo_config = _update_repo(repo_config, runner, tags_only)
        except RepositoryCannotBeUpdatedError as error:
            output.write_line(error.args[0])
            output_configs.append(repo_config)
            retv = 1
            continue

        if new_repo_config['sha'] != repo_config['sha']:
            changed = True
            output.write_line('updating {} -> {}.'.format(
                repo_config['sha'],
                new_repo_config['sha'],
            ))
            output_configs.append(new_repo_config)
        else:
            output.write_line('already up to date.')
            output_configs.append(repo_config)

    if changed:
        _write_new_config_file(runner.config_file_path, output_configs)

    return retv
Пример #23
0
def autoupdate(runner, tags_only):
    """Auto-update the pre-commit config to the latest versions of repos."""
    migrate_config(runner, quiet=True)
    retv = 0
    output_repos = []
    changed = False

    input_config = load_config(runner.config_file_path)

    for repo_config in input_config['repos']:
        if is_local_repo(repo_config):
            output_repos.append(repo_config)
            continue
        output.write('Updating {}...'.format(repo_config['repo']))
        try:
            new_repo_config = _update_repo(repo_config, runner, tags_only)
        except RepositoryCannotBeUpdatedError as error:
            output.write_line(error.args[0])
            output_repos.append(repo_config)
            retv = 1
            continue

        if new_repo_config['sha'] != repo_config['sha']:
            changed = True
            output.write_line('updating {} -> {}.'.format(
                repo_config['sha'], new_repo_config['sha'],
            ))
            output_repos.append(new_repo_config)
        else:
            output.write_line('already up to date.')
            output_repos.append(repo_config)

    if changed:
        output_config = input_config.copy()
        output_config['repos'] = output_repos
        _write_new_config_file(runner.config_file_path, output_config)

    return retv
Пример #24
0
def test_output_write_writes():
    fake_stream = mock.Mock()
    output.write('hello world', fake_stream)
    assert fake_stream.write.call_count == 1
Пример #25
0
def test_output_write_writes():
    fake_stream = mock.Mock()
    output.write('hello world', fake_stream)
    assert fake_stream.write.call_count == 1
Пример #26
0
def _run_single_hook(hook, repo, args, skips, cols):
    filenames = get_filenames(args, hook['files'], hook['exclude'])
    filenames = filter_filenames_by_types(
        filenames,
        hook['types'],
        hook['exclude_types'],
    )
    if hook['id'] in skips:
        output.write(
            get_hook_message(
                _hook_msg_start(hook, args.verbose),
                end_msg=SKIPPED,
                end_color=color.YELLOW,
                use_color=args.color,
                cols=cols,
            ))
        return 0
    elif not filenames and not hook['always_run']:
        output.write(
            get_hook_message(
                _hook_msg_start(hook, args.verbose),
                postfix=NO_FILES,
                end_msg=SKIPPED,
                end_color=color.TURQUOISE,
                use_color=args.color,
                cols=cols,
            ))
        return 0

    # Print the hook and the dots first in case the hook takes hella long to
    # run.
    output.write(
        get_hook_message(
            _hook_msg_start(hook, args.verbose),
            end_len=6,
            cols=cols,
        ))
    sys.stdout.flush()

    diff_before = cmd_output(
        'git',
        'diff',
        '--no-ext-diff',
        retcode=None,
        encoding=None,
    )
    retcode, stdout, stderr = repo.run_hook(
        hook,
        tuple(filenames) if hook['pass_filenames'] else (),
    )
    diff_after = cmd_output(
        'git',
        'diff',
        '--no-ext-diff',
        retcode=None,
        encoding=None,
    )

    file_modifications = diff_before != diff_after

    # If the hook makes changes, fail the commit
    if file_modifications:
        retcode = 1

    if retcode:
        retcode = 1
        print_color = color.RED
        pass_fail = 'Failed'
    else:
        retcode = 0
        print_color = color.GREEN
        pass_fail = 'Passed'

    output.write_line(color.format_color(pass_fail, print_color, args.color))

    if (stdout or stderr or file_modifications) and (retcode or args.verbose):
        output.write_line('hookid: {}\n'.format(hook['id']))

        # Print a message if failing due to file modifications
        if file_modifications:
            output.write('Files were modified by this hook.')

            if stdout or stderr:
                output.write_line(' Additional output:')

            output.write_line()

        for out in (stdout, stderr):
            assert type(out) is bytes, type(out)
            if out.strip():
                output.write_line(out.strip(), logfile_name=hook['log_file'])
        output.write_line()

    return retcode
Пример #27
0
def _run_single_hook(
    classifier: Classifier,
    hook: Hook,
    skips: Set[str],
    cols: int,
    diff_before: bytes,
    verbose: bool,
    use_color: bool,
) -> Tuple[bool, bytes]:
    filenames = classifier.filenames_for_hook(hook)

    if hook.id in skips or hook.alias in skips:
        output.write(
            _full_msg(
                start=hook.name,
                end_msg=SKIPPED,
                end_color=color.YELLOW,
                use_color=use_color,
                cols=cols,
            ), )
        duration = None
        retcode = 0
        diff_after = diff_before
        files_modified = False
        out = b''
    elif not filenames and not hook.always_run:
        output.write(
            _full_msg(
                start=hook.name,
                postfix=NO_FILES,
                end_msg=SKIPPED,
                end_color=color.TURQUOISE,
                use_color=use_color,
                cols=cols,
            ), )
        duration = None
        retcode = 0
        diff_after = diff_before
        files_modified = False
        out = b''
    else:
        # print hook and dots first in case the hook takes a while to run
        output.write(_start_msg(start=hook.name, end_len=6, cols=cols))

        if not hook.pass_filenames:
            filenames = ()
        time_before = time.time()
        language = languages[hook.language]
        retcode, out = language.run_hook(hook, filenames, use_color)
        duration = round(time.time() - time_before, 2) or 0
        diff_after = _get_diff()

        # if the hook makes changes, fail the commit
        files_modified = diff_before != diff_after

        if retcode or files_modified:
            print_color = color.RED
            status = 'Failed'
        else:
            print_color = color.GREEN
            status = 'Passed'

        output.write_line(color.format_color(status, print_color, use_color))

    if verbose or hook.verbose or retcode or files_modified:
        _subtle_line(f'- hook id: {hook.id}', use_color)

        if (verbose or hook.verbose) and duration is not None:
            _subtle_line(f'- duration: {duration}s', use_color)

        if retcode:
            _subtle_line(f'- exit code: {retcode}', use_color)

        # Print a message if failing due to file modifications
        if files_modified:
            _subtle_line('- files were modified by this hook', use_color)

        if out.strip():
            output.write_line()
            output.write_line_b(out.strip(), logfile_name=hook.log_file)
            output.write_line()

    return files_modified or bool(retcode), diff_after
Пример #28
0
def _run_single_hook(filenames, hook, repo, args, skips, cols):
    include, exclude = hook['files'], hook['exclude']
    filenames = _filter_by_include_exclude(filenames, include, exclude)
    types, exclude_types = hook['types'], hook['exclude_types']
    filenames = _filter_by_types(filenames, types, exclude_types)

    if hook['language'] == 'pcre':
        logger.warning(
            '`{}` (from {}) uses the deprecated pcre language.\n'
            'The pcre language is scheduled for removal in pre-commit 2.x.\n'
            'The pygrep language is a more portable (and usually drop-in) '
            'replacement.'.format(hook['id'], repo.repo_config['repo']), )

    if hook['id'] in skips:
        output.write(
            get_hook_message(
                _hook_msg_start(hook, args.verbose),
                end_msg=SKIPPED,
                end_color=color.YELLOW,
                use_color=args.color,
                cols=cols,
            ))
        return 0
    elif not filenames and not hook['always_run']:
        output.write(
            get_hook_message(
                _hook_msg_start(hook, args.verbose),
                postfix=NO_FILES,
                end_msg=SKIPPED,
                end_color=color.TURQUOISE,
                use_color=args.color,
                cols=cols,
            ))
        return 0

    # Print the hook and the dots first in case the hook takes hella long to
    # run.
    output.write(
        get_hook_message(
            _hook_msg_start(hook, args.verbose),
            end_len=6,
            cols=cols,
        ))
    sys.stdout.flush()

    diff_before = cmd_output(
        'git',
        'diff',
        '--no-ext-diff',
        retcode=None,
        encoding=None,
    )
    retcode, stdout, stderr = repo.run_hook(
        hook,
        tuple(filenames) if hook['pass_filenames'] else (),
    )
    diff_after = cmd_output(
        'git',
        'diff',
        '--no-ext-diff',
        retcode=None,
        encoding=None,
    )

    file_modifications = diff_before != diff_after

    # If the hook makes changes, fail the commit
    if file_modifications:
        retcode = 1

    if retcode:
        retcode = 1
        print_color = color.RED
        pass_fail = 'Failed'
    else:
        retcode = 0
        print_color = color.GREEN
        pass_fail = 'Passed'

    output.write_line(color.format_color(pass_fail, print_color, args.color))

    if ((stdout or stderr or file_modifications)
            and (retcode or args.verbose or hook['verbose'])):
        output.write_line('hookid: {}\n'.format(hook['id']))

        # Print a message if failing due to file modifications
        if file_modifications:
            output.write('Files were modified by this hook.')

            if stdout or stderr:
                output.write_line(' Additional output:')

            output.write_line()

        for out in (stdout, stderr):
            assert type(out) is bytes, type(out)
            if out.strip():
                output.write_line(out.strip(), logfile_name=hook['log_file'])
        output.write_line()

    return retcode
Пример #29
0
            # skip blank lines
            elif line.strip() in ["", "#"]:
                continue
            else:
                h_lines.append(line)

            if len(h_lines) == 3:
                break
    return h_lines


if __name__ == "__main__":
    retv = 0
    for filename in sys.argv[1:]:
        filepath = Path(filename)
        if not filepath.is_file():
            continue

        header_lines = get_header_lines(filepath)
        if len(header_lines) < 3:
            retv |= 1
            output.write_line(f"{filename}: (not enough lines)")
        else:
            header = "".join(header_lines)
            if header != EXPECTED_HEADER:
                retv |= 1
                output.write(f"{filename}:\n  {'  '.join(header_lines)}")
            else:
                retv |= 0
    sys.exit(retv)
Пример #30
0
def _run_single_hook(classifier, hook, args, skips, cols, use_color):
    filenames = classifier.filenames_for_hook(hook)

    if hook.language == 'pcre':
        logger.warning(
            '`{}` (from {}) uses the deprecated pcre language.\n'
            'The pcre language is scheduled for removal in pre-commit 2.x.\n'
            'The pygrep language is a more portable (and usually drop-in) '
            'replacement.'.format(hook.id, hook.src), )

    if hook.id in skips or hook.alias in skips:
        output.write(
            get_hook_message(
                _hook_msg_start(hook, args.verbose),
                end_msg=SKIPPED,
                end_color=color.YELLOW,
                use_color=args.color,
                cols=cols,
            ), )
        return 0
    elif not filenames and not hook.always_run:
        output.write(
            get_hook_message(
                _hook_msg_start(hook, args.verbose),
                postfix=NO_FILES,
                end_msg=SKIPPED,
                end_color=color.TURQUOISE,
                use_color=args.color,
                cols=cols,
            ), )
        return 0

    # Print the hook and the dots first in case the hook takes hella long to
    # run.
    output.write(
        get_hook_message(
            _hook_msg_start(hook, args.verbose),
            end_len=6,
            cols=cols,
        ), )
    sys.stdout.flush()

    diff_before = cmd_output_b('git', 'diff', '--no-ext-diff', retcode=None)
    filenames = tuple(filenames) if hook.pass_filenames else ()
    retcode, out = hook.run(filenames, use_color)
    diff_after = cmd_output_b('git', 'diff', '--no-ext-diff', retcode=None)

    file_modifications = diff_before != diff_after

    # If the hook makes changes, fail the commit
    if file_modifications:
        retcode = 1

    if retcode:
        retcode = 1
        print_color = color.RED
        pass_fail = 'Failed'
    else:
        retcode = 0
        print_color = color.GREEN
        pass_fail = 'Passed'

    output.write_line(color.format_color(pass_fail, print_color, args.color))

    if ((out or file_modifications)
            and (retcode or args.verbose or hook.verbose)):
        output.write_line('hookid: {}\n'.format(hook.id))

        # Print a message if failing due to file modifications
        if file_modifications:
            output.write('Files were modified by this hook.')

            if out:
                output.write_line(' Additional output:')

            output.write_line()

        if out.strip():
            output.write_line(out.strip(), logfile_name=hook.log_file)
        output.write_line()

    return retcode
Пример #31
0
def _run_single_hook(classifier, hook, args, skips, cols):
    filenames = classifier.filenames_for_hook(hook)

    if hook.language == 'pcre':
        logger.warning(
            '`{}` (from {}) uses the deprecated pcre language.\n'
            'The pcre language is scheduled for removal in pre-commit 2.x.\n'
            'The pygrep language is a more portable (and usually drop-in) '
            'replacement.'.format(hook.id, hook.src),
        )

    if hook.id in skips or hook.alias in skips:
        output.write(
            get_hook_message(
                _hook_msg_start(hook, args.verbose),
                end_msg=SKIPPED,
                end_color=color.YELLOW,
                use_color=args.color,
                cols=cols,
            ),
        )
        return 0
    elif not filenames and not hook.always_run:
        output.write(
            get_hook_message(
                _hook_msg_start(hook, args.verbose),
                postfix=NO_FILES,
                end_msg=SKIPPED,
                end_color=color.TURQUOISE,
                use_color=args.color,
                cols=cols,
            ),
        )
        return 0

    # Print the hook and the dots first in case the hook takes hella long to
    # run.
    output.write(
        get_hook_message(
            _hook_msg_start(hook, args.verbose), end_len=6, cols=cols,
        ),
    )
    sys.stdout.flush()

    diff_before = cmd_output(
        'git', 'diff', '--no-ext-diff', retcode=None, encoding=None,
    )
    retcode, stdout, stderr = hook.run(
        tuple(filenames) if hook.pass_filenames else (),
    )
    diff_after = cmd_output(
        'git', 'diff', '--no-ext-diff', retcode=None, encoding=None,
    )

    file_modifications = diff_before != diff_after

    # If the hook makes changes, fail the commit
    if file_modifications:
        retcode = 1

    if retcode:
        retcode = 1
        print_color = color.RED
        pass_fail = 'Failed'
    else:
        retcode = 0
        print_color = color.GREEN
        pass_fail = 'Passed'

    output.write_line(color.format_color(pass_fail, print_color, args.color))

    if (
            (stdout or stderr or file_modifications) and
            (retcode or args.verbose or hook.verbose)
    ):
        output.write_line('hookid: {}\n'.format(hook.id))

        # Print a message if failing due to file modifications
        if file_modifications:
            output.write('Files were modified by this hook.')

            if stdout or stderr:
                output.write_line(' Additional output:')

            output.write_line()

        for out in (stdout, stderr):
            assert type(out) is bytes, type(out)
            if out.strip():
                output.write_line(out.strip(), logfile_name=hook.log_file)
        output.write_line()

    return retcode
Пример #32
0
def _run_single_hook(classifier, hook, skips, cols, verbose, use_color):
    filenames = classifier.filenames_for_hook(hook)

    if hook.id in skips or hook.alias in skips:
        output.write(
            get_hook_message(
                hook.name,
                end_msg=SKIPPED,
                end_color=color.YELLOW,
                use_color=use_color,
                cols=cols,
            ), )
        duration = None
        retcode = 0
        files_modified = False
        out = b''
    elif not filenames and not hook.always_run:
        output.write(
            get_hook_message(
                hook.name,
                postfix=NO_FILES,
                end_msg=SKIPPED,
                end_color=color.TURQUOISE,
                use_color=use_color,
                cols=cols,
            ), )
        duration = None
        retcode = 0
        files_modified = False
        out = b''
    else:
        # print hook and dots first in case the hook takes a while to run
        output.write(get_hook_message(hook.name, end_len=6, cols=cols))

        diff_cmd = ('git', 'diff', '--no-ext-diff')
        diff_before = cmd_output_b(*diff_cmd, retcode=None)
        filenames = tuple(filenames) if hook.pass_filenames else ()
        time_before = time.time()
        retcode, out = hook.run(filenames, use_color)
        duration = round(time.time() - time_before, 2) or 0
        diff_after = cmd_output_b(*diff_cmd, retcode=None)

        # if the hook makes changes, fail the commit
        files_modified = diff_before != diff_after

        if retcode or files_modified:
            print_color = color.RED
            status = 'Failed'
        else:
            print_color = color.GREEN
            status = 'Passed'

        output.write_line(color.format_color(status, print_color, use_color))

    if verbose or hook.verbose or retcode or files_modified:
        _subtle_line('- hook id: {}'.format(hook.id), use_color)

        if (verbose or hook.verbose) and duration is not None:
            _subtle_line('- duration: {}s'.format(duration), use_color)

        if retcode:
            _subtle_line('- exit code: {}'.format(retcode), use_color)

        # Print a message if failing due to file modifications
        if files_modified:
            _subtle_line('- files were modified by this hook', use_color)

        if out.strip():
            output.write_line()
            output.write_line(out.strip(), logfile_name=hook.log_file)
            output.write_line()

    return files_modified or bool(retcode)
Пример #33
0
def test_output_write_writes():
    stream = io.BytesIO()
    output.write('hello world', stream)
    assert stream.getvalue() == b'hello world'
Пример #34
0
def _run_single_hook(hook, repo, args, skips, cols):
    filenames = get_filenames(args, hook.get('files', '^$'), hook['exclude'])
    if hook['id'] in skips:
        output.write(get_hook_message(
            _hook_msg_start(hook, args.verbose),
            end_msg=SKIPPED,
            end_color=color.YELLOW,
            use_color=args.color,
            cols=cols,
        ))
        return 0
    elif not filenames and not hook['always_run']:
        output.write(get_hook_message(
            _hook_msg_start(hook, args.verbose),
            postfix=NO_FILES,
            end_msg=SKIPPED,
            end_color=color.TURQUOISE,
            use_color=args.color,
            cols=cols,
        ))
        return 0

    # Print the hook and the dots first in case the hook takes hella long to
    # run.
    output.write(get_hook_message(
        _hook_msg_start(hook, args.verbose), end_len=6, cols=cols,
    ))
    sys.stdout.flush()

    diff_before = cmd_output(
        'git', 'diff', '--no-ext-diff', retcode=None, encoding=None,
    )
    retcode, stdout, stderr = repo.run_hook(
        hook,
        tuple(filenames) if hook['pass_filenames'] else (),
    )
    diff_after = cmd_output(
        'git', 'diff', '--no-ext-diff', retcode=None, encoding=None,
    )

    file_modifications = diff_before != diff_after

    # If the hook makes changes, fail the commit
    if file_modifications:
        retcode = 1

    if retcode:
        retcode = 1
        print_color = color.RED
        pass_fail = 'Failed'
    else:
        retcode = 0
        print_color = color.GREEN
        pass_fail = 'Passed'

    output.write_line(color.format_color(pass_fail, print_color, args.color))

    if (stdout or stderr or file_modifications) and (retcode or args.verbose):
        output.write_line('hookid: {}\n'.format(hook['id']))

        # Print a message if failing due to file modifications
        if file_modifications:
            output.write('Files were modified by this hook.')

            if stdout or stderr:
                output.write_line(' Additional output:')

            output.write_line()

        for out in (stdout, stderr):
            assert type(out) is bytes, type(out)
            if out.strip():
                output.write_line(out.strip(), logfile_name=hook['log_file'])
        output.write_line()

    return retcode