Ejemplo n.º 1
0
def test_gc_unused_local_repo_with_env(store, in_git_dir, cap_out):
    config = {
        'repo':
        'local',
        'hooks': [{
            'id': 'flake8',
            'name': 'flake8',
            'entry': 'flake8',
            # a `language: python` local hook will create an environment
            'types': ['python'],
            'language': 'python',
        }],
    }
    write_config('.', config)
    store.mark_config_used(C.CONFIG_FILE)

    # this causes the repositories to be created
    all_hooks(load_config(C.CONFIG_FILE), store)

    assert _config_count(store) == 1
    assert _repo_count(store) == 1
    assert not gc(store)
    assert _config_count(store) == 1
    assert _repo_count(store) == 1
    assert cap_out.get().splitlines()[-1] == '0 repo(s) removed.'

    _remove_config_assert_cleared(store, cap_out)
Ejemplo n.º 2
0
def test_default_language_version(store, local_python_config):
    config: Dict[str, Any] = {
        'default_language_version': {'python': 'fake'},
        'default_stages': ['commit'],
        'repos': [local_python_config],
    }

    # `language_version` was not set, should default
    hook, = all_hooks(config, store)
    assert hook.language_version == 'fake'

    # `language_version` is set, should not default
    config['repos'][0]['hooks'][0]['language_version'] = 'fake2'
    hook, = all_hooks(config, store)
    assert hook.language_version == 'fake2'
Ejemplo n.º 3
0
def test_default_stages(store, local_python_config):
    config: Dict[str, Any] = {
        'default_language_version': {'python': C.DEFAULT},
        'default_stages': ['commit'],
        'repos': [local_python_config],
    }

    # `stages` was not set, should default
    hook, = all_hooks(config, store)
    assert hook.stages == ['commit']

    # `stages` is set, should not default
    config['repos'][0]['hooks'][0]['stages'] = ['push']
    hook, = all_hooks(config, store)
    assert hook.stages == ['push']
Ejemplo n.º 4
0
def _get_hook_no_install(repo_config, store, hook_id):
    config = {'repos': [repo_config]}
    config = cfgv.validate(config, CONFIG_SCHEMA)
    config = cfgv.apply_defaults(config, CONFIG_SCHEMA)
    hooks = all_hooks(config, store)
    hook, = [hook for hook in hooks if hook.id == hook_id]
    return hook
Ejemplo n.º 5
0
def check_all_hooks_match_files(config_file: str) -> int:
    classifier = Classifier(git.get_all_files())
    retv = 0

    for hook in all_hooks(load_config(config_file), Store()):
        if hook.always_run or hook.language == 'fail':
            continue
        elif not classifier.filenames_for_hook(hook):
            print(f'{hook.id} does not apply to this repository')
            retv = 1

    return retv
Ejemplo n.º 6
0
def check_all_hooks_match_files(config_file):
    classifier = Classifier(git.get_all_files())
    retv = 0

    for hook in all_hooks(load_config(config_file), Store()):
        if hook.always_run or hook.language == 'fail':
            continue
        elif not classifier.filenames_for_hook(hook):
            print('{} does not apply to this repository'.format(hook.id))
            retv = 1

    return retv
Ejemplo n.º 7
0
def test_gc_config_with_missing_hook(
        tempdir_factory, store, in_git_dir, cap_out,
):
    path = make_repo(tempdir_factory, 'script_hooks_repo')
    write_config('.', make_config_from_repo(path))
    store.mark_config_used(C.CONFIG_FILE)
    # to trigger a clone
    all_hooks(load_config(C.CONFIG_FILE), store)

    with modify_config() as config:
        # add a hook which does not exist, make sure we don't crash
        config['repos'][0]['hooks'].append({'id': 'does-not-exist'})

    assert _config_count(store) == 1
    assert _repo_count(store) == 1
    assert not gc(store)
    assert _config_count(store) == 1
    assert _repo_count(store) == 1
    assert cap_out.get().splitlines()[-1] == '0 repo(s) removed.'

    _remove_config_assert_cleared(store, cap_out)
Ejemplo n.º 8
0
def run(
    config_file: str,
    store: Store,
    args: argparse.Namespace,
    environ: EnvironT = os.environ,
) -> int:
    stash = not args.all_files and not args.files

    # Check if we have unresolved merge conflict files and fail fast.
    if _has_unmerged_paths():
        logger.error('Unmerged files.  Resolve before committing.')
        return 1
    if bool(args.source) != bool(args.origin):
        logger.error('Specify both --origin and --source.')
        return 1
    if stash and _has_unstaged_config(config_file):
        logger.error(
            f'Your pre-commit configuration is unstaged.\n'
            f'`git add {config_file}` to fix this.', )
        return 1

    # Expose origin / source as environment variables for hooks to consume
    if args.origin and args.source:
        environ['PRE_COMMIT_ORIGIN'] = args.origin
        environ['PRE_COMMIT_SOURCE'] = args.source

    if args.remote_name and args.remote_url:
        environ['PRE_COMMIT_REMOTE_NAME'] = args.remote_name
        environ['PRE_COMMIT_REMOTE_URL'] = args.remote_url

    with contextlib.ExitStack() as exit_stack:
        if stash:
            exit_stack.enter_context(staged_files_only(store.directory))

        config = load_config(config_file)
        hooks = [
            hook for hook in all_hooks(config, store)
            if not args.hook or hook.id == args.hook or hook.alias == args.hook
            if args.hook_stage in hook.stages
        ]

        if args.hook and not hooks:
            output.write_line(
                f'No hook with id `{args.hook}` in stage `{args.hook_stage}`',
            )
            return 1

        install_hook_envs(hooks, store)

        return _run_hooks(config, hooks, args, environ)

    # https://github.com/python/mypy/issues/7726
    raise AssertionError('unreachable')
Ejemplo n.º 9
0
def test_gc_config_with_missing_hook(
        tempdir_factory, store, in_git_dir, cap_out,
):
    path = make_repo(tempdir_factory, 'script_hooks_repo')
    write_config('.', make_config_from_repo(path))
    store.mark_config_used(C.CONFIG_FILE)
    # to trigger a clone
    all_hooks(load_config(C.CONFIG_FILE), store)

    with modify_config() as config:
        # add a hook which does not exist, make sure we don't crash
        config['repos'][0]['hooks'].append({'id': 'does-not-exist'})

    assert _config_count(store) == 1
    assert _repo_count(store) == 1
    assert not gc(store)
    assert _config_count(store) == 1
    assert _repo_count(store) == 1
    assert cap_out.get().splitlines()[-1] == '0 repo(s) removed.'

    _remove_config_assert_cleared(store, cap_out)
Ejemplo n.º 10
0
def test_gc_unused_local_repo_with_env(store, in_git_dir, cap_out):
    config = {
        'repo': 'local',
        'hooks': [{
            'id': 'flake8', 'name': 'flake8', 'entry': 'flake8',
            # a `language: python` local hook will create an environment
            'types': ['python'], 'language': 'python',
        }],
    }
    write_config('.', config)
    store.mark_config_used(C.CONFIG_FILE)

    # this causes the repositories to be created
    all_hooks(load_config(C.CONFIG_FILE), store)

    assert _config_count(store) == 1
    assert _repo_count(store) == 1
    assert not gc(store)
    assert _config_count(store) == 1
    assert _repo_count(store) == 1
    assert cap_out.get().splitlines()[-1] == '0 repo(s) removed.'

    _remove_config_assert_cleared(store, cap_out)
def find_hook(args: argparse.Namespace, store: Store) -> Hook:
    config = load_config(args.config)
    hooks = [
        hook for hook in all_hooks(config, store)
        if not args.hook or hook.id == args.hook or hook.alias == args.hook
        if args.hook_stage in hook.stages
    ]

    if not hooks:
        raise ValueError(
            f"No hook with id `{args.hook}` in stage `{args.hook_stage}`")

    install_hook_envs(hooks, store)
    return hooks[0]
Ejemplo n.º 12
0
def check_all_hooks_match_files(config_file):
    files = git.get_all_files()
    retv = 0

    for hook in all_hooks(load_config(config_file), Store()):
        if hook.always_run or hook.language == 'fail':
            continue
        include, exclude = hook.files, hook.exclude
        filtered = _filter_by_include_exclude(files, include, exclude)
        types, exclude_types = hook.types, hook.exclude_types
        filtered = _filter_by_types(filtered, types, exclude_types)
        if not filtered:
            print('{} does not apply to this repository'.format(hook.id))
            retv = 1

    return retv
Ejemplo n.º 13
0
def run(config_file, store, args, environ=os.environ):
    no_stash = args.all_files or bool(args.files)

    # Check if we have unresolved merge conflict files and fail fast.
    if _has_unmerged_paths():
        logger.error('Unmerged files.  Resolve before committing.')
        return 1
    if bool(args.source) != bool(args.origin):
        logger.error('Specify both --origin and --source.')
        return 1
    if _has_unstaged_config(config_file) and not no_stash:
        logger.error(
            'Your pre-commit configuration is unstaged.\n'
            '`git add {}` to fix this.'.format(config_file),
        )
        return 1

    # Expose origin / source as environment variables for hooks to consume
    if args.origin and args.source:
        environ['PRE_COMMIT_ORIGIN'] = args.origin
        environ['PRE_COMMIT_SOURCE'] = args.source

    if no_stash:
        ctx = noop_context()
    else:
        ctx = staged_files_only(store.directory)

    with ctx:
        config = load_config(config_file)
        hooks = [
            hook
            for hook in all_hooks(config, store)
            if not args.hook or hook.id == args.hook or hook.alias == args.hook
            if args.hook_stage in hook.stages
        ]

        if args.hook and not hooks:
            output.write_line(
                'No hook with id `{}` in stage `{}`'.format(
                    args.hook, args.hook_stage,
                ),
            )
            return 1

        install_hook_envs(hooks, store)

        return _run_hooks(config, hooks, args, environ)
Ejemplo n.º 14
0
def check_all_hooks_match_files(config_file: str) -> int:
    config = load_config(config_file)
    classifier = Classifier.from_config(
        git.get_all_files(),
        config["files"],
        config["exclude"],
    )
    retv = 0

    for hook in all_hooks(config, Store()):
        if hook.always_run or hook.language == "fail":
            continue
        elif not classifier.filenames_for_hook(hook):
            print(f"{hook.id} does not apply to this repository")
            retv = 1

    return retv
Ejemplo n.º 15
0
def run(config_file, store, args, environ=os.environ):
    no_stash = args.all_files or bool(args.files)

    # Check if we have unresolved merge conflict files and fail fast.
    if _has_unmerged_paths():
        logger.error('Unmerged files.  Resolve before committing.')
        return 1
    if bool(args.source) != bool(args.origin):
        logger.error('Specify both --origin and --source.')
        return 1
    if _has_unstaged_config(config_file) and not no_stash:
        logger.error(
            'Your pre-commit configuration is unstaged.\n'
            '`git add {}` to fix this.'.format(config_file),
        )
        return 1

    # Expose origin / source as environment variables for hooks to consume
    if args.origin and args.source:
        environ['PRE_COMMIT_ORIGIN'] = args.origin
        environ['PRE_COMMIT_SOURCE'] = args.source

    if no_stash:
        ctx = noop_context()
    else:
        ctx = staged_files_only(store.directory)

    with ctx:
        config = load_config(config_file)
        hooks = [
            hook
            for hook in all_hooks(config, store)
            if not args.hook or hook.id == args.hook or hook.alias == args.hook
            if args.hook_stage in hook.stages
        ]

        if args.hook and not hooks:
            output.write_line('No hook with id `{}`'.format(args.hook))
            return 1

        install_hook_envs(hooks, store)

        return _run_hooks(config, hooks, args, environ)
def install_hooks(config_file: str, store: Store) -> int:
    install_hook_envs(all_hooks(load_config(config_file), store), store)
    return 0
Ejemplo n.º 17
0
def run(
    config_file: str,
    store: Store,
    args: argparse.Namespace,
    environ: MutableMapping[str, str] = os.environ,
) -> int:
    stash = not args.all_files and not args.files

    # Check if we have unresolved merge conflict files and fail fast.
    if _has_unmerged_paths():
        logger.error('Unmerged files.  Resolve before committing.')
        return 1
    if bool(args.from_ref) != bool(args.to_ref):
        logger.error('Specify both --from-ref and --to-ref.')
        return 1
    if stash and _has_unstaged_config(config_file):
        logger.error(
            f'Your pre-commit configuration is unstaged.\n'
            f'`git add {config_file}` to fix this.', )
        return 1
    if (args.hook_stage in {'prepare-commit-msg', 'commit-msg'}
            and not args.commit_msg_filename):
        logger.error(
            f'`--commit-msg-filename` is required for '
            f'`--hook-stage {args.hook_stage}`', )
        return 1
    # prevent recursive post-checkout hooks (#1418)
    if (args.hook_stage == 'post-checkout'
            and environ.get('_PRE_COMMIT_SKIP_POST_CHECKOUT')):
        return 0

    # Expose from-ref / to-ref as environment variables for hooks to consume
    if args.from_ref and args.to_ref:
        # legacy names
        environ['PRE_COMMIT_ORIGIN'] = args.from_ref
        environ['PRE_COMMIT_SOURCE'] = args.to_ref
        # new names
        environ['PRE_COMMIT_FROM_REF'] = args.from_ref
        environ['PRE_COMMIT_TO_REF'] = args.to_ref

    if args.remote_name and args.remote_url:
        environ['PRE_COMMIT_REMOTE_NAME'] = args.remote_name
        environ['PRE_COMMIT_REMOTE_URL'] = args.remote_url

    if args.checkout_type:
        environ['PRE_COMMIT_CHECKOUT_TYPE'] = args.checkout_type

    # Set pre_commit flag
    environ['PRE_COMMIT'] = '1'

    with contextlib.ExitStack() as exit_stack:
        if stash:
            exit_stack.enter_context(staged_files_only(store.directory))

        config = load_config(config_file)
        hooks = [
            hook for hook in all_hooks(config, store)
            if not args.hook or hook.id == args.hook or hook.alias == args.hook
            if args.hook_stage in hook.stages
        ]

        if args.hook and not hooks:
            output.write_line(
                f'No hook with id `{args.hook}` in stage `{args.hook_stage}`',
            )
            return 1

        install_hook_envs(hooks, store)

        return _run_hooks(config, hooks, args, environ)

    # https://github.com/python/mypy/issues/7726
    raise AssertionError('unreachable')
Ejemplo n.º 18
0
def install_hooks(config_file, store):
    install_hook_envs(all_hooks(load_config(config_file), store), store)
Ejemplo n.º 19
0
def install_hooks(config_file, store):
    install_hook_envs(all_hooks(load_config(config_file), store), store)