def test_pre_push_legacy(tempdir_factory, store):
    upstream = make_consuming_repo(tempdir_factory, 'script_hooks_repo')
    path = tempdir_factory.get()
    cmd_output('git', 'clone', upstream, path)
    with cwd(path):
        mkdirp(os.path.join(path, '.git/hooks'))
        with io.open(os.path.join(path, '.git/hooks/pre-push'), 'w') as f:
            f.write(
                '#!/usr/bin/env bash\n'
                'set -eu\n'
                'read lr ls rr rs\n'
                'test -n "$lr" -a -n "$ls" -a -n "$rr" -a -n "$rs"\n'
                'echo legacy\n',
            )
        make_executable(f.name)

        install(C.CONFIG_FILE, store, hook_type='pre-push')
        assert _get_commit_output(tempdir_factory)[0] == 0

        retc, output = _get_push_output(tempdir_factory)
        assert retc == 0
        first_line, _, third_line = output.splitlines()[:3]
        assert first_line == 'legacy'
        assert third_line.startswith('Bash hook')
        assert third_line.endswith('Passed')
예제 #2
0
def test_run_output_logfile(
        cap_out,
        tempdir_factory,
        mock_out_store_directory,
):

    expected_output = (
        b'This is STDOUT output\n',
        b'This is STDERR output\n',
    )

    git_path = make_consuming_repo(tempdir_factory, 'logfile_repo')
    with cwd(git_path):
        _test_run(
            cap_out,
            git_path, {},
            expected_output,
            expected_ret=1,
            stage=True
        )
    logfile_path = os.path.join(git_path, 'test.log')
    assert os.path.exists(logfile_path)
    with open(logfile_path, 'rb') as logfile:
        logfile_content = logfile.readlines()

    for expected_output_part in expected_output:
        assert expected_output_part in logfile_content
예제 #3
0
def in_merge_conflict(tmpdir_factory):
    path = make_consuming_repo(tmpdir_factory, 'script_hooks_repo')
    with cwd(path):
        cmd_output('touch', 'dummy')
        cmd_output('git', 'add', 'dummy')
        cmd_output('git', 'add', C.CONFIG_FILE)
        cmd_output('git', 'commit', '-m', 'Add config.')

    conflict_path = tmpdir_factory.get()
    cmd_output('git', 'clone', path, conflict_path)
    with cwd(conflict_path):
        cmd_output('git', 'checkout', 'origin/master', '-b', 'foo')
        with io.open('conflict_file', 'w') as conflict_file:
            conflict_file.write('herp\nderp\n')
        cmd_output('git', 'add', 'conflict_file')
        with io.open('foo_only_file', 'w') as foo_only_file:
            foo_only_file.write('foo')
        cmd_output('git', 'add', 'foo_only_file')
        cmd_output('git', 'commit', '-m', 'conflict_file')
        cmd_output('git', 'checkout', 'origin/master', '-b', 'bar')
        with io.open('conflict_file', 'w') as conflict_file:
            conflict_file.write('harp\nddrp\n')
        cmd_output('git', 'add', 'conflict_file')
        with io.open('bar_only_file', 'w') as bar_only_file:
            bar_only_file.write('bar')
        cmd_output('git', 'add', 'bar_only_file')
        cmd_output('git', 'commit', '-m', 'conflict_file')
        cmd_output('git', 'merge', 'foo', retcode=None)
        yield os.path.join(conflict_path)
예제 #4
0
def test_hook_install_failure(mock_out_store_directory, tempdir_factory):
    git_path = make_consuming_repo(tempdir_factory, 'not_installable_repo')
    with cwd(git_path):
        install(Runner(git_path))

        # Don't want to write to home directory
        env = dict(os.environ, PRE_COMMIT_HOME=tempdir_factory.get())
        _, stdout, _ = cmd_output(
            'git', 'commit', '-m', 'Commit!',
            # git commit puts pre-commit to stderr
            stderr=subprocess.STDOUT,
            env=env,
            retcode=None,
            encoding=None,
        )
        assert b'UnicodeDecodeError' not in stdout
        # Doesn't actually happen, but a reasonable assertion
        assert b'UnicodeEncodeError' not in stdout

        # Sanity check our output
        assert (
            b'An unexpected error has occurred: CalledProcessError: ' in
            stdout
        )
        assert '☃'.encode('UTF-8') + '²'.encode('latin1') in stdout
예제 #5
0
def in_merge_conflict(tempdir_factory):
    path = make_consuming_repo(tempdir_factory, "script_hooks_repo")
    with cwd(path):
        cmd_output("touch", "dummy")
        cmd_output("git", "add", "dummy")
        cmd_output("git", "add", C.CONFIG_FILE)
        cmd_output("git", "commit", "-m", "Add config.")

    conflict_path = tempdir_factory.get()
    cmd_output("git", "clone", path, conflict_path)
    with cwd(conflict_path):
        cmd_output("git", "checkout", "origin/master", "-b", "foo")
        with io.open("conflict_file", "w") as conflict_file:
            conflict_file.write("herp\nderp\n")
        cmd_output("git", "add", "conflict_file")
        with io.open("foo_only_file", "w") as foo_only_file:
            foo_only_file.write("foo")
        cmd_output("git", "add", "foo_only_file")
        cmd_output("git", "commit", "-m", "conflict_file")
        cmd_output("git", "checkout", "origin/master", "-b", "bar")
        with io.open("conflict_file", "w") as conflict_file:
            conflict_file.write("harp\nddrp\n")
        cmd_output("git", "add", "conflict_file")
        with io.open("bar_only_file", "w") as bar_only_file:
            bar_only_file.write("bar")
        cmd_output("git", "add", "bar_only_file")
        cmd_output("git", "commit", "-m", "conflict_file")
        cmd_output("git", "merge", "foo", retcode=None)
        yield os.path.join(conflict_path)
def test_environment_not_sourced(tempdir_factory, store):
    path = make_consuming_repo(tempdir_factory, 'script_hooks_repo')
    with cwd(path):
        # Patch the executable to simulate rming virtualenv
        with mock.patch.object(sys, 'executable', '/does-not-exist'):
            assert install(C.CONFIG_FILE, store) == 0

        # Use a specific homedir to ignore --user installs
        homedir = tempdir_factory.get()
        ret, stdout, stderr = git_commit(
            env={
                'HOME': homedir,
                'PATH': _path_without_us(),
                # Git needs this to make a commit
                'GIT_AUTHOR_NAME': os.environ['GIT_AUTHOR_NAME'],
                'GIT_COMMITTER_NAME': os.environ['GIT_COMMITTER_NAME'],
                'GIT_AUTHOR_EMAIL': os.environ['GIT_AUTHOR_EMAIL'],
                'GIT_COMMITTER_EMAIL': os.environ['GIT_COMMITTER_EMAIL'],
            },
            retcode=None,
        )
        assert ret == 1
        assert stdout == ''
        assert stderr.replace('\r\n', '\n') == (
            '`pre-commit` not found.  '
            'Did you forget to activate your virtualenv?\n'
        )
예제 #7
0
def test_installed_from_venv(tempdir_factory):
    path = make_consuming_repo(tempdir_factory, 'script_hooks_repo')
    with cwd(path):
        install(Runner(path, C.CONFIG_FILE))
        # No environment so pre-commit is not on the path when running!
        # Should still pick up the python from when we installed
        ret, output = _get_commit_output(
            tempdir_factory,
            env={
                'HOME': os.path.expanduser('~'),
                'PATH': _path_without_us(),
                'TERM': os.environ.get('TERM', ''),
                # Windows needs this to import `random`
                'SYSTEMROOT': os.environ.get('SYSTEMROOT', ''),
                # Windows needs this to resolve executables
                'PATHEXT': os.environ.get('PATHEXT', ''),
                # Git needs this to make a commit
                'GIT_AUTHOR_NAME': os.environ['GIT_AUTHOR_NAME'],
                'GIT_COMMITTER_NAME': os.environ['GIT_COMMITTER_NAME'],
                'GIT_AUTHOR_EMAIL': os.environ['GIT_AUTHOR_EMAIL'],
                'GIT_COMMITTER_EMAIL': os.environ['GIT_COMMITTER_EMAIL'],
            },
        )
        assert ret == 0
        assert NORMAL_PRE_COMMIT_RUN.match(output)
예제 #8
0
def test_environment_not_sourced(tempdir_factory):
    path = make_consuming_repo(tempdir_factory, 'script_hooks_repo')
    with cwd(path):
        # Patch the executable to simulate rming virtualenv
        with mock.patch.object(sys, 'executable', '/bin/false'):
            assert install(Runner(path, C.CONFIG_FILE)) == 0

        # Use a specific homedir to ignore --user installs
        homedir = tempdir_factory.get()
        ret, stdout, stderr = cmd_output(
            'git', 'commit', '--allow-empty', '-m', 'foo',
            env={
                'HOME': homedir,
                'PATH': _path_without_us(),
                # Git needs this to make a commit
                'GIT_AUTHOR_NAME': os.environ['GIT_AUTHOR_NAME'],
                'GIT_COMMITTER_NAME': os.environ['GIT_COMMITTER_NAME'],
                'GIT_AUTHOR_EMAIL': os.environ['GIT_AUTHOR_EMAIL'],
                'GIT_COMMITTER_EMAIL': os.environ['GIT_COMMITTER_EMAIL'],
            },
            retcode=None,
        )
        assert ret == 1
        assert stdout == ''
        assert stderr == (
            '`pre-commit` not found.  '
            'Did you forget to activate your virtualenv?\n'
        )
예제 #9
0
def test_environment_not_sourced(tmpdir_factory):
    path = make_consuming_repo(tmpdir_factory, 'script_hooks_repo')
    with cwd(path):
        # Patch the executable to simulate rming virtualenv
        with mock.patch.object(sys, 'executable', '/bin/false'):
            assert install(Runner(path)) == 0

        # Use a specific homedir to ignore --user installs
        homedir = tmpdir_factory.get()
        # Need this so we can call git commit without sploding
        with io.open(os.path.join(homedir, '.gitconfig'), 'w') as gitconfig:
            gitconfig.write(
                '[user]\n'
                '    name = Travis CI\n'
                '    email = [email protected]\n'
            )
        ret, stdout, stderr = cmd_output(
            'git', 'commit', '--allow-empty', '-m', 'foo',
            env={'HOME': homedir},
            retcode=None,
        )
        assert ret == 1
        assert stdout == ''
        assert stderr == (
            '`pre-commit` not found.  '
            'Did you forget to activate your virtualenv?\n'
        )
예제 #10
0
def test_hook_that_modifies_but_returns_zero(
        tempdir_factory, mock_out_store_directory,
):
    git_path = make_consuming_repo(
        tempdir_factory, 'modified_file_returns_zero_repo',
    )
    with cwd(git_path):
        stage_a_file('bar.py')
        _test_run(
            git_path,
            {},
            (
                # The first should fail
                b'Failed',
                # With a modified file (default message + the hook's output)
                b'Files were modified by this hook. Additional output:\n\n'
                b'Modified: foo.py',
                # The next hook should pass despite the first modifying
                b'Passed',
                # The next hook should fail
                b'Failed',
                # bar.py was modified, but provides no additional output
                b'Files were modified by this hook.\n',
            ),
            1,
            True,
        )
예제 #11
0
def test_lots_of_files(mock_out_store_directory, tempdir_factory):
    # windows xargs seems to have a bug, here's a regression test for
    # our workaround
    git_path = make_consuming_repo(tempdir_factory, 'python_hooks_repo')
    with cwd(git_path):
        # Override files so we run against them
        with modify_config() as config:
            config[0]['hooks'][0]['files'] = ''

        # Write a crap ton of files
        for i in range(400):
            filename = '{0}{1}'.format('a' * 100, i)
            open(filename, 'w').close()

        cmd_output('bash', '-c', 'git add .')
        install(Runner(git_path))

        # Don't want to write to home directory
        env = dict(os.environ, PRE_COMMIT_HOME=tempdir_factory.get())
        cmd_output(
            'git', 'commit', '-m', 'Commit!',
            # git commit puts pre-commit to stderr
            stderr=subprocess.STDOUT,
            env=env,
        )
def test_installs_hooks_with_hooks_True(tmpdir_factory, mock_out_store_directory):
    path = make_consuming_repo(tmpdir_factory, "script_hooks_repo")
    with cwd(path):
        install(Runner(path), hooks=True)
        ret, output = _get_commit_output(tmpdir_factory, home=mock_out_store_directory)

        assert ret == 0
        assert PRE_INSTALLED.match(output)
예제 #13
0
def test_install_overwrite_no_existing_hooks(tmpdir_factory):
    path = make_consuming_repo(tmpdir_factory, 'script_hooks_repo')
    with cwd(path):
        assert install(Runner(path), overwrite=True) == 0

        ret, output = _get_commit_output(tmpdir_factory)
        assert ret == 0
        assert NORMAL_PRE_COMMIT_RUN.match(output)
def test_legacy_overwriting_legacy_hook(tempdir_factory, store):
    path = make_consuming_repo(tempdir_factory, 'script_hooks_repo')
    with cwd(path):
        _write_legacy_hook(path)
        assert install(C.CONFIG_FILE, store) == 0
        _write_legacy_hook(path)
        # this previously crashed on windows.  See #1010
        assert install(C.CONFIG_FILE, store) == 0
예제 #15
0
def test_install_pre_commit_and_run(tmpdir_factory):
    path = make_consuming_repo(tmpdir_factory, 'script_hooks_repo')
    with cwd(path):
        assert install(Runner(path)) == 0

        ret, output = _get_commit_output(tmpdir_factory)
        assert ret == 0
        assert NORMAL_PRE_COMMIT_RUN.match(output)
예제 #16
0
def test_failing_hooks_returns_nonzero(tmpdir_factory):
    path = make_consuming_repo(tmpdir_factory, 'failing_hook_repo')
    with cwd(path):
        assert install(Runner(path)) == 0

        ret, output = _get_commit_output(tmpdir_factory)
        assert ret == 1
        assert FAILING_PRE_COMMIT_RUN.match(output)
def test_install_overwrite(tempdir_factory, store):
    path = make_consuming_repo(tempdir_factory, 'script_hooks_repo')
    with cwd(path):
        _write_legacy_hook(path)
        assert install(C.CONFIG_FILE, store, overwrite=True) == 0

        ret, output = _get_commit_output(tempdir_factory)
        assert ret == 0
        assert NORMAL_PRE_COMMIT_RUN.match(output)
예제 #18
0
def test_install_idempotent(tempdir_factory):
    path = make_consuming_repo(tempdir_factory, 'script_hooks_repo')
    with cwd(path):
        assert install(Runner(path, C.CONFIG_FILE)) == 0
        assert install(Runner(path, C.CONFIG_FILE)) == 0

        ret, output = _get_commit_output(tempdir_factory)
        assert ret == 0
        assert NORMAL_PRE_COMMIT_RUN.match(output)
예제 #19
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
예제 #20
0
def aliased_repo(tempdir_factory):
    git_path = make_consuming_repo(tempdir_factory, 'script_hooks_repo')
    with cwd(git_path):
        with modify_config() as config:
            config['repos'][0]['hooks'].append(
                {'id': 'bash_hook', 'alias': 'foo_bash'},
            )
        stage_a_file()
        yield git_path
예제 #21
0
def test_install_disallow_mising_config(tempdir_factory):
    path = make_consuming_repo(tempdir_factory, 'script_hooks_repo')
    with cwd(path):
        runner = Runner(path, C.CONFIG_FILE)

        remove_config_from_repo(path)
        assert install(runner, overwrite=True, skip_on_missing_conf=False) == 0

        ret, output = _get_commit_output(tempdir_factory)
        assert ret == 1
def test_install_pre_commit_and_run_custom_path(tempdir_factory, store):
    path = make_consuming_repo(tempdir_factory, 'script_hooks_repo')
    with cwd(path):
        cmd_output('git', 'mv', C.CONFIG_FILE, 'custom-config.yaml')
        git_commit(cwd=path)
        assert install('custom-config.yaml', store) == 0

        ret, output = _get_commit_output(tempdir_factory)
        assert ret == 0
        assert NORMAL_PRE_COMMIT_RUN.match(output)
예제 #23
0
def test_unicode_merge_commit_message(tempdir_factory):
    path = make_consuming_repo(tempdir_factory, 'script_hooks_repo')
    with cwd(path):
        assert install(Runner(path, C.CONFIG_FILE)) == 0
        cmd_output('git', 'checkout', 'master', '-b', 'foo')
        cmd_output('git', 'commit', '--allow-empty', '-m', 'branch2')
        cmd_output('git', 'checkout', 'master')
        cmd_output('git', 'merge', 'foo', '--no-ff', '--no-commit', '-m', '☃')
        # Used to crash
        cmd_output('git', 'commit', '--no-edit')
예제 #24
0
def test_pre_push_integration_empty_push(tempdir_factory):
    upstream = make_consuming_repo(tempdir_factory, 'script_hooks_repo')
    path = tempdir_factory.get()
    cmd_output('git', 'clone', upstream, path)
    with cwd(path):
        install(Runner(path), hook_type='pre-push')
        _get_push_output(tempdir_factory)
        retc, output = _get_push_output(tempdir_factory)
        assert output == 'Everything up-to-date\n'
        assert retc == 0
def test_installs_hooks_with_hooks_True(tempdir_factory, store):
    path = make_consuming_repo(tempdir_factory, 'script_hooks_repo')
    with cwd(path):
        install(C.CONFIG_FILE, store, hooks=True)
        ret, output = _get_commit_output(
            tempdir_factory, pre_commit_home=store.directory,
        )

        assert ret == 0
        assert PRE_INSTALLED.match(output)
예제 #26
0
def in_merge_conflict(tempdir_factory):
    path = make_consuming_repo(tempdir_factory, 'script_hooks_repo')
    open(os.path.join(path, 'dummy'), 'a').close()
    cmd_output('git', 'add', 'dummy', cwd=path)
    git_commit(msg=in_merge_conflict.__name__, cwd=path)

    conflict_path = tempdir_factory.get()
    cmd_output('git', 'clone', path, conflict_path)
    with cwd(conflict_path):
        _make_conflict()
        yield os.path.join(conflict_path)
def test_install_in_worktree_and_run(tempdir_factory, store):
    src_path = make_consuming_repo(tempdir_factory, 'script_hooks_repo')
    path = tempdir_factory.get()
    cmd_output('git', '-C', src_path, 'branch', '-m', 'notmaster')
    cmd_output('git', '-C', src_path, 'worktree', 'add', path, '-b', 'master')

    with cwd(path):
        assert install(C.CONFIG_FILE, store) == 0
        ret, output = _get_commit_output(tempdir_factory)
        assert ret == 0
        assert NORMAL_PRE_COMMIT_RUN.match(output)
예제 #28
0
def test_install_hooks_command(tempdir_factory, mock_out_store_directory):
    path = make_consuming_repo(tempdir_factory, 'script_hooks_repo')
    with cwd(path):
        runner = Runner(path, C.CONFIG_FILE)
        install(runner)
        install_hooks(runner)
        ret, output = _get_commit_output(
            tempdir_factory, pre_commit_home=mock_out_store_directory,
        )

        assert ret == 0
        assert PRE_INSTALLED.match(output)
예제 #29
0
def in_merge_conflict(tempdir_factory):
    path = make_consuming_repo(tempdir_factory, 'script_hooks_repo')
    with cwd(path):
        cmd_output('touch', 'dummy')
        cmd_output('git', 'add', 'dummy')
        cmd_output('git', 'commit', '-m', 'Add config.')

    conflict_path = tempdir_factory.get()
    cmd_output('git', 'clone', path, conflict_path)
    with cwd(conflict_path):
        _make_conflict()
        yield os.path.join(conflict_path)
예제 #30
0
def test_pre_push_integration_accepted(tmpdir_factory):
    upstream = make_consuming_repo(tmpdir_factory, 'script_hooks_repo')
    path = tmpdir_factory.get()
    cmd_output('git', 'clone', upstream, path)
    with cwd(path):
        install(Runner(path), hook_type='pre-push')
        assert _get_commit_output(tmpdir_factory)[0] == 0

        retc, output = _get_push_output(tmpdir_factory)
        assert retc == 0
        assert 'Bash hook' in output
        assert 'Passed' in output
예제 #31
0
def test_show_diff_on_failure(
    capfd,
    cap_out,
    tempdir_factory,
    mock_out_store_directory,
):
    git_path = make_consuming_repo(
        tempdir_factory,
        'modified_file_returns_zero_repo',
    )
    with cwd(git_path):
        stage_a_file('bar.py')
        _test_run(
            cap_out,
            git_path,
            {'show_diff_on_failure': True},
            # we're only testing the output after running
            (),
            1,
            True,
        )
    out, _ = capfd.readouterr()
    assert 'diff --git' in out
예제 #32
0
def test_lots_of_files(mock_out_store_directory, tempdir_factory):
    # windows xargs seems to have a bug, here's a regression test for
    # our workaround
    git_path = make_consuming_repo(tempdir_factory, 'python_hooks_repo')
    with cwd(git_path):
        # Override files so we run against them
        with modify_config() as config:
            config[0]['hooks'][0]['files'] = ''

        # Write a crap ton of files
        for i in range(400):
            filename = '{}{}'.format('a' * 100, i)
            open(filename, 'w').close()

        cmd_output('bash', '-c', 'git add .')
        install(Runner(git_path, C.CONFIG_FILE))

        cmd_output_mocked_pre_commit_home(
            'git', 'commit', '-m', 'Commit!',
            # git commit puts pre-commit to stderr
            stderr=subprocess.STDOUT,
            tempdir_factory=tempdir_factory,
        )
예제 #33
0
def test_hook_install_failure(mock_out_store_directory, tempdir_factory):
    git_path = make_consuming_repo(tempdir_factory, 'not_installable_repo')
    with cwd(git_path):
        install(Runner(git_path, C.CONFIG_FILE))

        _, stdout, _ = cmd_output_mocked_pre_commit_home(
            'git', 'commit', '-m', 'Commit!',
            # git commit puts pre-commit to stderr
            stderr=subprocess.STDOUT,
            retcode=None,
            encoding=None,
            tempdir_factory=tempdir_factory,
        )
        assert b'UnicodeDecodeError' not in stdout
        # Doesn't actually happen, but a reasonable assertion
        assert b'UnicodeEncodeError' not in stdout

        # Sanity check our output
        assert (
            b'An unexpected error has occurred: CalledProcessError: ' in
            stdout
        )
        assert '☃'.encode('UTF-8') + '²'.encode('latin1') in stdout
def test_replace_old_commit_script(tempdir_factory):
    path = make_consuming_repo(tempdir_factory, 'script_hooks_repo')
    with cwd(path):
        runner = Runner(path)

        # Install a script that looks like our old script
        pre_commit_contents = io.open(resource_filename('hook-tmpl'), ).read()
        new_contents = pre_commit_contents.replace(
            IDENTIFYING_HASH,
            PREVIOUS_IDENTIFYING_HASHES[-1],
        )

        mkdirp(os.path.dirname(runner.pre_commit_path))
        with io.open(runner.pre_commit_path, 'w') as pre_commit_file:
            pre_commit_file.write(new_contents)
        make_executable(runner.pre_commit_path)

        # Install normally
        assert install(runner) == 0

        ret, output = _get_commit_output(tempdir_factory)
        assert ret == 0
        assert NORMAL_PRE_COMMIT_RUN.match(output)
예제 #35
0
def test_replace_old_commit_script(tempdir_factory, store):
    path = make_consuming_repo(tempdir_factory, 'script_hooks_repo')
    with cwd(path):
        runner = Runner(path, C.CONFIG_FILE)

        # Install a script that looks like our old script
        pre_commit_contents = resource_text('hook-tmpl')
        new_contents = pre_commit_contents.replace(
            CURRENT_HASH,
            PRIOR_HASHES[-1],
        )

        mkdirp(os.path.join(path, '.git/hooks'))
        with io.open(os.path.join(path, '.git/hooks/pre-commit'), 'w') as f:
            f.write(new_contents)
        make_executable(f.name)

        # Install normally
        assert install(runner, store) == 0

        ret, output = _get_commit_output(tempdir_factory)
        assert ret == 0
        assert NORMAL_PRE_COMMIT_RUN.match(output)
예제 #36
0
def test_lots_of_files(store, tempdir_factory):
    # windows xargs seems to have a bug, here's a regression test for
    # our workaround
    git_path = make_consuming_repo(tempdir_factory, 'script_hooks_repo')
    with cwd(git_path):
        # Override files so we run against them
        with modify_config() as config:
            config['repos'][0]['hooks'][0]['files'] = ''

        # Write a crap ton of files
        for i in range(400):
            filename = '{}{}'.format('a' * 100, i)
            open(filename, 'w').close()

        cmd_output('git', 'add', '.')
        install(C.CONFIG_FILE, store)

        git_commit(
            fn=cmd_output_mocked_pre_commit_home,
            # git commit puts pre-commit to stderr
            stderr=subprocess.STDOUT,
            tempdir_factory=tempdir_factory,
        )
예제 #37
0
def test_install_existing_hooks_no_overwrite(tmpdir_factory):
    path = make_consuming_repo(tmpdir_factory, 'script_hooks_repo')
    with cwd(path):
        runner = Runner(path)

        # Write out an "old" hook
        with io.open(runner.pre_commit_path, 'w') as hook_file:
            hook_file.write('#!/usr/bin/env bash\necho "legacy hook"\n')
        make_executable(runner.pre_commit_path)

        # Make sure we installed the "old" hook correctly
        ret, output = _get_commit_output(tmpdir_factory, touch_file='baz')
        assert ret == 0
        assert EXISTING_COMMIT_RUN.match(output)

        # Now install pre-commit (no-overwrite)
        assert install(runner) == 0

        # We should run both the legacy and pre-commit hooks
        ret, output = _get_commit_output(tmpdir_factory)
        assert ret == 0
        assert output.startswith('legacy hook\n')
        assert NORMAL_PRE_COMMIT_RUN.match(output[len('legacy hook\n'):])
예제 #38
0
def test_run_output_logfile(cap_out, store, tempdir_factory):
    expected_output = (
        b'This is STDOUT output\n',
        b'This is STDERR output\n',
    )

    git_path = make_consuming_repo(tempdir_factory, 'logfile_repo')
    with cwd(git_path):
        _test_run(
            cap_out,
            store,
            git_path, {},
            expected_output,
            expected_ret=1,
            stage=True,
        )
    logfile_path = os.path.join(git_path, 'test.log')
    assert os.path.exists(logfile_path)
    with open(logfile_path, 'rb') as logfile:
        logfile_content = logfile.readlines()

    for expected_output_part in expected_output:
        assert expected_output_part in logfile_content
예제 #39
0
def test_pre_push_legacy(tempdir_factory, store):
    upstream = make_consuming_repo(tempdir_factory, 'script_hooks_repo')
    path = tempdir_factory.get()
    cmd_output('git', 'clone', upstream, path)
    with cwd(path):
        os.makedirs(os.path.join(path, '.git/hooks'), exist_ok=True)
        with open(os.path.join(path, '.git/hooks/pre-push'), 'w') as f:
            f.write(
                '#!/usr/bin/env bash\n'
                'set -eu\n'
                'read lr ls rr rs\n'
                'test -n "$lr" -a -n "$ls" -a -n "$rr" -a -n "$rs"\n'
                'echo legacy\n', )
        make_executable(f.name)

        install(C.CONFIG_FILE, store, hook_types=['pre-push'])
        assert _get_commit_output(tempdir_factory)[0] == 0

        retc, output = _get_push_output(tempdir_factory)
        assert retc == 0
        first_line, _, third_line = output.splitlines()[:3]
        assert first_line == 'legacy'
        assert third_line.startswith('Bash hook')
        assert third_line.endswith('Passed')
예제 #40
0
def test_environment_not_sourced(tempdir_factory, store):
    path = make_consuming_repo(tempdir_factory, 'script_hooks_repo')
    with cwd(path):
        # Patch the executable to simulate rming virtualenv
        with mock.patch.object(sys, 'executable', '/does-not-exist'):
            assert not install(C.CONFIG_FILE, store, hook_types=['pre-commit'])

        # Use a specific homedir to ignore --user installs
        homedir = tempdir_factory.get()
        ret, out = git_commit(
            env={
                'HOME': homedir,
                'PATH': _path_without_us(),
                # Git needs this to make a commit
                'GIT_AUTHOR_NAME': os.environ['GIT_AUTHOR_NAME'],
                'GIT_COMMITTER_NAME': os.environ['GIT_COMMITTER_NAME'],
                'GIT_AUTHOR_EMAIL': os.environ['GIT_AUTHOR_EMAIL'],
                'GIT_COMMITTER_EMAIL': os.environ['GIT_COMMITTER_EMAIL'],
            },
            retcode=None,
        )
        assert ret == 1
        assert out == ('`pre-commit` not found.  '
                       'Did you forget to activate your virtualenv?\n')
def test_pre_merge_commit_integration(tempdir_factory, store):
    output_pattern = re_assert.Matches(
        r'^\[INFO\] Initializing environment for .+\n'
        r'Bash hook\.+Passed\n'
        r"Merge made by the '(ort|recursive)' strategy.\n"
        r' foo \| 0\n'
        r' 1 file changed, 0 insertions\(\+\), 0 deletions\(-\)\n'
        r' create mode 100644 foo\n$',
    )

    path = make_consuming_repo(tempdir_factory, 'script_hooks_repo')
    with cwd(path):
        ret = install(C.CONFIG_FILE, store, hook_types=['pre-merge-commit'])
        assert ret == 0

        cmd_output('git', 'checkout', 'master', '-b', 'feature')
        _get_commit_output(tempdir_factory)
        cmd_output('git', 'checkout', 'master')
        ret, output, _ = cmd_output_mocked_pre_commit_home(
            'git', 'merge', '--no-ff', '--no-edit', 'feature',
            tempdir_factory=tempdir_factory,
        )
        assert ret == 0
        output_pattern.assert_matches(output)
def test_init_templatedir(tmpdir, tempdir_factory, store, cap_out):
    target = str(tmpdir.join('tmpl'))
    init_templatedir(C.CONFIG_FILE, store, target, hook_type='pre-commit')
    lines = cap_out.get().splitlines()
    assert lines[0].startswith('pre-commit installed at ')
    assert lines[1] == (
        '[WARNING] `init.templateDir` not set to the target directory'
    )
    assert lines[2].startswith(
        '[WARNING] maybe `git config --global init.templateDir',
    )

    with envcontext([('GIT_TEMPLATE_DIR', target)]):
        path = make_consuming_repo(tempdir_factory, 'script_hooks_repo')

        with cwd(path):
            retcode, output, _ = git_commit(
                fn=cmd_output_mocked_pre_commit_home,
                tempdir_factory=tempdir_factory,
                # git commit puts pre-commit to stderr
                stderr=subprocess.STDOUT,
            )
            assert retcode == 0
            assert 'Bash hook....' in output
예제 #43
0
파일: run_test.py 프로젝트: xiar/pre-commit
def repo_with_failing_hook(tempdir_factory):
    git_path = make_consuming_repo(tempdir_factory, 'failing_hook_repo')
    with cwd(git_path):
        yield git_path
예제 #44
0
파일: run_test.py 프로젝트: xiar/pre-commit
def repo_with_passing_hook(tempdir_factory):
    git_path = make_consuming_repo(tempdir_factory, 'script_hooks_repo')
    with cwd(git_path):
        yield git_path
예제 #45
0
def test_arbitrary_bytes_hook(cap_out, store, tempdir_factory):
    git_path = make_consuming_repo(tempdir_factory, 'arbitrary_bytes_repo')
    with cwd(git_path):
        _test_run(
            cap_out, store, git_path, {}, (b'\xe2\x98\x83\xb2\n',), 1, True,
        )
예제 #46
0
def test_repositories(tempdir_factory, mock_out_store_directory):
    path = make_consuming_repo(tempdir_factory, 'script_hooks_repo')
    runner = Runner(path, C.CONFIG_FILE)
    assert len(runner.repositories) == 1