Beispiel #1
0
def install(
    config_file,
    store,
    overwrite=False,
    hooks=False,
    hook_type='pre-commit',
    skip_on_missing_config=False,
    git_dir=None,
):
    """Install the pre-commit hooks."""
    if cmd_output('git', 'config', 'core.hooksPath', retcode=None)[1].strip():
        logger.error(
            'Cowardly refusing to install hooks with `core.hooksPath` set.\n'
            'hint: `git config --unset-all core.hooksPath`', )
        return 1

    hook_path, legacy_path = _hook_paths(hook_type, git_dir=git_dir)

    mkdirp(os.path.dirname(hook_path))

    # If we have an existing hook, move it to pre-commit.legacy
    if os.path.lexists(hook_path) and not is_our_script(hook_path):
        shutil.move(hook_path, legacy_path)

    # If we specify overwrite, we simply delete the legacy file
    if overwrite and os.path.exists(legacy_path):
        os.remove(legacy_path)
    elif os.path.exists(legacy_path):
        output.write_line(
            'Running in migration mode with existing hooks at {}\n'
            'Use -f to use only pre-commit.'.format(legacy_path), )

    params = {
        'CONFIG': config_file,
        'HOOK_TYPE': hook_type,
        'INSTALL_PYTHON': sys.executable,
        'SKIP_ON_MISSING_CONFIG': skip_on_missing_config,
    }

    with io.open(hook_path, 'w') as hook_file:
        contents = resource_text('hook-tmpl')
        before, rest = contents.split(TEMPLATE_START)
        to_template, after = rest.split(TEMPLATE_END)

        before = before.replace('#!/usr/bin/env python3', shebang())

        hook_file.write(before + TEMPLATE_START)
        for line in to_template.splitlines():
            var = line.split()[0]
            hook_file.write('{} = {!r}\n'.format(var, params[var]))
        hook_file.write(TEMPLATE_END + after)
    make_executable(hook_path)

    output.write_line('pre-commit installed at {}'.format(hook_path))

    # If they requested we install all of the hooks, do so.
    if hooks:
        install_hooks(config_file, store)

    return 0
def install(
        config_file, store,
        overwrite=False, hooks=False, hook_type='pre-commit',
        skip_on_missing_conf=False,
):
    """Install the pre-commit hooks."""
    if cmd_output('git', 'config', 'core.hooksPath', retcode=None)[1].strip():
        logger.error(
            'Cowardly refusing to install hooks with `core.hooksPath` set.\n'
            'hint: `git config --unset-all core.hooksPath`',
        )
        return 1

    hook_path, legacy_path = _hook_paths(hook_type)

    mkdirp(os.path.dirname(hook_path))

    # If we have an existing hook, move it to pre-commit.legacy
    if os.path.lexists(hook_path) and not is_our_script(hook_path):
        shutil.move(hook_path, legacy_path)

    # If we specify overwrite, we simply delete the legacy file
    if overwrite and os.path.exists(legacy_path):
        os.remove(legacy_path)
    elif os.path.exists(legacy_path):
        output.write_line(
            'Running in migration mode with existing hooks at {}\n'
            'Use -f to use only pre-commit.'.format(legacy_path),
        )

    params = {
        'CONFIG': config_file,
        'HOOK_TYPE': hook_type,
        'INSTALL_PYTHON': sys.executable,
        'SKIP_ON_MISSING_CONFIG': skip_on_missing_conf,
    }

    with io.open(hook_path, 'w') as hook_file:
        contents = resource_text('hook-tmpl')
        before, rest = contents.split(TEMPLATE_START)
        to_template, after = rest.split(TEMPLATE_END)

        before = before.replace('#!/usr/bin/env python3', shebang())

        hook_file.write(before + TEMPLATE_START)
        for line in to_template.splitlines():
            var = line.split()[0]
            hook_file.write('{} = {!r}\n'.format(var, params[var]))
        hook_file.write(TEMPLATE_END + after)
    make_executable(hook_path)

    output.write_line('pre-commit installed at {}'.format(hook_path))

    # If they requested we install all of the hooks, do so.
    if hooks:
        install_hooks(config_file, store)

    return 0
Beispiel #3
0
def _install_hook_script(
        config_file: str,
        hook_type: str,
        overwrite: bool = False,
        skip_on_missing_config: bool = False,
        git_dir: Optional[str] = None,
) -> None:
    hook_path, legacy_path = _hook_paths(hook_type, git_dir=git_dir)

    os.makedirs(os.path.dirname(hook_path), exist_ok=True)

    # If we have an existing hook, move it to pre-commit.legacy
    if os.path.lexists(hook_path) and not is_our_script(hook_path):
        shutil.move(hook_path, legacy_path)

    # If we specify overwrite, we simply delete the legacy file
    if overwrite and os.path.exists(legacy_path):
        os.remove(legacy_path)
    elif os.path.exists(legacy_path):
        output.write_line(
            f'Running in migration mode with existing hooks at {legacy_path}\n'
            f'Use -f to use only pre-commit.',
        )

    args = ['hook-impl', f'--config={config_file}', f'--hook-type={hook_type}']
    if skip_on_missing_config:
        args.append('--skip-on-missing-config')

    with open(hook_path, 'w') as hook_file:
        contents = resource_text('hook-tmpl')
        before, rest = contents.split(TEMPLATE_START)
        _, after = rest.split(TEMPLATE_END)

        # on windows always use `/bin/sh` since `bash` might not be on PATH
        # though we use bash-specific features `sh` on windows is actually
        # bash in "POSIXLY_CORRECT" mode which still supports the features we
        # use: subshells / arrays
        if sys.platform == 'win32':  # pragma: win32 cover
            hook_file.write('#!/bin/sh\n')

        hook_file.write(before + TEMPLATE_START)
        hook_file.write(f'INSTALL_PYTHON={shlex.quote(sys.executable)}\n')
        # TODO: python3.8+: shlex.join
        args_s = ' '.join(shlex.quote(part) for part in args)
        hook_file.write(f'ARGS=({args_s})\n')
        hook_file.write(TEMPLATE_END + after)
    make_executable(hook_path)

    output.write_line(f'pre-commit installed at {hook_path}')
Beispiel #4
0
        def make_local_strategy(directory):
            for resource in self.LOCAL_RESOURCES:
                contents = resource_text('empty_template_{}'.format(resource))
                with io.open(os.path.join(directory, resource), 'w') as f:
                    f.write(contents)

            env = git.no_git_env()

            # initialize the git repository so it looks more like cloned repos
            def _git_cmd(*args):
                cmd_output_b('git', *args, cwd=directory, env=env)

            git.init_repo(directory, '<<unknown>>')
            _git_cmd('add', '.')
            git.commit(repo=directory)
Beispiel #5
0
        def make_local_strategy(directory: str) -> None:
            for resource in self.LOCAL_RESOURCES:
                contents = resource_text(f"empty_template_{resource}")
                with open(os.path.join(directory, resource), "w") as f:
                    f.write(contents)

            env = git.no_git_env()

            # initialize the git repository so it looks more like cloned repos
            def _git_cmd(*args: str) -> None:
                cmd_output_b("git", *args, cwd=directory, env=env)

            git.init_repo(directory, "<<unknown>>")
            _git_cmd("add", ".")
            git.commit(repo=directory)
Beispiel #6
0
        def make_local_strategy(directory):
            for resource in self.LOCAL_RESOURCES:
                contents = resource_text('empty_template_{}'.format(resource))
                with io.open(os.path.join(directory, resource), 'w') as f:
                    f.write(contents)

            env = git.no_git_env()

            # initialize the git repository so it looks more like cloned repos
            def _git_cmd(*args):
                cmd_output('git', *args, cwd=directory, env=env)

            _git_cmd('init', '.')
            _git_cmd('config', 'remote.origin.url', '<<unknown>>')
            _git_cmd('add', '.')
            git.commit(repo=directory)
def _install_hook_script(
    config_file: str,
    hook_type: str,
    overwrite: bool = False,
    skip_on_missing_config: bool = False,
    git_dir: Optional[str] = None,
) -> None:
    hook_path, legacy_path = _hook_paths(hook_type, git_dir=git_dir)

    os.makedirs(os.path.dirname(hook_path), exist_ok=True)

    # If we have an existing hook, move it to pre-commit.legacy
    if os.path.lexists(hook_path) and not is_our_script(hook_path):
        shutil.move(hook_path, legacy_path)

    # If we specify overwrite, we simply delete the legacy file
    if overwrite and os.path.exists(legacy_path):
        os.remove(legacy_path)
    elif os.path.exists(legacy_path):
        output.write_line(
            f'Running in migration mode with existing hooks at {legacy_path}\n'
            f'Use -f to use only pre-commit.', )

    params = {
        'CONFIG': config_file,
        'HOOK_TYPE': hook_type,
        'INSTALL_PYTHON': sys.executable,
        'SKIP_ON_MISSING_CONFIG': skip_on_missing_config,
    }

    with open(hook_path, 'w') as hook_file:
        contents = resource_text('hook-tmpl')
        before, rest = contents.split(TEMPLATE_START)
        to_template, after = rest.split(TEMPLATE_END)

        before = before.replace('#!/usr/bin/env python3', shebang())

        hook_file.write(before + TEMPLATE_START)
        for line in to_template.splitlines():
            var = line.split()[0]
            hook_file.write(f'{var} = {params[var]!r}\n')
        hook_file.write(TEMPLATE_END + after)
    make_executable(hook_path)

    output.write_line(f'pre-commit installed at {hook_path}')
def _install_hook_script(
    config_file: str,
    hook_type: str,
    overwrite: bool = False,
    skip_on_missing_config: bool = False,
    git_dir: Optional[str] = None,
) -> None:
    hook_path, legacy_path = _hook_paths(hook_type, git_dir=git_dir)

    os.makedirs(os.path.dirname(hook_path), exist_ok=True)

    # If we have an existing hook, move it to pre-commit.legacy
    if os.path.lexists(hook_path) and not is_our_script(hook_path):
        shutil.move(hook_path, legacy_path)

    # If we specify overwrite, we simply delete the legacy file
    if overwrite and os.path.exists(legacy_path):
        os.remove(legacy_path)
    elif os.path.exists(legacy_path):
        output.write_line(
            f"Running in migration mode with existing hooks at {legacy_path}\n"
            f"Use -f to use only pre-commit.", )

    args = ["hook-impl", f"--config={config_file}", f"--hook-type={hook_type}"]
    if skip_on_missing_config:
        args.append("--skip-on-missing-config")
    params = {"INSTALL_PYTHON": sys.executable, "ARGS": args}

    with open(hook_path, "w") as hook_file:
        contents = resource_text("hook-tmpl")
        before, rest = contents.split(TEMPLATE_START)
        to_template, after = rest.split(TEMPLATE_END)

        before = before.replace("#!/usr/bin/env python3", shebang())

        hook_file.write(before + TEMPLATE_START)
        for line in to_template.splitlines():
            var = line.split()[0]
            hook_file.write(f"{var} = {params[var]!r}\n")
        hook_file.write(TEMPLATE_END + after)
    make_executable(hook_path)

    output.write_line(f"pre-commit installed at {hook_path}")
Beispiel #9
0
        def make_local_strategy(directory):
            for resource in self.LOCAL_RESOURCES:
                contents = resource_text('empty_template_{}'.format(resource))
                with io.open(os.path.join(directory, resource), 'w') as f:
                    f.write(contents)

            env = no_git_env()
            name, email = 'pre-commit', '*****@*****.**'
            env['GIT_AUTHOR_NAME'] = env['GIT_COMMITTER_NAME'] = name
            env['GIT_AUTHOR_EMAIL'] = env['GIT_COMMITTER_EMAIL'] = email

            # initialize the git repository so it looks more like cloned repos
            def _git_cmd(*args):
                cmd_output('git', *args, cwd=directory, env=env)

            _git_cmd('init', '.')
            _git_cmd('config', 'remote.origin.url', '<<unknown>>')
            _git_cmd('add', '.')
            _git_cmd('commit', '--no-edit', '--no-gpg-sign', '-n', '-minit')
Beispiel #10
0
        def make_local_strategy(directory: str) -> None:
            for resource in self.LOCAL_RESOURCES:
                resource_dirname, resource_basename = os.path.split(resource)
                contents = resource_text(f'empty_template_{resource_basename}')
                target_dir = os.path.join(directory, resource_dirname)
                target_file = os.path.join(target_dir, resource_basename)
                os.makedirs(target_dir, exist_ok=True)
                with open(target_file, 'w') as f:
                    f.write(contents)

            env = git.no_git_env()

            # initialize the git repository so it looks more like cloned repos
            def _git_cmd(*args: str) -> None:
                cmd_output_b('git', *args, cwd=directory, env=env)

            git.init_repo(directory, '<<unknown>>')
            _git_cmd('add', '.')
            git.commit(repo=directory)
def _install_hook_script(
        config_file: str,
        hook_type: str,
        overwrite: bool = False,
        skip_on_missing_config: bool = False,
        git_dir: Optional[str] = None,
) -> None:
    hook_path, legacy_path = _hook_paths(hook_type, git_dir=git_dir)

    os.makedirs(os.path.dirname(hook_path), exist_ok=True)

    # If we have an existing hook, move it to pre-commit.legacy
    if os.path.lexists(hook_path) and not is_our_script(hook_path):
        shutil.move(hook_path, legacy_path)

    # If we specify overwrite, we simply delete the legacy file
    if overwrite and os.path.exists(legacy_path):
        os.remove(legacy_path)
    elif os.path.exists(legacy_path):
        output.write_line(
            f'Running in migration mode with existing hooks at {legacy_path}\n'
            f'Use -f to use only pre-commit.',
        )

    args = ['hook-impl', f'--config={config_file}', f'--hook-type={hook_type}']
    if skip_on_missing_config:
        args.append('--skip-on-missing-config')

    with open(hook_path, 'w') as hook_file:
        contents = resource_text('hook-tmpl')
        before, rest = contents.split(TEMPLATE_START)
        _, after = rest.split(TEMPLATE_END)

        hook_file.write(before + TEMPLATE_START)
        hook_file.write(f'INSTALL_PYTHON={shlex.quote(sys.executable)}\n')
        # TODO: python3.8+: shlex.join
        args_s = ' '.join(shlex.quote(part) for part in args)
        hook_file.write(f'ARGS=({args_s})\n')
        hook_file.write(TEMPLATE_END + after)
    make_executable(hook_path)

    output.write_line(f'pre-commit installed at {hook_path}')
def test_replace_old_commit_script(tempdir_factory, store):
    path = make_consuming_repo(tempdir_factory, 'script_hooks_repo')
    with cwd(path):
        # Install a script that looks like our old script
        pre_commit_contents = resource_text('hook-tmpl')
        new_contents = pre_commit_contents.replace(
            CURRENT_HASH.decode(), PRIOR_HASHES[-1].decode(),
        )

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

        # Install normally
        assert install(C.CONFIG_FILE, store, hook_types=['pre-commit']) == 0

        ret, output = _get_commit_output(tempdir_factory)
        assert ret == 0
        NORMAL_PRE_COMMIT_RUN.assert_matches(output)
def test_replace_old_commit_script(tempdir_factory, store):
    path = make_consuming_repo(tempdir_factory, 'script_hooks_repo')
    with cwd(path):
        # 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(C.CONFIG_FILE, store) == 0

        ret, output = _get_commit_output(tempdir_factory)
        assert ret == 0
        assert NORMAL_PRE_COMMIT_RUN.match(output)
Beispiel #14
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)