예제 #1
0
def test_local_hooks_alt_config(tempdir_factory, mock_out_store_directory):
    config = OrderedDict(
        (('repo', 'local'),
         ('hooks', (OrderedDict((
             ('id', 'arg-per-line'),
             ('name', 'Args per line hook'),
             ('entry', 'bin/hook.sh'),
             ('language', 'script'),
             ('files', ''),
             ('args', ['hello', 'world']),
         )),
                    OrderedDict((
                        ('id', 'ugly-format-json'),
                        ('name', 'Ugly format json'),
                        ('entry', 'ugly-format-json'),
                        ('language', 'python'),
                        ('files', ''),
                    )),
                    OrderedDict((
                        ('id', 'do_not_commit'),
                        ('name', 'Block if "DO NOT COMMIT" is found'),
                        ('entry', 'DO NOT COMMIT'),
                        ('language', 'pcre'),
                        ('files', '^(.*)$'),
                    ))))))
    git_path = git_dir(tempdir_factory)
    alt_config_file = 'alternate_config.yaml'
    add_config_to_repo(git_path, config, config_file=alt_config_file)
    runner = Runner(git_path, alt_config_file)
    assert len(runner.repositories) == 1
    assert len(runner.repositories[0].hooks) == 3
예제 #2
0
def test_local_hook_passes(repo_with_passing_hook, mock_out_store_directory):
    config = OrderedDict((
        ('repo', 'local'),
        ('hooks', (OrderedDict((
            ('id', 'flake8'),
            ('name', 'flake8'),
            ('entry', 'python -m flake8.__main__'),
            ('language', 'system'),
            ('files', r'\.py$'),
        )), OrderedDict((
            ('id', 'do_not_commit'),
            ('name', 'Block if "DO NOT COMMIT" is found'),
            ('entry', 'DO NOT COMMIT'),
            ('language', 'pcre'),
            ('files', '^(.*)$'),
        ))))
    ))
    add_config_to_repo(repo_with_passing_hook, config)

    with io.open('dummy.py', 'w') as staged_file:
        staged_file.write('"""TODO: something"""\n')
    cmd_output('git', 'add', 'dummy.py')

    _test_run(
        repo_with_passing_hook,
        options={},
        expected_outputs=[b''],
        expected_ret=0,
        stage=False
    )
예제 #3
0
def test_local_hook_fails(
    cap_out,
    repo_with_passing_hook,
    mock_out_store_directory,
):
    config = OrderedDict((('repo', 'local'), ('hooks', [
        OrderedDict((
            ('id', 'no-todo'),
            ('name', 'No TODO'),
            ('entry', 'sh -c "! grep -iI todo $@" --'),
            ('language', 'system'),
            ('files', ''),
        ))
    ])))
    add_config_to_repo(repo_with_passing_hook, config)

    with io.open('dummy.py', 'w') as staged_file:
        staged_file.write('"""TODO: something"""\n')
    cmd_output('git', 'add', 'dummy.py')

    _test_run(
        cap_out,
        repo_with_passing_hook,
        opts={},
        expected_outputs=[b''],
        expected_ret=1,
        stage=False,
    )
예제 #4
0
def test_local_hook_for_stages(
    cap_out,
    repo_with_passing_hook,
    mock_out_store_directory,
    stage_for_first_hook,
    stage_for_second_hook,
    hook_stage,
    expected_output,
):
    config = OrderedDict(
        (('repo', 'local'),
         ('hooks', (OrderedDict(
             (('id', 'flake8'), ('name', 'hook 1'),
              ('entry', 'python -m flake8.__main__'), ('language', 'system'),
              ('files', r'\.py$'), ('stages', stage_for_first_hook))),
                    OrderedDict(
                        (('id', 'do_not_commit'), ('name', 'hook 2'),
                         ('entry', 'DO NOT COMMIT'), ('language', 'pcre'),
                         ('files', '^(.*)$'), ('stages',
                                               stage_for_second_hook)))))))
    add_config_to_repo(repo_with_passing_hook, config)

    with io.open('dummy.py', 'w') as staged_file:
        staged_file.write('"""TODO: something"""\n')
    cmd_output('git', 'add', 'dummy.py')

    _test_run(cap_out,
              repo_with_passing_hook, {'hook_stage': hook_stage},
              expected_outputs=expected_output,
              expected_ret=0,
              stage=False)
예제 #5
0
def config_with_local_hooks():
    return OrderedDict((('repo', 'local'), ('hooks', [
        OrderedDict((
            ('id', 'do_not_commit'),
            ('name', 'Block if "DO NOT COMMIT" is found'),
            ('entry', 'DO NOT COMMIT'),
            ('language', 'pcre'),
            ('files', '^(.*)$'),
        ))
    ])))
예제 #6
0
def _update_repository(repo_config, runner):
    """Updates a repository to the tip of `master`.  If the repository cannot
    be updated because a hook that is configured does not exist in `master`,
    this raises a RepositoryCannotBeUpdatedError

    Args:
        repo_config - A config for a repository
    """
    repo = Repository.create(repo_config, runner.store)

    with cwd(repo.repo_path_getter.repo_path):
        cmd_output('git', 'fetch')
        head_sha = cmd_output('git', 'rev-parse', 'origin/master')[1].strip()

    # Don't bother trying to update if our sha is the same
    if head_sha == repo_config['sha']:
        return repo_config

    # Construct a new config with the head sha
    new_config = OrderedDict(repo_config)
    new_config['sha'] = head_sha
    new_repo = Repository.create(new_config, runner.store)

    # See if any of our hooks were deleted with the new commits
    hooks = set(hook_id for hook_id, _ in repo.hooks)
    hooks_missing = hooks - (hooks & set(new_repo.manifest.hooks.keys()))
    if hooks_missing:
        raise RepositoryCannotBeUpdatedError(
            'Cannot update because the tip of master is missing these hooks:\n'
            '{0}'.format(', '.join(sorted(hooks_missing))))

    return new_config
예제 #7
0
def make_config_from_repo(repo_path, sha=None, hooks=None, check=True):
    manifest = load_manifest(os.path.join(repo_path, C.MANIFEST_FILE))
    config = OrderedDict((
        ('repo', repo_path),
        ('sha', sha or get_head_sha(repo_path)),
        (
            'hooks',
            hooks or [OrderedDict((('id', hook['id']),)) for hook in manifest],
        ),
    ))

    if check:
        wrapped_config = apply_defaults([config], CONFIG_JSON_SCHEMA)
        validate_config_extra(wrapped_config)
        return wrapped_config[0]
    else:
        return config
예제 #8
0
def test_hook_disppearing_repo_raises(hook_disappearing_repo,
                                      runner_with_mocked_store):
    config = make_config_from_repo(
        hook_disappearing_repo.path,
        sha=hook_disappearing_repo.original_sha,
        hooks=[OrderedDict((('id', 'foo'), ))],
    )
    with pytest.raises(RepositoryCannotBeUpdatedError):
        _update_repository(config, runner_with_mocked_store)
예제 #9
0
def test_local_hooks(tempdir_factory, mock_out_store_directory):
    config = OrderedDict(
        (('repo', 'local'),
         ('hooks', (OrderedDict((
             ('id', 'arg-per-line'),
             ('name', 'Args per line hook'),
             ('entry', 'bin/hook.sh'),
             ('language', 'script'),
             ('files', ''),
             ('args', ['hello', 'world']),
         )),
                    OrderedDict((
                        ('id', 'do_not_commit'),
                        ('name', 'Block if "DO NOT COMMIT" is found'),
                        ('entry', 'DO NOT COMMIT'),
                        ('language', 'pcre'),
                        ('files', '^(.*)$'),
                    ))))))
    git_path = git_dir(tempdir_factory)
    add_config_to_repo(git_path, config)
    runner = Runner(git_path, C.CONFIG_FILE)
    assert len(runner.repositories) == 1
    assert len(runner.repositories[0].hooks) == 2
예제 #10
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()
    runner = Runner('.')
    ret = autoupdate(runner)
    after = open(C.CONFIG_FILE).read()
    assert ret == 1
    assert before == after