Example #1
0
def test_merge_conflict_resolved(cap_out, store, in_merge_conflict):
    cmd_output('git', 'add', '.')
    ret, printed = _do_run(cap_out, store, in_merge_conflict, run_opts())
    for msg in (
            b'Checking merge-conflict files only.', b'Bash hook', b'Passed',
    ):
        assert msg in printed
Example #2
0
def test_origin_source_error_msg_error(
        cap_out, store, repo_with_passing_hook, origin, source,
):
    args = run_opts(origin=origin, source=source)
    ret, printed = _do_run(cap_out, store, repo_with_passing_hook, args)
    assert ret == 1
    assert b'Specify both --origin and --source.' in printed
Example #3
0
def test_skip_hook(cap_out, store, repo_with_passing_hook):
    ret, printed = _do_run(
        cap_out, store, repo_with_passing_hook, run_opts(),
        {'SKIP': 'bash_hook'},
    )
    for msg in (b'Bash hook', b'Skipped'):
        assert msg in printed
Example #4
0
def test_aliased_hook_run(cap_out, store, aliased_repo):
    ret, output = _do_run(
        cap_out, store, aliased_repo,
        run_opts(verbose=True, hook='bash_hook'),
    )
    assert ret == 0
    # Both hooks will run since they share the same ID
    assert output.count(b'Bash hook') == 2

    ret, output = _do_run(
        cap_out, store, aliased_repo,
        run_opts(verbose=True, hook='foo_bash'),
    )
    assert ret == 0
    # Only the aliased hook runs
    assert output.count(b'Bash hook') == 1
Example #5
0
def test_hook_id_not_in_non_verbose_output(
        cap_out, store, repo_with_passing_hook,
):
    ret, printed = _do_run(
        cap_out, store, repo_with_passing_hook, run_opts(verbose=False),
    )
    assert b'[bash_hook]' not in printed
Example #6
0
 def _run_for_stage(stage):
     args = run_opts(hook_stage=stage)
     ret, printed = _do_run(cap_out, store, repo_with_passing_hook, args)
     assert not ret, (ret, printed)
     # this test should only run one hook
     assert printed.count(b'hook ') == 1
     return printed
Example #7
0
def test_args_hook_only(cap_out, store, repo_with_passing_hook):
    config = {
        'repo': 'local',
        'hooks': [
            {
                'id': 'flake8',
                'name': 'flake8',
                'entry': "'{}' -m flake8".format(sys.executable),
                'language': 'system',
                'stages': ['commit'],
            },
            {
                'id': 'do_not_commit',
                'name': 'Block if "DO NOT COMMIT" is found',
                'entry': 'DO NOT COMMIT',
                'language': 'pygrep',
            },
        ],
    }
    add_config_to_repo(repo_with_passing_hook, config)
    stage_a_file()
    ret, printed = _do_run(
        cap_out,
        store,
        repo_with_passing_hook,
        run_opts(hook='do_not_commit'),
    )
    assert b'flake8' not in printed
Example #8
0
def test_types_hook_repository(cap_out, store, tempdir_factory):
    git_path = make_consuming_repo(tempdir_factory, 'types_repo')
    with cwd(git_path):
        stage_a_file('bar.py')
        stage_a_file('bar.notpy')
        ret, printed = _do_run(cap_out, store, git_path, run_opts())
        assert ret == 1
        assert b'bar.py' in printed
        assert b'bar.notpy' not in printed
Example #9
0
def test_types_hook_repository(cap_out, store, tempdir_factory):
    git_path = make_consuming_repo(tempdir_factory, 'types_repo')
    with cwd(git_path):
        stage_a_file('bar.py')
        stage_a_file('bar.notpy')
        ret, printed = _do_run(cap_out, store, git_path, run_opts())
        assert ret == 1
        assert b'bar.py' in printed
        assert b'bar.notpy' not in printed
Example #10
0
def test_merge_conflict_modified(cap_out, store, in_merge_conflict):
    # Touch another file so we have unstaged non-conflicting things
    assert os.path.exists('dummy')
    with open('dummy', 'w') as dummy_file:
        dummy_file.write('bar\nbaz\n')

    ret, printed = _do_run(cap_out, store, in_merge_conflict, run_opts())
    assert ret == 1
    assert b'Unmerged files.  Resolve before committing.' in printed
Example #11
0
def test_no_unstaged_error_with_all_files_or_files(
    cap_out,
    modified_config_repo,
    mock_out_store_directory,
    opts,
):
    args = run_opts(**opts)
    ret, printed = _do_run(cap_out, modified_config_repo, args)
    assert b'Your .pre-commit-config.yaml is unstaged.' not in printed
Example #12
0
def test_merge_conflict_modified(cap_out, store, in_merge_conflict):
    # Touch another file so we have unstaged non-conflicting things
    assert os.path.exists('dummy')
    with open('dummy', 'w') as dummy_file:
        dummy_file.write('bar\nbaz\n')

    ret, printed = _do_run(cap_out, store, in_merge_conflict, run_opts())
    assert ret == 1
    assert b'Unmerged files.  Resolve before committing.' in printed
Example #13
0
def test_skip_hook(cap_out, repo_with_passing_hook, mock_out_store_directory):
    ret, printed = _do_run(
        cap_out,
        repo_with_passing_hook,
        run_opts(),
        {'SKIP': 'bash_hook'},
    )
    for msg in (b'Bash hook', b'Skipped'):
        assert msg in printed
Example #14
0
def test_error_with_unstaged_config(
    cap_out,
    modified_config_repo,
    mock_out_store_directory,
):
    args = run_opts()
    ret, printed = _do_run(cap_out, modified_config_repo, args)
    assert b'Your .pre-commit-config.yaml is unstaged.' in printed
    assert ret == 1
Example #15
0
def test_all_push_options_ok(cap_out, store, repo_with_passing_hook):
    args = run_opts(
        from_ref='master',
        to_ref='master',
        remote_name='origin',
        remote_url='https://example.com/repo',
    )
    ret, printed = _do_run(cap_out, store, repo_with_passing_hook, args)
    assert ret == 0
    assert b'Specify both --from-ref and --to-ref.' not in printed
Example #16
0
def test_multiple_hooks_same_id(cap_out, store, repo_with_passing_hook):
    with cwd(repo_with_passing_hook):
        # Add bash hook on there again
        with modify_config() as config:
            config['repos'][0]['hooks'].append({'id': 'bash_hook'})
        stage_a_file()

    ret, output = _do_run(cap_out, store, repo_with_passing_hook, run_opts())
    assert ret == 0
    assert output.count(b'Bash hook') == 2
Example #17
0
def test_skip_aliased_hook(cap_out, store, aliased_repo):
    ret, printed = _do_run(
        cap_out, store, aliased_repo,
        run_opts(hook='foo_bash'),
        {'SKIP': 'foo_bash'},
    )
    assert ret == 0
    # Only the aliased hook runs and is skipped
    for msg in (b'Bash hook', b'Skipped'):
        assert printed.count(msg) == 1
Example #18
0
def test_multiple_hooks_same_id(cap_out, store, repo_with_passing_hook):
    with cwd(repo_with_passing_hook):
        # Add bash hook on there again
        with modify_config() as config:
            config['repos'][0]['hooks'].append({'id': 'bash_hook'})
        stage_a_file()

    ret, output = _do_run(cap_out, store, repo_with_passing_hook, run_opts())
    assert ret == 0
    assert output.count(b'Bash hook') == 2
Example #19
0
def test_fail_fast(cap_out, store, repo_with_failing_hook):
    with modify_config() as config:
        # More than one hook
        config['fail_fast'] = True
        config['repos'][0]['hooks'] *= 2
    stage_a_file()

    ret, printed = _do_run(cap_out, store, repo_with_failing_hook, run_opts())
    # it should have only run one hook
    assert printed.count(b'Failing hook') == 1
Example #20
0
def test_skip_aliased_hook(cap_out, store, aliased_repo):
    ret, printed = _do_run(
        cap_out, store, aliased_repo,
        run_opts(hook='foo_bash'),
        {'SKIP': 'foo_bash'},
    )
    assert ret == 0
    # Only the aliased hook runs and is skipped
    for msg in (b'Bash hook', b'Skipped'):
        assert printed.count(msg) == 1
Example #21
0
def test_fail_fast(cap_out, store, repo_with_failing_hook):
    with modify_config() as config:
        # More than one hook
        config['fail_fast'] = True
        config['repos'][0]['hooks'] *= 2
    stage_a_file()

    ret, printed = _do_run(cap_out, store, repo_with_failing_hook, run_opts())
    # it should have only run one hook
    assert printed.count(b'Failing hook') == 1
Example #22
0
def test_pre_commit_env_variable_set(cap_out, store, repo_with_passing_hook):
    args = run_opts()
    environ: MutableMapping[str, str] = {}
    ret, printed = _do_run(
        cap_out,
        store,
        repo_with_passing_hook,
        args,
        environ,
    )
    assert environ['PRE_COMMIT'] == '1'
Example #23
0
def test_hook_id_in_verbose_output(
    cap_out,
    repo_with_passing_hook,
    mock_out_store_directory,
):
    ret, printed = _do_run(
        cap_out,
        repo_with_passing_hook,
        run_opts(verbose=True),
    )
    assert b'[bash_hook] Bash hook' in printed
Example #24
0
def test_checkout_type(cap_out, store, repo_with_passing_hook):
    args = run_opts(from_ref='', to_ref='', checkout_type='1')
    environ: MutableMapping[str, str] = {}
    ret, printed = _do_run(
        cap_out,
        store,
        repo_with_passing_hook,
        args,
        environ,
    )
    assert environ['PRE_COMMIT_CHECKOUT_TYPE'] == '1'
Example #25
0
def test_from_ref_to_ref_error_msg_error(
    cap_out,
    store,
    repo_with_passing_hook,
    from_ref,
    to_ref,
):
    args = run_opts(from_ref=from_ref, to_ref=to_ref)
    ret, printed = _do_run(cap_out, store, repo_with_passing_hook, args)
    assert ret == 1
    assert b'Specify both --from-ref and --to-ref.' in printed
Example #26
0
def test_is_squash_merge(cap_out, store, repo_with_passing_hook):
    args = run_opts(is_squash_merge='1')
    environ: MutableMapping[str, str] = {}
    ret, printed = _do_run(
        cap_out,
        store,
        repo_with_passing_hook,
        args,
        environ,
    )
    assert environ['PRE_COMMIT_IS_SQUASH_MERGE'] == '1'
Example #27
0
def test_origin_source_error_msg_error(
    cap_out,
    store,
    repo_with_passing_hook,
    origin,
    source,
):
    args = run_opts(origin=origin, source=source)
    ret, printed = _do_run(cap_out, store, repo_with_passing_hook, args)
    assert ret == 1
    assert b'Specify both --origin and --source.' in printed
Example #28
0
def test_aliased_hook_run(cap_out, store, aliased_repo):
    ret, output = _do_run(
        cap_out,
        store,
        aliased_repo,
        run_opts(verbose=True, hook='bash_hook'),
    )
    assert ret == 0
    # Both hooks will run since they share the same ID
    assert output.count(b'Bash hook') == 2

    ret, output = _do_run(
        cap_out,
        store,
        aliased_repo,
        run_opts(verbose=True, hook='foo_bash'),
    )
    assert ret == 0
    # Only the aliased hook runs
    assert output.count(b'Bash hook') == 1
Example #29
0
def test_hook_id_not_in_non_verbose_output(
    cap_out,
    store,
    repo_with_passing_hook,
):
    ret, printed = _do_run(
        cap_out,
        store,
        repo_with_passing_hook,
        run_opts(verbose=False),
    )
    assert b'[bash_hook]' not in printed
Example #30
0
def _test_run(
    cap_out, store, repo, opts, expected_outputs, expected_ret, stage,
    config_file=C.CONFIG_FILE,
):
    if stage:
        stage_a_file()
    args = run_opts(**opts)
    ret, printed = _do_run(cap_out, store, repo, args, config_file=config_file)

    assert ret == expected_ret, (ret, expected_ret, printed)
    for expected_output_part in expected_outputs:
        assert expected_output_part in printed
Example #31
0
def test_exclude_types_hook_repository(cap_out, store, tempdir_factory):
    git_path = make_consuming_repo(tempdir_factory, 'exclude_types_repo')
    with cwd(git_path):
        with open('exe', 'w') as exe:
            exe.write('#!/usr/bin/env python3\n')
        make_executable('exe')
        cmd_output('git', 'add', 'exe')
        stage_a_file('bar.py')
        ret, printed = _do_run(cap_out, store, git_path, run_opts())
        assert ret == 1
        assert b'bar.py' in printed
        assert b'exe' not in printed
Example #32
0
def test_exclude_types_hook_repository(cap_out, store, tempdir_factory):
    git_path = make_consuming_repo(tempdir_factory, 'exclude_types_repo')
    with cwd(git_path):
        with io.open('exe', 'w') as exe:
            exe.write('#!/usr/bin/env python3\n')
        make_executable('exe')
        cmd_output('git', 'add', 'exe')
        stage_a_file('bar.py')
        ret, printed = _do_run(cap_out, store, git_path, run_opts())
        assert ret == 1
        assert b'bar.py' in printed
        assert b'exe' not in printed
Example #33
0
def _test_run(
    cap_out, store, repo, opts, expected_outputs, expected_ret, stage,
    config_file=C.CONFIG_FILE,
):
    if stage:
        stage_a_file()
    args = run_opts(**opts)
    ret, printed = _do_run(cap_out, store, repo, args, config_file=config_file)

    assert ret == expected_ret, (ret, expected_ret, printed)
    for expected_output_part in expected_outputs:
        assert expected_output_part in printed
Example #34
0
def test_origin_source_error_msg(
        repo_with_passing_hook, origin, source, expect_failure,
        mock_out_store_directory, cap_out,
):
    args = run_opts(origin=origin, source=source)
    ret, printed = _do_run(cap_out, repo_with_passing_hook, args)
    warning_msg = b'Specify both --origin and --source.'
    if expect_failure:
        assert ret == 1
        assert warning_msg in printed
    else:
        assert ret == 0
        assert warning_msg not in printed
Example #35
0
def test_pass_filenames(
        cap_out, store, repo_with_passing_hook,
        pass_filenames, hook_args, expected_out,
):
    with modify_config() as config:
        config['repos'][0]['hooks'][0]['pass_filenames'] = pass_filenames
        config['repos'][0]['hooks'][0]['args'] = hook_args
    stage_a_file()
    ret, printed = _do_run(
        cap_out, store, repo_with_passing_hook, run_opts(verbose=True),
    )
    assert expected_out + b'\nHello World' in printed
    assert (b'foo.py' in printed) == pass_filenames
Example #36
0
def test_pass_filenames(
        cap_out, store, repo_with_passing_hook,
        pass_filenames, hook_args, expected_out,
):
    with modify_config() as config:
        config['repos'][0]['hooks'][0]['pass_filenames'] = pass_filenames
        config['repos'][0]['hooks'][0]['args'] = hook_args
    stage_a_file()
    ret, printed = _do_run(
        cap_out, store, repo_with_passing_hook, run_opts(verbose=True),
    )
    assert expected_out + b'\nHello World' in printed
    assert (b'foo.py' in printed) == pass_filenames
Example #37
0
def test_merge_conflict_resolved(
    cap_out,
    in_merge_conflict,
    mock_out_store_directory,
):
    cmd_output('git', 'add', '.')
    ret, printed = _do_run(cap_out, in_merge_conflict, run_opts())
    for msg in (
            b'Checking merge-conflict files only.',
            b'Bash hook',
            b'Passed',
    ):
        assert msg in printed
Example #38
0
def test_global_exclude(cap_out, tempdir_factory, mock_out_store_directory):
    git_path = make_consuming_repo(tempdir_factory, 'script_hooks_repo')
    with cwd(git_path):
        with modify_config() as config:
            config['exclude'] = '^foo.py$'
        open('foo.py', 'a').close()
        open('bar.py', 'a').close()
        cmd_output('git', 'add', '.')
        ret, printed = _do_run(cap_out, git_path, run_opts(verbose=True))
        assert ret == 0
        # Does not contain foo.py since it was excluded
        expected = b'hookid: bash_hook\n\nbar.py\nHello World\n\n'
        assert printed.endswith(expected)
Example #39
0
def test_global_exclude(cap_out, store, tempdir_factory):
    git_path = make_consuming_repo(tempdir_factory, 'script_hooks_repo')
    with cwd(git_path):
        with modify_config() as config:
            config['exclude'] = '^foo.py$'
        open('foo.py', 'a').close()
        open('bar.py', 'a').close()
        cmd_output('git', 'add', '.')
        opts = run_opts(verbose=True)
        ret, printed = _do_run(cap_out, store, git_path, opts)
        assert ret == 0
        # Does not contain foo.py since it was excluded
        expected = b'hookid: bash_hook\n\nbar.py\nHello World\n\n'
        assert printed.endswith(expected)
Example #40
0
def test_global_files(cap_out, store, in_git_dir):
    config = {
        'files': r'^bar\.py$',
        'repos': [{'repo': 'meta', 'hooks': [{'id': 'identity'}]}],
    }
    write_config('.', config)
    open('foo.py', 'a').close()
    open('bar.py', 'a').close()
    cmd_output('git', 'add', '.')
    opts = run_opts(verbose=True)
    ret, printed = _do_run(cap_out, store, str(in_git_dir), opts)
    assert ret == 0
    # Does not contain foo.py since it was excluded
    assert printed.startswith(f'identity{"." * 65}Passed\n'.encode())
    assert printed.endswith(b'\n\nbar.py\n\n')
Example #41
0
def test_global_exclude(cap_out, store, in_git_dir):
    config = {
        'exclude': r'^foo\.py$',
        'repos': [{
            'repo': 'meta',
            'hooks': [{
                'id': 'identity'
            }]
        }],
    }
    write_config('.', config)
    open('foo.py', 'a').close()
    open('bar.py', 'a').close()
    cmd_output('git', 'add', '.')
    opts = run_opts(verbose=True)
    ret, printed = _do_run(cap_out, store, str(in_git_dir), opts)
    assert ret == 0
    # Does not contain foo.py since it was excluded
    assert printed.startswith(b'identity' + b'.' * 65 + b'Passed\n')
    assert printed.endswith(b'\n\n.pre-commit-config.yaml\nbar.py\n\n')
Example #42
0
def test_skip_bypasses_installation(cap_out, store, repo_with_passing_hook):
    config = {
        'repo': 'local',
        'hooks': [
            {
                'id': 'skipme',
                'name': 'skipme',
                'entry': 'skipme',
                'language': 'python',
                'additional_dependencies': ['/pre-commit-does-not-exist'],
            },
        ],
    }
    add_config_to_repo(repo_with_passing_hook, config)

    ret, printed = _do_run(
        cap_out, store, repo_with_passing_hook,
        run_opts(all_files=True),
        {'SKIP': 'skipme'},
    )
    assert ret == 0
Example #43
0
def test_args_hook_only(cap_out, store, repo_with_passing_hook):
    config = {
        'repo':
        'local',
        'hooks': [
            {
                'id':
                'identity-copy',
                'name':
                'identity-copy',
                'entry':
                '{} -m pre_commit.meta_hooks.identity'.format(
                    shlex.quote(sys.executable), ),
                'language':
                'system',
                'files':
                r'\.py$',
                'stages': ['commit'],
            },
            {
                'id': 'do_not_commit',
                'name': 'Block if "DO NOT COMMIT" is found',
                'entry': 'DO NOT COMMIT',
                'language': 'pygrep',
            },
        ],
    }
    add_config_to_repo(repo_with_passing_hook, config)
    stage_a_file()
    ret, printed = _do_run(
        cap_out,
        store,
        repo_with_passing_hook,
        run_opts(hook='do_not_commit'),
    )
    assert b'identity-copy' not in printed
Example #44
0
def test_merge_conflict(cap_out, store, in_merge_conflict):
    ret, printed = _do_run(cap_out, store, in_merge_conflict, run_opts())
    assert ret == 1
    assert b'Unmerged files.  Resolve before committing.' in printed
Example #45
0
def test_merge_conflict(cap_out, in_merge_conflict, mock_out_store_directory):
    ret, printed = _do_run(cap_out, in_merge_conflict, run_opts())
    assert ret == 1
    assert b'Unmerged files.  Resolve before committing.' in printed
Example #46
0
def test_error_with_unstaged_config(cap_out, store, modified_config_repo):
    args = run_opts()
    ret, printed = _do_run(cap_out, store, modified_config_repo, args)
    assert b'Your pre-commit configuration is unstaged.' in printed
    assert ret == 1
Example #47
0
def test_hook_id_in_verbose_output(cap_out, store, repo_with_passing_hook):
    ret, printed = _do_run(
        cap_out, store, repo_with_passing_hook, run_opts(verbose=True),
    )
    assert b'[bash_hook] Bash hook' in printed
Example #48
0
def test_hook_id_in_verbose_output(cap_out, store, repo_with_passing_hook):
    ret, printed = _do_run(
        cap_out, store, repo_with_passing_hook, run_opts(verbose=True),
    )
    assert b'- hook id: bash_hook' in printed
Example #49
0
def modified_config_repo(repo_with_passing_hook):
    with modify_config(repo_with_passing_hook, commit=False) as config:
        # Some minor modification
        config['repos'][0]['hooks'][0]['files'] = ''
    yield repo_with_passing_hook


def test_error_with_unstaged_config(cap_out, store, modified_config_repo):
    args = run_opts()
    ret, printed = _do_run(cap_out, store, modified_config_repo, args)
    assert b'Your pre-commit configuration is unstaged.' in printed
    assert ret == 1


@pytest.mark.parametrize(
    'opts', (run_opts(all_files=True), run_opts(files=[C.CONFIG_FILE])),
)
def test_no_unstaged_error_with_all_files_or_files(
        cap_out, store, modified_config_repo, opts,
):
    ret, printed = _do_run(cap_out, store, modified_config_repo, opts)
    assert b'Your pre-commit configuration is unstaged.' not in printed


def test_files_running_subdir(repo_with_passing_hook, tempdir_factory):
    with cwd(repo_with_passing_hook):
        os.mkdir('subdir')
        open('subdir/foo.py', 'w').close()
        cmd_output('git', 'add', 'subdir/foo.py')

        with cwd('subdir'):
Example #50
0
def test_error_with_unstaged_config(cap_out, store, modified_config_repo):
    args = run_opts()
    ret, printed = _do_run(cap_out, store, modified_config_repo, args)
    assert b'Your pre-commit configuration is unstaged.' in printed
    assert ret == 1
Example #51
0
def test_origin_source_both_ok(cap_out, store, repo_with_passing_hook):
    args = run_opts(origin='master', source='master')
    ret, printed = _do_run(cap_out, store, repo_with_passing_hook, args)
    assert ret == 0
    assert b'Specify both --origin and --source.' not in printed