Example #1
0
def test_loses_formatting_when_not_detectable(
    out_of_date_repo,
    store,
    in_tmpdir,
):
    """A best-effort attempt is made at updating rev without rewriting
    formatting.  When the original formatting cannot be detected, this
    is abandoned.
    """
    config = ('repos: [\n'
              '    {{\n'
              '        repo: {}, rev: {},\n'
              '        hooks: [\n'
              '            # A comment!\n'
              '            {{id: foo}},\n'
              '        ],\n'
              '    }}\n'
              ']\n'.format(
                  pipes.quote(out_of_date_repo.path),
                  out_of_date_repo.original_rev,
              ))
    with open(C.CONFIG_FILE, 'w') as f:
        f.write(config)

    autoupdate(Runner('.', C.CONFIG_FILE), store, tags_only=False)
    with open(C.CONFIG_FILE) as f:
        after = f.read()
    expected = ('repos:\n'
                '-   repo: {}\n'
                '    rev: {}\n'
                '    hooks:\n'
                '    -   id: foo\n').format(out_of_date_repo.path,
                                            out_of_date_repo.head_rev)
    assert after == expected
Example #2
0
def test_loses_formatting_when_not_detectable(
        out_of_date_repo, mock_out_store_directory, in_tmpdir,
):
    """A best-effort attempt is made at updating sha without rewriting
    formatting.  When the original formatting cannot be detected, this
    is abandoned.
    """
    config = (
        'repos: [\n'
        '    {{\n'
        '        repo: {}, sha: {},\n'
        '        hooks: [\n'
        '            # A comment!\n'
        '            {{id: foo}},\n'
        '        ],\n'
        '    }}\n'
        ']\n'.format(
            pipes.quote(out_of_date_repo.path), out_of_date_repo.original_sha,
        )
    )
    with open(C.CONFIG_FILE, 'w') as f:
        f.write(config)

    autoupdate(Runner('.', C.CONFIG_FILE), tags_only=False)
    after = open(C.CONFIG_FILE).read()
    expected = (
        'repos:\n'
        '-   repo: {}\n'
        '    sha: {}\n'
        '    hooks:\n'
        '    -   id: foo\n'
    ).format(out_of_date_repo.path, out_of_date_repo.head_sha)
    assert after == expected
Example #3
0
def test_autoupdate_freeze(tagged, in_tmpdir, store):
    config = make_config_from_repo(tagged.path, rev=tagged.original_rev)
    write_config('.', config)

    assert autoupdate(C.CONFIG_FILE, store, freeze=True, tags_only=False) == 0
    with open(C.CONFIG_FILE) as f:
        expected = f'rev: {tagged.head_rev}  # frozen: v1.2.3'
        assert expected in f.read()

    # if we un-freeze it should remove the frozen comment
    assert autoupdate(C.CONFIG_FILE, store, freeze=False, tags_only=False) == 0
    with open(C.CONFIG_FILE) as f:
        assert 'rev: v1.2.3\n' in f.read()
Example #4
0
def test_does_not_reformat(in_tmpdir, out_of_date_repo, store):
    fmt = ('repos:\n'
           '-   repo: {}\n'
           '    rev: {}  # definitely the version I want!\n'
           '    hooks:\n'
           '    -   id: foo\n'
           '        # These args are because reasons!\n'
           '        args: [foo, bar, baz]\n')
    config = fmt.format(out_of_date_repo.path, out_of_date_repo.original_rev)
    with open(C.CONFIG_FILE, 'w') as f:
        f.write(config)

    autoupdate(Runner('.', C.CONFIG_FILE), store, tags_only=False)
    after = open(C.CONFIG_FILE).read()
    expected = fmt.format(out_of_date_repo.path, out_of_date_repo.head_rev)
    assert after == expected
Example #5
0
def test_autoupdate_only_one_to_update(up_to_date, out_of_date, tmpdir, store):
    fmt = ('repos:\n'
           '-   repo: {}\n'
           '    rev: {}\n'
           '    hooks:\n'
           '    -   id: foo\n'
           '-   repo: {}\n'
           '    rev: {}\n'
           '    hooks:\n'
           '    -   id: foo\n')
    cfg = tmpdir.join(C.CONFIG_FILE)
    before = fmt.format(
        up_to_date,
        git.head_rev(up_to_date),
        out_of_date.path,
        out_of_date.original_rev,
    )
    cfg.write(before)

    assert autoupdate(str(cfg), store, freeze=False, tags_only=False) == 0
    assert cfg.read() == fmt.format(
        up_to_date,
        git.head_rev(up_to_date),
        out_of_date.path,
        out_of_date.head_rev,
    )
Example #6
0
def test_autoupdate_old_revision_broken(tempdir_factory, in_tmpdir, store):
    """In $FUTURE_VERSION, hooks.yaml will no longer be supported.  This
    asserts that when that day comes, pre-commit will be able to autoupdate
    despite not being able to read hooks.yaml in that repository.
    """
    path = make_repo(tempdir_factory, 'python_hooks_repo')
    config = make_config_from_repo(path, check=False)

    cmd_output('git', 'mv', C.MANIFEST_FILE, 'nope.yaml', cwd=path)
    git_commit(cwd=path)
    # Assume this is the revision the user's old repository was at
    rev = git.head_rev(path)
    cmd_output('git', 'mv', 'nope.yaml', C.MANIFEST_FILE, cwd=path)
    git_commit(cwd=path)
    update_rev = git.head_rev(path)

    config['rev'] = rev
    write_config('.', config)
    with open(C.CONFIG_FILE) as f:
        before = f.read()
    assert autoupdate(C.CONFIG_FILE, store, freeze=False, tags_only=False) == 0
    with open(C.CONFIG_FILE) as f:
        after = f.read()
    assert before != after
    assert update_rev in after
Example #7
0
def test_autoupdate_old_revision_broken(tempdir_factory, in_tmpdir, store):
    """In $FUTURE_VERSION, hooks.yaml will no longer be supported.  This
    asserts that when that day comes, pre-commit will be able to autoupdate
    despite not being able to read hooks.yaml in that repository.
    """
    path = make_repo(tempdir_factory, 'python_hooks_repo')
    config = make_config_from_repo(path, check=False)

    cmd_output('git', 'mv', C.MANIFEST_FILE, 'nope.yaml', cwd=path)
    git_commit(cwd=path)
    # Assume this is the revision the user's old repository was at
    rev = git.head_rev(path)
    cmd_output('git', 'mv', 'nope.yaml', C.MANIFEST_FILE, cwd=path)
    git_commit(cwd=path)
    update_rev = git.head_rev(path)

    config['rev'] = rev
    write_config('.', config)
    with open(C.CONFIG_FILE) as f:
        before = f.read()
    ret = autoupdate(C.CONFIG_FILE, store, tags_only=False)
    with open(C.CONFIG_FILE) as f:
        after = f.read()
    assert ret == 0
    assert before != after
    assert update_rev in after
Example #8
0
def test_updates_old_format_to_new_format(tmpdir, capsys, store):
    cfg = tmpdir.join(C.CONFIG_FILE)
    cfg.write(
        '-   repo: local\n'
        '    hooks:\n'
        '    -   id: foo\n'
        '        name: foo\n'
        '        entry: ./bin/foo.sh\n'
        '        language: script\n',
    )
    with tmpdir.as_cwd():
        ret = autoupdate(C.CONFIG_FILE, store, tags_only=True)
    assert ret == 0
    contents = cfg.read()
    assert contents == (
        'repos:\n'
        '-   repo: local\n'
        '    hooks:\n'
        '    -   id: foo\n'
        '        name: foo\n'
        '        entry: ./bin/foo.sh\n'
        '        language: script\n'
    )
    out, _ = capsys.readouterr()
    assert out == 'Configuration has been migrated.\n'
Example #9
0
def test_autoupdate_out_of_date_repo_with_wrong_repo_name(
    out_of_date,
    in_tmpdir,
    store,
):
    config = make_config_from_repo(
        out_of_date.path,
        rev=out_of_date.original_rev,
        check=False,
    )
    write_config('.', config)

    with open(C.CONFIG_FILE) as f:
        before = f.read()
    # It will not update it, because the name doesn't match
    ret = autoupdate(
        C.CONFIG_FILE,
        store,
        freeze=False,
        tags_only=False,
        repos=('dne', ),
    )
    with open(C.CONFIG_FILE) as f:
        after = f.read()
    assert ret == 0
    assert before == after
Example #10
0
def test_autoupdate_out_of_date_repo_with_correct_repo_name(
    out_of_date,
    in_tmpdir,
    store,
):
    stale_config = make_config_from_repo(
        out_of_date.path,
        rev=out_of_date.original_rev,
        check=False,
    )
    local_config = sample_local_config()
    config = {'repos': [stale_config, local_config]}
    write_config('.', config)

    with open(C.CONFIG_FILE) as f:
        before = f.read()
    repo_name = f'file://{out_of_date.path}'
    ret = autoupdate(
        C.CONFIG_FILE,
        store,
        freeze=False,
        tags_only=False,
        repos=(repo_name, ),
    )
    with open(C.CONFIG_FILE) as f:
        after = f.read()
    assert ret == 0
    assert before != after
    assert out_of_date.head_rev in after
    assert 'local' in after
Example #11
0
def test_autoupdate_tagged_repo(tagged, in_tmpdir, store):
    config = make_config_from_repo(tagged.path, rev=tagged.original_rev)
    write_config('.', config)

    assert autoupdate(C.CONFIG_FILE, store, freeze=False, tags_only=False) == 0
    with open(C.CONFIG_FILE) as f:
        assert 'v1.2.3' in f.read()
Example #12
0
def test_loses_formatting_when_not_detectable(out_of_date, store, tmpdir):
    """A best-effort attempt is made at updating rev without rewriting
    formatting.  When the original formatting cannot be detected, this
    is abandoned.
    """
    config = ('repos: [\n'
              '    {{\n'
              '        repo: {}, rev: {},\n'
              '        hooks: [\n'
              '            # A comment!\n'
              '            {{id: foo}},\n'
              '        ],\n'
              '    }}\n'
              ']\n'.format(
                  shlex.quote(out_of_date.path),
                  out_of_date.original_rev,
              ))
    cfg = tmpdir.join(C.CONFIG_FILE)
    cfg.write(config)

    assert autoupdate(str(cfg), store, freeze=False, tags_only=False) == 0
    expected = (f'repos:\n'
                f'-   repo: {out_of_date.path}\n'
                f'    rev: {out_of_date.head_rev}\n'
                f'    hooks:\n'
                f'    -   id: foo\n')
    assert cfg.read() == expected
Example #13
0
def test_updates_old_format_to_new_format(tmpdir, capsys, store):
    cfg = tmpdir.join(C.CONFIG_FILE)
    cfg.write(
        '-   repo: local\n'
        '    hooks:\n'
        '    -   id: foo\n'
        '        name: foo\n'
        '        entry: ./bin/foo.sh\n'
        '        language: script\n',
    )
    with tmpdir.as_cwd():
        ret = autoupdate(C.CONFIG_FILE, store, tags_only=True)
    assert ret == 0
    contents = cfg.read()
    assert contents == (
        'repos:\n'
        '-   repo: local\n'
        '    hooks:\n'
        '    -   id: foo\n'
        '        name: foo\n'
        '        entry: ./bin/foo.sh\n'
        '        language: script\n'
    )
    out, _ = capsys.readouterr()
    assert out == 'Configuration has been migrated.\n'
Example #14
0
def test_autoupdate_out_of_date_repo_with_correct_repo_name(
    out_of_date_repo,
    in_tmpdir,
    store,
):
    stale_config = make_config_from_repo(
        out_of_date_repo.path,
        rev=out_of_date_repo.original_rev,
        check=False,
    )
    local_config = config_with_local_hooks()
    config = {'repos': [stale_config, local_config]}
    # Write out the config
    write_config('.', config)

    runner = Runner('.', C.CONFIG_FILE)
    with open(C.CONFIG_FILE) as f:
        before = f.read()
    repo_name = 'file://{}'.format(out_of_date_repo.path)
    ret = autoupdate(runner, store, tags_only=False, repos=(repo_name, ))
    with open(C.CONFIG_FILE) as f:
        after = f.read()
    assert ret == 0
    assert before != after
    assert out_of_date_repo.head_rev in after
    assert local_config['repo'] in after
def test_autoupdate_old_revision_broken(
    tempdir_factory, in_tmpdir, mock_out_store_directory,
):
    """In $FUTURE_VERSION, hooks.yaml will no longer be supported.  This
    asserts that when that day comes, pre-commit will be able to autoupdate
    despite not being able to read hooks.yaml in that repository.
    """
    path = make_repo(tempdir_factory, 'python_hooks_repo')
    config = make_config_from_repo(path, check=False)

    with cwd(path):
        cmd_output('git', 'mv', C.MANIFEST_FILE, 'nope.yaml')
        cmd_output('git', 'commit', '-m', 'simulate old repo')
        # Assume this is the revision the user's old repository was at
        rev = git.head_sha(path)
        cmd_output('git', 'mv', 'nope.yaml', C.MANIFEST_FILE)
        cmd_output('git', 'commit', '-m', 'move hooks file')
        update_rev = git.head_sha(path)

    config['sha'] = rev
    write_config('.', config)
    before = open(C.CONFIG_FILE).read()
    ret = autoupdate(Runner('.', C.CONFIG_FILE), tags_only=False)
    after = open(C.CONFIG_FILE).read()
    assert ret == 0
    assert before != after
    assert update_rev in after
Example #16
0
def test_autoupdate_local_hooks(in_git_dir, store):
    config = sample_local_config()
    add_config_to_repo('.', config)
    assert autoupdate(C.CONFIG_FILE, store, freeze=False, tags_only=False) == 0
    new_config_writen = read_config('.')
    assert len(new_config_writen['repos']) == 1
    assert new_config_writen['repos'][0] == config
Example #17
0
def test_autoupdate_old_revision_broken(
    tempdir_factory, in_tmpdir, mock_out_store_directory,
):
    """In $FUTURE_VERSION, hooks.yaml will no longer be supported.  This
    asserts that when that day comes, pre-commit will be able to autoupdate
    despite not being able to read hooks.yaml in that repository.
    """
    path = make_repo(tempdir_factory, 'python_hooks_repo')
    config = make_config_from_repo(path, check=False)

    with cwd(path):
        cmd_output('git', 'mv', C.MANIFEST_FILE, 'nope.yaml')
        cmd_output('git', 'commit', '-m', 'simulate old repo')
        # Assume this is the revision the user's old repository was at
        rev = get_head_sha(path)
        cmd_output('git', 'mv', 'nope.yaml', C.MANIFEST_FILE)
        cmd_output('git', 'commit', '-m', 'move hooks file')
        update_rev = get_head_sha(path)

    config['sha'] = rev
    write_config('.', config)
    before = open(C.CONFIG_FILE).read()
    ret = autoupdate(Runner('.', C.CONFIG_FILE), tags_only=False)
    after = open(C.CONFIG_FILE).read()
    assert ret == 0
    assert before != after
    assert update_rev in after
Example #18
0
def test_autoupdate_local_hooks(in_git_dir, store):
    config = sample_local_config()
    add_config_to_repo('.', config)
    assert autoupdate(C.CONFIG_FILE, store, tags_only=False) == 0
    new_config_writen = read_config('.')
    assert len(new_config_writen['repos']) == 1
    assert new_config_writen['repos'][0] == config
Example #19
0
def test_autoupdate_local_hooks(tmpdir_factory):
    git_path = git_dir(tmpdir_factory)
    config = config_with_local_hooks()
    path = add_config_to_repo(git_path, config)
    runner = Runner(path)
    assert autoupdate(runner) == 0
    new_config_writen = load_config(runner.config_file_path)
    assert len(new_config_writen) == 1
    assert new_config_writen[0] == config
Example #20
0
def test_autoupdate_local_hooks(tempdir_factory):
    git_path = git_dir(tempdir_factory)
    config = config_with_local_hooks()
    path = add_config_to_repo(git_path, config)
    runner = Runner(path, C.CONFIG_FILE)
    assert autoupdate(runner, tags_only=False) == 0
    new_config_writen = load_config(runner.config_file_path)
    assert len(new_config_writen['repos']) == 1
    assert new_config_writen['repos'][0] == config
Example #21
0
def test_autoupdate_local_hooks(tempdir_factory):
    git_path = git_dir(tempdir_factory)
    config = config_with_local_hooks()
    path = add_config_to_repo(git_path, config)
    runner = Runner(path)
    assert autoupdate(runner) == 0
    new_config_writen = load_config(runner.config_file_path)
    assert len(new_config_writen) == 1
    assert new_config_writen[0] == config
Example #22
0
def test_autoupdate_local_hooks(tempdir_factory, store):
    git_path = git_dir(tempdir_factory)
    config = config_with_local_hooks()
    path = add_config_to_repo(git_path, config)
    runner = Runner(path, C.CONFIG_FILE)
    assert autoupdate(runner, store, tags_only=False) == 0
    new_config_writen = load_config(runner.config_file_path)
    assert len(new_config_writen['repos']) == 1
    assert new_config_writen['repos'][0] == config
Example #23
0
def test_autoupdate_tags_only(tagged_repo_with_more_commits, in_tmpdir, store):
    config = make_config_from_repo(
        tagged_repo_with_more_commits.path,
        rev=tagged_repo_with_more_commits.original_rev,
    )
    write_config('.', config)

    ret = autoupdate(Runner('.', C.CONFIG_FILE), store, tags_only=True)
    assert ret == 0
    assert 'v1.2.3' in open(C.CONFIG_FILE).read()
Example #24
0
def test_autoupdate_tags_only(tagged, in_tmpdir, store):
    # add some commits after the tag
    git_commit(cwd=tagged.path)

    config = make_config_from_repo(tagged.path, rev=tagged.original_rev)
    write_config('.', config)

    assert autoupdate(C.CONFIG_FILE, store, freeze=False, tags_only=True) == 0
    with open(C.CONFIG_FILE) as f:
        assert 'v1.2.3' in f.read()
Example #25
0
def test_does_not_reformat(in_tmpdir, out_of_date_repo, store):
    fmt = (
        'repos:\n'
        '-   repo: {}\n'
        '    rev: {}  # definitely the version I want!\n'
        '    hooks:\n'
        '    -   id: foo\n'
        '        # These args are because reasons!\n'
        '        args: [foo, bar, baz]\n'
    )
    config = fmt.format(out_of_date_repo.path, out_of_date_repo.original_rev)
    with open(C.CONFIG_FILE, 'w') as f:
        f.write(config)

    autoupdate(C.CONFIG_FILE, store, tags_only=False)
    with open(C.CONFIG_FILE) as f:
        after = f.read()
    expected = fmt.format(out_of_date_repo.path, out_of_date_repo.head_rev)
    assert after == expected
Example #26
0
def test_autoupdate_tagged_repo(tagged_repo, in_tmpdir, store):
    config = make_config_from_repo(
        tagged_repo.path, rev=tagged_repo.original_rev,
    )
    write_config('.', config)

    ret = autoupdate(C.CONFIG_FILE, store, tags_only=False)
    assert ret == 0
    with open(C.CONFIG_FILE) as f:
        assert 'v1.2.3' in f.read()
def test_autoupdate_tagged_repo(
        tagged_repo, in_tmpdir, mock_out_store_directory,
):
    config = make_config_from_repo(
        tagged_repo.path, sha=tagged_repo.original_sha,
    )
    write_config('.', config)

    ret = autoupdate(Runner('.', C.CONFIG_FILE), tags_only=False)
    assert ret == 0
    assert 'v1.2.3' in open(C.CONFIG_FILE).read()
Example #28
0
def test_autoupdate_tagged_repo(
        tagged_repo, in_tmpdir, mock_out_store_directory,
):
    config = make_config_from_repo(
        tagged_repo.path, sha=tagged_repo.original_sha,
    )
    write_config('.', config)

    ret = autoupdate(Runner('.', C.CONFIG_FILE), tags_only=False)
    assert ret == 0
    assert 'v1.2.3' in open(C.CONFIG_FILE).read()
Example #29
0
def test_does_not_reformat(
        out_of_date_repo, mock_out_store_directory, in_tmpdir,
):
    fmt = (
        'repos:\n'
        '-   repo: {}\n'
        '    sha: {}  # definitely the version I want!\n'
        '    hooks:\n'
        '    -   id: foo\n'
        '        # These args are because reasons!\n'
        '        args: [foo, bar, baz]\n'
    )
    config = fmt.format(out_of_date_repo.path, out_of_date_repo.original_sha)
    with open(C.CONFIG_FILE, 'w') as f:
        f.write(config)

    autoupdate(Runner('.', C.CONFIG_FILE), tags_only=False)
    after = open(C.CONFIG_FILE).read()
    expected = fmt.format(out_of_date_repo.path, out_of_date_repo.head_sha)
    assert after == expected
Example #30
0
def test_autoupdate_hook_disappearing_repo(hook_disappearing, tmpdir, store):
    contents = (f'repos:\n'
                f'-   repo: {hook_disappearing.path}\n'
                f'    rev: {hook_disappearing.original_rev}\n'
                f'    hooks:\n'
                f'    -   id: foo\n')
    cfg = tmpdir.join(C.CONFIG_FILE)
    cfg.write(contents)

    assert autoupdate(str(cfg), store, freeze=False, tags_only=False) == 1
    assert cfg.read() == contents
Example #31
0
def test_autoupdate_up_to_date_repo(up_to_date_repo, in_tmpdir, store):
    # Write out the config
    config = make_config_from_repo(up_to_date_repo, check=False)
    write_config('.', config)

    before = open(C.CONFIG_FILE).read()
    assert '^$' not in before
    ret = autoupdate(Runner('.', C.CONFIG_FILE), store, tags_only=False)
    after = open(C.CONFIG_FILE).read()
    assert ret == 0
    assert before == after
Example #32
0
def test_autoupdate_tagged_repo(tagged_repo, in_tmpdir, store):
    config = make_config_from_repo(
        tagged_repo.path,
        rev=tagged_repo.original_rev,
    )
    write_config('.', config)

    ret = autoupdate(Runner('.', C.CONFIG_FILE), store, tags_only=False)
    assert ret == 0
    with open(C.CONFIG_FILE) as f:
        assert 'v1.2.3' in f.read()
Example #33
0
def test_autoupdate_up_to_date_repo(up_to_date, tmpdir, store):
    contents = (f'repos:\n'
                f'-   repo: {up_to_date}\n'
                f'    rev: {git.head_rev(up_to_date)}\n'
                f'    hooks:\n'
                f'    -   id: foo\n')
    cfg = tmpdir.join(C.CONFIG_FILE)
    cfg.write(contents)

    assert autoupdate(str(cfg), store, freeze=False, tags_only=False) == 0
    assert cfg.read() == contents
Example #34
0
def test_autoupdate_meta_hooks(tmpdir, store):
    cfg = tmpdir.join(C.CONFIG_FILE)
    cfg.write(
        'repos:\n'
        '-   repo: meta\n'
        '    hooks:\n'
        '    -   id: check-useless-excludes\n', )
    assert autoupdate(str(cfg), store, freeze=False, tags_only=True) == 0
    assert cfg.read() == ('repos:\n'
                          '-   repo: meta\n'
                          '    hooks:\n'
                          '    -   id: check-useless-excludes\n')
Example #35
0
def test_autoupdate_latest_no_config(out_of_date, in_tmpdir, store):
    config = make_config_from_repo(
        out_of_date.path, rev=out_of_date.original_rev,
    )
    write_config('.', config)

    cmd_output('git', 'rm', '-r', ':/', cwd=out_of_date.path)
    git_commit(cwd=out_of_date.path)

    assert autoupdate(C.CONFIG_FILE, store, freeze=False, tags_only=False) == 1
    with open(C.CONFIG_FILE) as f:
        assert out_of_date.original_rev in f.read()
Example #36
0
def test_autoupdate_local_hooks_with_out_of_date_repo(
        out_of_date_repo, in_tmpdir, store,
):
    stale_config = make_config_from_repo(
        out_of_date_repo.path, rev=out_of_date_repo.original_rev, check=False,
    )
    local_config = sample_local_config()
    config = {'repos': [local_config, stale_config]}
    write_config('.', config)
    assert autoupdate(C.CONFIG_FILE, store, tags_only=False) == 0
    new_config_writen = read_config('.')
    assert len(new_config_writen['repos']) == 2
    assert new_config_writen['repos'][0] == local_config
Example #37
0
def test_autoupdate_up_to_date_repo(
        up_to_date_repo, in_tmpdir, mock_out_store_directory,
):
    # Write out the config
    config = make_config_from_repo(up_to_date_repo, check=False)
    write_config('.', config)

    before = open(C.CONFIG_FILE).read()
    assert '^$' not in before
    ret = autoupdate(Runner('.', C.CONFIG_FILE), tags_only=False)
    after = open(C.CONFIG_FILE).read()
    assert ret == 0
    assert before == after
Example #38
0
def test_autoupdate_meta_hooks(tmpdir, capsys):
    cfg = tmpdir.join(C.CONFIG_FILE)
    cfg.write(
        'repos:\n'
        '-   repo: meta\n'
        '    hooks:\n'
        '    -   id: check-useless-excludes\n', )
    ret = autoupdate(Runner(tmpdir.strpath, C.CONFIG_FILE), tags_only=True)
    assert ret == 0
    assert cfg.read() == ('repos:\n'
                          '-   repo: meta\n'
                          '    hooks:\n'
                          '    -   id: check-useless-excludes\n')
Example #39
0
def test_autoupdate_latest_no_config(out_of_date_repo, in_tmpdir, store):
    config = make_config_from_repo(
        out_of_date_repo.path, rev=out_of_date_repo.original_rev,
    )
    write_config('.', config)

    cmd_output('git', 'rm', '-r', ':/', cwd=out_of_date_repo.path)
    git_commit(cwd=out_of_date_repo.path)

    ret = autoupdate(C.CONFIG_FILE, store, tags_only=False)
    assert ret == 1
    with open(C.CONFIG_FILE) as f:
        assert out_of_date_repo.original_rev in f.read()
Example #40
0
def test_autoupdate_up_to_date_repo(up_to_date_repo, in_tmpdir, store):
    # Write out the config
    config = make_config_from_repo(up_to_date_repo, check=False)
    write_config('.', config)

    with open(C.CONFIG_FILE) as f:
        before = f.read()
    assert '^$' not in before
    ret = autoupdate(C.CONFIG_FILE, store, tags_only=False)
    with open(C.CONFIG_FILE) as f:
        after = f.read()
    assert ret == 0
    assert before == after
Example #41
0
def test_autoupdate_local_hooks_with_out_of_date_repo(
        out_of_date_repo, in_tmpdir, store,
):
    stale_config = make_config_from_repo(
        out_of_date_repo.path, rev=out_of_date_repo.original_rev, check=False,
    )
    local_config = sample_local_config()
    config = {'repos': [local_config, stale_config]}
    write_config('.', config)
    assert autoupdate(C.CONFIG_FILE, store, tags_only=False) == 0
    new_config_writen = read_config('.')
    assert len(new_config_writen['repos']) == 2
    assert new_config_writen['repos'][0] == local_config
Example #42
0
def test_autoupdate_up_to_date_repo(
        up_to_date_repo, in_tmpdir, mock_out_store_directory,
):
    # Write out the config
    config = make_config_from_repo(up_to_date_repo, check=False)
    write_config('.', config)

    before = open(C.CONFIG_FILE).read()
    assert '^$' not in before
    runner = Runner('.')
    ret = autoupdate(runner)
    after = open(C.CONFIG_FILE).read()
    assert ret == 0
    assert before == after
Example #43
0
def test_autoupdate_local_hooks_with_out_of_date_repo(
        out_of_date_repo, in_tmpdir, mock_out_store_directory,
):
    stale_config = make_config_from_repo(
        out_of_date_repo.path, sha=out_of_date_repo.original_sha, check=False,
    )
    local_config = config_with_local_hooks()
    config = {'repos': [local_config, stale_config]}
    write_config('.', config)
    runner = Runner('.', C.CONFIG_FILE)
    assert autoupdate(runner, tags_only=False) == 0
    new_config_writen = load_config(runner.config_file_path)
    assert len(new_config_writen['repos']) == 2
    assert new_config_writen['repos'][0] == local_config
Example #44
0
def test_autoupdate_local_hooks_with_out_of_date_repo(
        out_of_date_repo, in_tmpdir, mock_out_store_directory
):
    stale_config = make_config_from_repo(
        out_of_date_repo.path, sha=out_of_date_repo.original_sha, check=False,
    )
    local_config = config_with_local_hooks()
    config = [local_config, stale_config]
    write_config('.', config)
    runner = Runner('.')
    assert autoupdate(runner) == 0
    new_config_writen = load_config(runner.config_file_path)
    assert len(new_config_writen) == 2
    assert new_config_writen[0] == local_config
Example #45
0
def test_autoupdate_latest_no_config(out_of_date_repo, in_tmpdir, store):
    config = make_config_from_repo(
        out_of_date_repo.path,
        rev=out_of_date_repo.original_rev,
    )
    write_config('.', config)

    cmd_output('git', '-C', out_of_date_repo.path, 'rm', '-r', ':/')
    cmd_output('git', '-C', out_of_date_repo.path, 'commit', '-m', 'rm')

    ret = autoupdate(Runner('.', C.CONFIG_FILE), store, tags_only=False)
    assert ret == 1
    with open(C.CONFIG_FILE) as f:
        assert out_of_date_repo.original_rev in f.read()
def test_autoupdate_local_hooks_with_out_of_date_repo(
        out_of_date_repo, in_tmpdir, mock_out_store_directory,
):
    stale_config = make_config_from_repo(
        out_of_date_repo.path, sha=out_of_date_repo.original_sha, check=False,
    )
    local_config = config_with_local_hooks()
    config = {'repos': [local_config, stale_config]}
    write_config('.', config)
    runner = Runner('.', C.CONFIG_FILE)
    assert autoupdate(runner, tags_only=False) == 0
    new_config_writen = load_config(runner.config_file_path)
    assert len(new_config_writen['repos']) == 2
    assert new_config_writen['repos'][0] == local_config
Example #47
0
def test_does_not_reformat(tmpdir, out_of_date, store):
    fmt = ('repos:\n'
           '-   repo: {}\n'
           '    rev: {}  # definitely the version I want!\n'
           '    hooks:\n'
           '    -   id: foo\n'
           '        # These args are because reasons!\n'
           '        args: [foo, bar, baz]\n')
    cfg = tmpdir.join(C.CONFIG_FILE)
    cfg.write(fmt.format(out_of_date.path, out_of_date.original_rev))

    assert autoupdate(str(cfg), store, freeze=False, tags_only=False) == 0
    expected = fmt.format(out_of_date.path, out_of_date.head_rev)
    assert cfg.read() == expected
Example #48
0
def test_autoupdate_hook_disappearing_repo(
        hook_disappearing_repo, in_tmpdir, mock_out_store_directory,
):
    config = make_config_from_repo(
        hook_disappearing_repo.path,
        sha=hook_disappearing_repo.original_sha,
        hooks=[OrderedDict((('id', 'foo'),))],
        check=False,
    )
    write_config('.', config)

    before = open(C.CONFIG_FILE).read()
    ret = autoupdate(Runner('.', C.CONFIG_FILE), tags_only=False)
    after = open(C.CONFIG_FILE).read()
    assert ret == 1
    assert before == after
Example #49
0
def test_autoupdate_out_of_date_repo(out_of_date_repo, in_tmpdir, store):
    # Write out the config
    config = make_config_from_repo(
        out_of_date_repo.path, rev=out_of_date_repo.original_rev, check=False,
    )
    write_config('.', config)

    with open(C.CONFIG_FILE) as f:
        before = f.read()
    ret = autoupdate(C.CONFIG_FILE, store, tags_only=False)
    with open(C.CONFIG_FILE) as f:
        after = f.read()
    assert ret == 0
    assert before != after
    # Make sure we don't add defaults
    assert 'exclude' not in after
    assert out_of_date_repo.head_rev in after
Example #50
0
def test_autoupdate_out_of_date_repo_with_wrong_repo_name(
        out_of_date_repo, in_tmpdir, store,
):
    # Write out the config
    config = make_config_from_repo(
        out_of_date_repo.path, rev=out_of_date_repo.original_rev, check=False,
    )
    write_config('.', config)

    with open(C.CONFIG_FILE) as f:
        before = f.read()
    # It will not update it, because the name doesn't match
    ret = autoupdate(C.CONFIG_FILE, store, tags_only=False, repos=('dne',))
    with open(C.CONFIG_FILE) as f:
        after = f.read()
    assert ret == 0
    assert before == after
Example #51
0
def test_autoupdate_meta_hooks(tmpdir, capsys, store):
    cfg = tmpdir.join(C.CONFIG_FILE)
    cfg.write(
        'repos:\n'
        '-   repo: meta\n'
        '    hooks:\n'
        '    -   id: check-useless-excludes\n',
    )
    with tmpdir.as_cwd():
        ret = autoupdate(C.CONFIG_FILE, store, tags_only=True)
    assert ret == 0
    assert cfg.read() == (
        'repos:\n'
        '-   repo: meta\n'
        '    hooks:\n'
        '    -   id: check-useless-excludes\n'
    )
Example #52
0
def test_autoupdate_out_of_date_repo(
        out_of_date_repo, in_tmpdir, mock_out_store_directory,
):
    # Write out the config
    config = make_config_from_repo(
        out_of_date_repo.path, sha=out_of_date_repo.original_sha, check=False,
    )
    write_config('.', config)

    before = open(C.CONFIG_FILE).read()
    ret = autoupdate(Runner('.', C.CONFIG_FILE), tags_only=False)
    after = open(C.CONFIG_FILE).read()
    assert ret == 0
    assert before != after
    # Make sure we don't add defaults
    assert 'exclude' not in after
    assert out_of_date_repo.head_sha in after
Example #53
0
def test_autoupdate_hook_disappearing_repo(
        hook_disappearing_repo, in_tmpdir, store,
):
    config = make_config_from_repo(
        hook_disappearing_repo.path,
        rev=hook_disappearing_repo.original_rev,
        hooks=[{'id': 'foo'}],
        check=False,
    )
    write_config('.', config)

    with open(C.CONFIG_FILE) as f:
        before = f.read()
    ret = autoupdate(C.CONFIG_FILE, store, tags_only=False)
    with open(C.CONFIG_FILE) as f:
        after = f.read()
    assert ret == 1
    assert before == after
Example #54
0
def test_invalid_manifest_gcd(tempdir_factory, store, in_git_dir, cap_out):
    # clean up repos from old pre-commit versions
    path = make_repo(tempdir_factory, 'script_hooks_repo')
    write_config('.', make_config_from_repo(path))
    store.mark_config_used(C.CONFIG_FILE)

    # trigger a clone
    assert not autoupdate(C.CONFIG_FILE, store, tags_only=False)

    # we'll "break" the manifest to simulate an old version clone
    (_, _, path), = store.select_all_repos()
    os.remove(os.path.join(path, C.MANIFEST_FILE))

    assert _config_count(store) == 1
    assert _repo_count(store) == 1
    assert not gc(store)
    assert _config_count(store) == 1
    assert _repo_count(store) == 0
    assert cap_out.get().splitlines()[-1] == '1 repo(s) removed.'
Example #55
0
def test_gc(tempdir_factory, store, in_git_dir, cap_out):
    path = make_repo(tempdir_factory, 'script_hooks_repo')
    old_rev = git.head_rev(path)
    git_commit(cwd=path)

    write_config('.', make_config_from_repo(path, rev=old_rev))
    store.mark_config_used(C.CONFIG_FILE)

    # update will clone both the old and new repo, making the old one gc-able
    assert not autoupdate(C.CONFIG_FILE, store, tags_only=False)

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

    _remove_config_assert_cleared(store, cap_out)
Example #56
0
def test_autoupdate_out_of_date_repo_with_correct_repo_name(
        out_of_date_repo, in_tmpdir, store,
):
    stale_config = make_config_from_repo(
        out_of_date_repo.path, rev=out_of_date_repo.original_rev, check=False,
    )
    local_config = sample_local_config()
    config = {'repos': [stale_config, local_config]}
    # Write out the config
    write_config('.', config)

    with open(C.CONFIG_FILE) as f:
        before = f.read()
    repo_name = 'file://{}'.format(out_of_date_repo.path)
    ret = autoupdate(C.CONFIG_FILE, store, tags_only=False, repos=(repo_name,))
    with open(C.CONFIG_FILE) as f:
        after = f.read()
    assert ret == 0
    assert before != after
    assert out_of_date_repo.head_rev in after
    assert 'local' in after
Example #57
0
def main(argv=None):
    argv = argv if argv is not None else sys.argv[1:]
    argv = [five.to_text(arg) for arg in argv]
    parser = argparse.ArgumentParser()

    # http://stackoverflow.com/a/8521644/812183
    parser.add_argument(
        '-V', '--version',
        action='version',
        version='%(prog)s {}'.format(C.VERSION),
    )

    subparsers = parser.add_subparsers(dest='command')

    install_parser = subparsers.add_parser(
        'install', help='Install the pre-commit script.',
    )
    _add_color_option(install_parser)
    _add_config_option(install_parser)
    install_parser.add_argument(
        '-f', '--overwrite', action='store_true',
        help='Overwrite existing hooks / remove migration mode.',
    )
    install_parser.add_argument(
        '--install-hooks', action='store_true',
        help=(
            'Whether to install hook environments for all environments '
            'in the config file.'
        ),
    )
    _add_hook_type_option(install_parser)
    install_parser.add_argument(
        '--allow-missing-config', action='store_true', default=False,
        help=(
            'Whether to allow a missing `pre-commit` configuration file '
            'or exit with a failure code.'
        ),
    )

    install_hooks_parser = subparsers.add_parser(
        'install-hooks',
        help=(
            'Install hook environments for all environments in the config '
            'file.  You may find `pre-commit install --install-hooks` more '
            'useful.'
        ),
    )
    _add_color_option(install_hooks_parser)
    _add_config_option(install_hooks_parser)

    uninstall_parser = subparsers.add_parser(
        'uninstall', help='Uninstall the pre-commit script.',
    )
    _add_color_option(uninstall_parser)
    _add_config_option(uninstall_parser)
    _add_hook_type_option(uninstall_parser)

    clean_parser = subparsers.add_parser(
        'clean', help='Clean out pre-commit files.',
    )
    _add_color_option(clean_parser)
    _add_config_option(clean_parser)
    autoupdate_parser = subparsers.add_parser(
        'autoupdate',
        help="Auto-update pre-commit config to the latest repos' versions.",
    )
    _add_color_option(autoupdate_parser)
    _add_config_option(autoupdate_parser)
    autoupdate_parser.add_argument(
        '--tags-only', action='store_true', help='LEGACY: for compatibility',
    )
    autoupdate_parser.add_argument(
        '--bleeding-edge', action='store_true',
        help=(
            'Update to the bleeding edge of `master` instead of the latest '
            'tagged version (the default behavior).'
        ),
    )

    migrate_config_parser = subparsers.add_parser(
        'migrate-config',
        help='Migrate list configuration to new map configuration.',
    )
    _add_color_option(migrate_config_parser)
    _add_config_option(migrate_config_parser)

    run_parser = subparsers.add_parser('run', help='Run hooks.')
    _add_color_option(run_parser)
    _add_config_option(run_parser)
    run_parser.add_argument('hook', nargs='?', help='A single hook-id to run')
    run_parser.add_argument(
        '--verbose', '-v', action='store_true', default=False,
    )
    run_parser.add_argument(
        '--origin', '-o',
        help="The origin branch's commit_id when using `git push`.",
    )
    run_parser.add_argument(
        '--source', '-s',
        help="The remote branch's commit_id when using `git push`.",
    )
    run_parser.add_argument(
        '--commit-msg-filename',
        help='Filename to check when running during `commit-msg`',
    )
    run_parser.add_argument(
        '--hook-stage', choices=('commit', 'push', 'commit-msg'),
        default='commit',
        help='The stage during which the hook is fired e.g. commit or push.',
    )
    run_parser.add_argument(
        '--show-diff-on-failure', action='store_true',
        help='When hooks fail, run `git diff` directly afterward.',
    )
    run_mutex_group = run_parser.add_mutually_exclusive_group(required=False)
    run_mutex_group.add_argument(
        '--all-files', '-a', action='store_true', default=False,
        help='Run on all the files in the repo.',
    )
    run_mutex_group.add_argument(
        '--files', nargs='*', default=[],
        help='Specific filenames to run hooks on.',
    )

    sample_config_parser = subparsers.add_parser(
        'sample-config', help='Produce a sample {} file'.format(C.CONFIG_FILE),
    )
    _add_color_option(sample_config_parser)
    _add_config_option(sample_config_parser)

    help = subparsers.add_parser(
        'help', help='Show help for a specific command.',
    )
    help.add_argument('help_cmd', nargs='?', help='Command to show help for.')

    # Argparse doesn't really provide a way to use a `default` subparser
    if len(argv) == 0:
        argv = ['run']
    args = parser.parse_args(argv)
    if args.command == 'run':
        args.files = [
            os.path.relpath(os.path.abspath(filename), git.get_root())
            for filename in args.files
        ]

    if args.command == 'help':
        if args.help_cmd:
            parser.parse_args([args.help_cmd, '--help'])
        else:
            parser.parse_args(['--help'])

    with error_handler():
        add_logging_handler(args.color)
        runner = Runner.create(args.config)
        git.check_for_cygwin_mismatch()

        if args.command == 'install':
            return install(
                runner, overwrite=args.overwrite, hooks=args.install_hooks,
                hook_type=args.hook_type,
                skip_on_missing_conf=args.allow_missing_config,
            )
        elif args.command == 'install-hooks':
            return install_hooks(runner)
        elif args.command == 'uninstall':
            return uninstall(runner, hook_type=args.hook_type)
        elif args.command == 'clean':
            return clean(runner)
        elif args.command == 'autoupdate':
            if args.tags_only:
                logger.warning('--tags-only is the default')
            return autoupdate(runner, tags_only=not args.bleeding_edge)
        elif args.command == 'migrate-config':
            return migrate_config(runner)
        elif args.command == 'run':
            return run(runner, args)
        elif args.command == 'sample-config':
            return sample_config()
        else:
            raise NotImplementedError(
                'Command {} not implemented.'.format(args.command),
            )

        raise AssertionError(
            'Command {} failed to exit with a returncode'.format(args.command),
        )
Example #58
0
def main(argv=None):
    argv = argv if argv is not None else sys.argv[1:]
    argv = [five.to_text(arg) for arg in argv]
    parser = argparse.ArgumentParser()

    # https://stackoverflow.com/a/8521644/812183
    parser.add_argument(
        '-V', '--version',
        action='version',
        version='%(prog)s {}'.format(C.VERSION),
    )

    subparsers = parser.add_subparsers(dest='command')

    install_parser = subparsers.add_parser(
        'install', help='Install the pre-commit script.',
    )
    _add_color_option(install_parser)
    _add_config_option(install_parser)
    install_parser.add_argument(
        '-f', '--overwrite', action='store_true',
        help='Overwrite existing hooks / remove migration mode.',
    )
    install_parser.add_argument(
        '--install-hooks', action='store_true',
        help=(
            'Whether to install hook environments for all environments '
            'in the config file.'
        ),
    )
    _add_hook_type_option(install_parser)
    install_parser.add_argument(
        '--allow-missing-config', action='store_true', default=False,
        help=(
            'Whether to allow a missing `pre-commit` configuration file '
            'or exit with a failure code.'
        ),
    )

    install_hooks_parser = subparsers.add_parser(
        'install-hooks',
        help=(
            'Install hook environments for all environments in the config '
            'file.  You may find `pre-commit install --install-hooks` more '
            'useful.'
        ),
    )
    _add_color_option(install_hooks_parser)
    _add_config_option(install_hooks_parser)

    uninstall_parser = subparsers.add_parser(
        'uninstall', help='Uninstall the pre-commit script.',
    )
    _add_color_option(uninstall_parser)
    _add_config_option(uninstall_parser)
    _add_hook_type_option(uninstall_parser)

    clean_parser = subparsers.add_parser(
        'clean', help='Clean out pre-commit files.',
    )
    _add_color_option(clean_parser)
    _add_config_option(clean_parser)

    gc_parser = subparsers.add_parser('gc', help='Clean unused cached repos.')
    _add_color_option(gc_parser)
    _add_config_option(gc_parser)

    autoupdate_parser = subparsers.add_parser(
        'autoupdate',
        help="Auto-update pre-commit config to the latest repos' versions.",
    )
    _add_color_option(autoupdate_parser)
    _add_config_option(autoupdate_parser)
    autoupdate_parser.add_argument(
        '--tags-only', action='store_true', help='LEGACY: for compatibility',
    )
    autoupdate_parser.add_argument(
        '--bleeding-edge', action='store_true',
        help=(
            'Update to the bleeding edge of `master` instead of the latest '
            'tagged version (the default behavior).'
        ),
    )
    autoupdate_parser.add_argument(
        '--repo', dest='repos', action='append', metavar='REPO',
        help='Only update this repository -- may be specified multiple times.',
    )

    migrate_config_parser = subparsers.add_parser(
        'migrate-config',
        help='Migrate list configuration to new map configuration.',
    )
    _add_color_option(migrate_config_parser)
    _add_config_option(migrate_config_parser)

    run_parser = subparsers.add_parser('run', help='Run hooks.')
    _add_color_option(run_parser)
    _add_config_option(run_parser)
    _add_run_options(run_parser)

    sample_config_parser = subparsers.add_parser(
        'sample-config', help='Produce a sample {} file'.format(C.CONFIG_FILE),
    )
    _add_color_option(sample_config_parser)
    _add_config_option(sample_config_parser)

    try_repo_parser = subparsers.add_parser(
        'try-repo',
        help='Try the hooks in a repository, useful for developing new hooks.',
    )
    _add_color_option(try_repo_parser)
    _add_config_option(try_repo_parser)
    try_repo_parser.add_argument(
        'repo', help='Repository to source hooks from.',
    )
    try_repo_parser.add_argument(
        '--ref', '--rev',
        help=(
            'Manually select a rev to run against, otherwise the `HEAD` '
            'revision will be used.'
        ),
    )
    _add_run_options(try_repo_parser)

    help = subparsers.add_parser(
        'help', help='Show help for a specific command.',
    )
    help.add_argument('help_cmd', nargs='?', help='Command to show help for.')

    # argparse doesn't really provide a way to use a `default` subparser
    if len(argv) == 0:
        argv = ['run']
    args = parser.parse_args(argv)

    if args.command == 'help' and args.help_cmd:
        parser.parse_args([args.help_cmd, '--help'])
    elif args.command == 'help':
        parser.parse_args(['--help'])

    with error_handler(), logging_handler(args.color):
        if args.command not in {'clean', 'gc', 'sample-config'}:
            _adjust_args_and_chdir(args)

        git.check_for_cygwin_mismatch()

        store = Store()
        store.mark_config_used(args.config)

        if args.command == 'install':
            return install(
                args.config, store,
                overwrite=args.overwrite, hooks=args.install_hooks,
                hook_type=args.hook_type,
                skip_on_missing_conf=args.allow_missing_config,
            )
        elif args.command == 'install-hooks':
            return install_hooks(args.config, store)
        elif args.command == 'uninstall':
            return uninstall(hook_type=args.hook_type)
        elif args.command == 'clean':
            return clean(store)
        elif args.command == 'gc':
            return gc(store)
        elif args.command == 'autoupdate':
            if args.tags_only:
                logger.warning('--tags-only is the default')
            return autoupdate(
                args.config, store,
                tags_only=not args.bleeding_edge,
                repos=args.repos,
            )
        elif args.command == 'migrate-config':
            return migrate_config(args.config)
        elif args.command == 'run':
            return run(args.config, store, args)
        elif args.command == 'sample-config':
            return sample_config()
        elif args.command == 'try-repo':
            return try_repo(args)
        else:
            raise NotImplementedError(
                'Command {} not implemented.'.format(args.command),
            )

        raise AssertionError(
            'Command {} failed to exit with a returncode'.format(args.command),
        )
Example #59
0
def main(argv=None):
    argv = argv if argv is not None else sys.argv[1:]
    argv = [five.to_text(arg) for arg in argv]
    parser = argparse.ArgumentParser()

    # http://stackoverflow.com/a/8521644/812183
    parser.add_argument(
        '-V', '--version',
        action='version',
        version='%(prog)s {}'.format(
            pkg_resources.get_distribution('pre-commit').version
        )
    )

    subparsers = parser.add_subparsers(dest='command')

    install_parser = subparsers.add_parser(
        'install', help='Install the pre-commit script.',
    )
    _add_color_option(install_parser)
    _add_config_option(install_parser)
    install_parser.add_argument(
        '-f', '--overwrite', action='store_true',
        help='Overwrite existing hooks / remove migration mode.',
    )
    install_parser.add_argument(
        '--install-hooks', action='store_true',
        help=(
            'Whether to install hook environments for all environments '
            'in the config file.'
        ),
    )
    install_parser.add_argument(
        '-t', '--hook-type', choices=('pre-commit', 'pre-push'),
        default='pre-commit',
    )

    install_hooks_parser = subparsers.add_parser(
        'install-hooks',
        help=(
            'Install hook environemnts for all environemnts in the config '
            'file.  You may find `pre-commit install --install-hooks` more '
            'useful.'
        ),
    )
    _add_color_option(install_hooks_parser)
    _add_config_option(install_hooks_parser)

    uninstall_parser = subparsers.add_parser(
        'uninstall', help='Uninstall the pre-commit script.',
    )
    _add_color_option(uninstall_parser)
    _add_config_option(uninstall_parser)
    uninstall_parser.add_argument(
        '-t', '--hook-type', choices=('pre-commit', 'pre-push'),
        default='pre-commit',
    )

    clean_parser = subparsers.add_parser(
        'clean', help='Clean out pre-commit files.',
    )
    _add_color_option(clean_parser)
    _add_config_option(clean_parser)
    autoupdate_parser = subparsers.add_parser(
        'autoupdate',
        help="Auto-update pre-commit config to the latest repos' versions.",
    )
    _add_color_option(autoupdate_parser)
    _add_config_option(autoupdate_parser)

    run_parser = subparsers.add_parser('run', help='Run hooks.')
    _add_color_option(run_parser)
    _add_config_option(run_parser)
    run_parser.add_argument('hook', nargs='?', help='A single hook-id to run')
    run_parser.add_argument(
        '--no-stash', default=False, action='store_true',
        help='Use this option to prevent auto stashing of unstaged files.',
    )
    run_parser.add_argument(
        '--verbose', '-v', action='store_true', default=False,
    )
    run_parser.add_argument(
        '--origin', '-o',
        help="The origin branch's commit_id when using `git push`.",
    )
    run_parser.add_argument(
        '--source', '-s',
        help="The remote branch's commit_id when using `git push`.",
    )
    run_parser.add_argument(
        '--allow-unstaged-config', default=False, action='store_true',
        help=(
            'Allow an unstaged config to be present.  Note that this will '
            'be stashed before parsing unless --no-stash is specified.'
        ),
    )
    run_parser.add_argument(
        '--hook-stage', choices=('commit', 'push'), default='commit',
        help='The stage during which the hook is fired e.g. commit or push.',
    )
    run_mutex_group = run_parser.add_mutually_exclusive_group(required=False)
    run_mutex_group.add_argument(
        '--all-files', '-a', action='store_true', default=False,
        help='Run on all the files in the repo.  Implies --no-stash.',
    )
    run_mutex_group.add_argument(
        '--files', nargs='*', default=[],
        help='Specific filenames to run hooks on.',
    )

    help = subparsers.add_parser(
        'help', help='Show help for a specific command.',
    )
    help.add_argument('help_cmd', nargs='?', help='Command to show help for.')

    # Argparse doesn't really provide a way to use a `default` subparser
    if len(argv) == 0:
        argv = ['run']
    args = parser.parse_args(argv)
    if args.command == 'run':
        args.files = [
            os.path.relpath(os.path.abspath(filename), git.get_root())
            for filename in args.files
        ]

    if args.command == 'help':
        if args.help_cmd:
            parser.parse_args([args.help_cmd, '--help'])
        else:
            parser.parse_args(['--help'])

    with error_handler():
        add_logging_handler(args.color)
        runner = Runner.create(args.config)
        git.check_for_cygwin_mismatch()

        if args.command == 'install':
            return install(
                runner, overwrite=args.overwrite, hooks=args.install_hooks,
                hook_type=args.hook_type,
            )
        elif args.command == 'install-hooks':
            return install_hooks(runner)
        elif args.command == 'uninstall':
            return uninstall(runner, hook_type=args.hook_type)
        elif args.command == 'clean':
            return clean(runner)
        elif args.command == 'autoupdate':
            return autoupdate(runner)
        elif args.command == 'run':
            return run(runner, args)
        else:
            raise NotImplementedError(
                'Command {} not implemented.'.format(args.command)
            )

        raise AssertionError(
            'Command {} failed to exit with a returncode'.format(args.command)
        )
Example #60
0
def main(argv=None):
    argv = argv if argv is not None else sys.argv[1:]
    parser = argparse.ArgumentParser()

    # http://stackoverflow.com/a/8521644/812183
    parser.add_argument(
        '-V', '--version',
        action='version',
        version='%(prog)s {0}'.format(
            pkg_resources.get_distribution('pre-commit').version
        )
    )

    subparsers = parser.add_subparsers(dest='command')

    install_parser = subparsers.add_parser(
        'install', help='Install the pre-commit script.',
    )
    install_parser.add_argument(
        '-f', '--overwrite', action='store_true',
        help='Overwrite existing hooks / remove migration mode.',
    )
    install_parser.add_argument(
        '--install-hooks', action='store_true',
        help=(
            'Whether to install hook environments for all environments '
            'in the config file.'
        ),
    )

    subparsers.add_parser('uninstall', help='Uninstall the pre-commit script.')

    subparsers.add_parser('clean', help='Clean out pre-commit files.')

    subparsers.add_parser(
        'autoupdate',
        help="Auto-update pre-commit config to the latest repos' versions.",
    )

    run_parser = subparsers.add_parser('run', help='Run hooks.')
    run_parser.add_argument('hook', nargs='?', help='A single hook-id to run')
    run_parser.add_argument(
        '--color', default='auto', type=color.use_color,
        help='Whether to use color in output.  Defaults to `auto`',
    )
    run_parser.add_argument(
        '--no-stash', default=False, action='store_true',
        help='Use this option to prevent auto stashing of unstaged files.',
    )
    run_parser.add_argument(
        '--verbose', '-v', action='store_true', default=False,
    )
    run_mutex_group = run_parser.add_mutually_exclusive_group(required=False)
    run_mutex_group.add_argument(
        '--all-files', '-a', action='store_true', default=False,
        help='Run on all the files in the repo.  Implies --no-stash.',
    )
    run_mutex_group.add_argument(
        '--files', nargs='*', help='Specific filenames to run hooks on.',
    )

    help = subparsers.add_parser(
        'help', help='Show help for a specific command.'
    )
    help.add_argument('help_cmd', nargs='?', help='Command to show help for.')

    # Argparse doesn't really provide a way to use a `default` subparser
    if len(argv) == 0:
        argv = ['run']
    args = parser.parse_args(argv)

    if args.command == 'help':
        if args.help_cmd:
            parser.parse_args([args.help_cmd, '--help'])
        else:
            parser.parse_args(['--help'])

    with error_handler():
        runner = Runner.create()

        if args.command == 'install':
            return install(
                runner, overwrite=args.overwrite, hooks=args.install_hooks,
            )
        elif args.command == 'uninstall':
            return uninstall(runner)
        elif args.command == 'clean':
            return clean(runner)
        elif args.command == 'autoupdate':
            return autoupdate(runner)
        elif args.command == 'run':
            return run(runner, args)
        else:
            raise NotImplementedError(
                'Command {0} not implemented.'.format(args.command)
            )

        raise AssertionError(
            'Command {0} failed to exit with a returncode'.format(args.command)
        )