Example #1
0
def install_environment(
    prefix: Prefix,
    version: str,
    additional_dependencies: Sequence[str],
) -> None:
    additional_dependencies = tuple(additional_dependencies)
    assert prefix.exists('package.json')
    envdir = _envdir(prefix, version)

    # https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx?f=255&MSPPError=-2147217396#maxpath
    if sys.platform == 'win32':  # pragma: no cover
        envdir = fr'\\?\{os.path.normpath(envdir)}'
    with clean_path_on_failure(envdir):
        cmd = [
            sys.executable,
            '-mnodeenv',
            '--prebuilt',
            '--clean-src',
            envdir,
        ]
        if version != C.DEFAULT:
            cmd.extend(['-n', version])
        cmd_output_b(*cmd)

        with in_env(prefix, version):
            # https://npm.community/t/npm-install-g-git-vs-git-clone-cd-npm-install-g/5449
            # install as if we installed from git
            helpers.run_setup_cmd(prefix, ('npm', 'install'))
            helpers.run_setup_cmd(
                prefix,
                ('npm', 'install', '-g', '.', *additional_dependencies),
            )
Example #2
0
def install_environment(
    prefix: Prefix, version: str, additional_dependencies: Sequence[str],
) -> None:
    helpers.assert_version_default("conda", version)
    directory = helpers.environment_dir(ENVIRONMENT_DIR, version)

    env_dir = prefix.path(directory)
    with clean_path_on_failure(env_dir):
        cmd_output_b(
            "conda",
            "env",
            "create",
            "-p",
            env_dir,
            "--file",
            "environment.yml",
            cwd=prefix.prefix_dir,
        )
        if additional_dependencies:
            cmd_output_b(
                "conda",
                "install",
                "-p",
                env_dir,
                *additional_dependencies,
                cwd=prefix.prefix_dir,
            )
Example #3
0
def install_environment(prefix, version, additional_dependencies):
    helpers.assert_version_default('golang', version)
    directory = prefix.path(
        helpers.environment_dir(ENVIRONMENT_DIR, C.DEFAULT), )

    with clean_path_on_failure(directory):
        remote = git.get_remote_url(prefix.prefix_dir)
        repo_src_dir = os.path.join(directory, 'src', guess_go_dir(remote))

        # Clone into the goenv we'll create
        helpers.run_setup_cmd(prefix, ('git', 'clone', '.', repo_src_dir))

        if sys.platform == 'cygwin':  # pragma: no cover
            _, gopath, _ = cmd_output('cygpath', '-w', directory)
            gopath = gopath.strip()
        else:
            gopath = directory
        env = dict(os.environ, GOPATH=gopath)
        env.pop('GOBIN', None)
        cmd_output_b('go', 'get', './...', cwd=repo_src_dir, env=env)
        for dependency in additional_dependencies:
            cmd_output_b('go', 'get', dependency, cwd=repo_src_dir, env=env)
        # Same some disk space, we don't need these after installation
        rmtree(prefix.path(directory, 'src'))
        pkgdir = prefix.path(directory, 'pkg')
        if os.path.exists(pkgdir):  # pragma: no cover (go<1.10)
            rmtree(pkgdir)
Example #4
0
def commit(repo: str = '.') -> None:
    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
    cmd = ('git', 'commit', '--no-edit', '--no-gpg-sign', '-n', '-minit')
    cmd_output_b(*cmd, cwd=repo, env=env)
def docker_is_running() -> bool:  # pragma: win32 no cover
    try:
        cmd_output_b("docker", "ps")
    except CalledProcessError:
        return False
    else:
        return True
def commit(repo: str = ".") -> None:
    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
    cmd = ("git", "commit", "--no-edit", "--no-gpg-sign", "-n", "-minit")
    cmd_output_b(*cmd, cwd=repo, env=env)
def install_environment(
    prefix: Prefix,
    version: str,
    additional_dependencies: Sequence[str],
) -> None:
    helpers.assert_version_default("golang", version)
    directory = prefix.path(
        helpers.environment_dir(ENVIRONMENT_DIR, C.DEFAULT), )

    with clean_path_on_failure(directory):
        remote = git.get_remote_url(prefix.prefix_dir)
        repo_src_dir = os.path.join(directory, "src", guess_go_dir(remote))

        # Clone into the goenv we'll create
        helpers.run_setup_cmd(prefix, ("git", "clone", ".", repo_src_dir))

        if sys.platform == "cygwin":  # pragma: no cover
            _, gopath, _ = cmd_output("cygpath", "-w", directory)
            gopath = gopath.strip()
        else:
            gopath = directory
        env = dict(os.environ, GOPATH=gopath)
        env.pop("GOBIN", None)
        cmd_output_b("go", "get", "./...", cwd=repo_src_dir, env=env)
        for dependency in additional_dependencies:
            cmd_output_b("go", "get", dependency, cwd=repo_src_dir, env=env)
        # Same some disk space, we don't need these after installation
        rmtree(prefix.path(directory, "src"))
        pkgdir = prefix.path(directory, "pkg")
        if os.path.exists(pkgdir):  # pragma: no cover (go<1.10)
            rmtree(pkgdir)
Example #8
0
def greppable_files(tmpdir):
    with tmpdir.as_cwd():
        cmd_output_b('git', 'init', '.')
        tmpdir.join('f1').write_binary(b"hello'hi\nworld\n")
        tmpdir.join('f2').write_binary(b'foo\nbar\nbaz\n')
        tmpdir.join('f3').write_binary(b'[WARN] hi\n')
        yield tmpdir
Example #9
0
def init_repo(path: str, remote: str) -> None:
    if os.path.isdir(remote):
        remote = os.path.abspath(remote)

    env = no_git_env()
    cmd_output_b('git', 'init', path, env=env)
    cmd_output_b('git', 'remote', 'add', 'origin', remote, cwd=path, env=env)
Example #10
0
def _git_apply(patch: str) -> None:
    args = ('apply', '--whitespace=nowarn', patch)
    try:
        cmd_output_b('git', *args)
    except CalledProcessError:
        # Retry with autocrlf=false -- see #570
        cmd_output_b('git', '-c', 'core.autocrlf=false', *args)
def _git_apply(patch: str) -> None:
    args = ("apply", "--whitespace=nowarn", patch)
    try:
        cmd_output_b("git", *args)
    except CalledProcessError:
        # Retry with autocrlf=false -- see #570
        cmd_output_b("git", "-c", "core.autocrlf=false", *args)
Example #12
0
def docker_is_running() -> bool:  # pragma: win32 no cover
    try:
        cmd_output_b('docker', 'ps')
    except CalledProcessError:  # pragma: no cover
        return False
    else:
        return True
Example #13
0
    def update(self, tags_only: bool, freeze: bool) -> RevInfo:
        git_cmd = ('git', *git.NO_FS_MONITOR)

        if tags_only:
            tag_cmd = (
                *git_cmd, 'describe',
                'FETCH_HEAD', '--tags', '--abbrev=0',
            )
        else:
            tag_cmd = (
                *git_cmd, 'describe',
                'FETCH_HEAD', '--tags', '--exact',
            )

        with tmpdir() as tmp:
            git.init_repo(tmp, self.repo)
            cmd_output_b(
                *git_cmd, 'fetch', 'origin', 'HEAD', '--tags',
                cwd=tmp,
            )

            try:
                rev = cmd_output(*tag_cmd, cwd=tmp)[1].strip()
            except CalledProcessError:
                cmd = (*git_cmd, 'rev-parse', 'FETCH_HEAD')
                rev = cmd_output(*cmd, cwd=tmp)[1].strip()

            frozen = None
            if freeze:
                exact_rev_cmd = (*git_cmd, 'rev-parse', rev)
                exact = cmd_output(*exact_rev_cmd, cwd=tmp)[1].strip()
                if exact != rev:
                    rev, frozen = exact, rev
        return self._replace(rev=rev, frozen=frozen)
Example #14
0
def install_environment(
    prefix: Prefix,
    version: str,
    additional_dependencies: Sequence[str],
) -> None:
    helpers.assert_version_default('conda', version)
    directory = helpers.environment_dir(ENVIRONMENT_DIR, version)

    conda_exe = _conda_exe()

    env_dir = prefix.path(directory)
    with clean_path_on_failure(env_dir):
        cmd_output_b(
            conda_exe,
            'env',
            'create',
            '-p',
            env_dir,
            '--file',
            'environment.yml',
            cwd=prefix.prefix_dir,
        )
        if additional_dependencies:
            cmd_output_b(
                conda_exe,
                'install',
                '-p',
                env_dir,
                *additional_dependencies,
                cwd=prefix.prefix_dir,
            )
def init_repo(path: str, remote: str) -> None:
    if os.path.isdir(remote):
        remote = os.path.abspath(remote)

    env = no_git_env()
    # avoid the user's template so that hooks do not recurse
    cmd_output_b("git", "init", "--template=", path, env=env)
    cmd_output_b("git", "remote", "add", "origin", remote, cwd=path, env=env)
Example #16
0
def init_repo(path: str, remote: str) -> None:
    if os.path.isdir(remote):
        remote = os.path.abspath(remote)

    env = no_git_env()
    # avoid the user's template so that hooks do not recurse
    cmd_output_b('git', 'init', '--template=', path, env=env)
    cmd_output_b('git', 'remote', 'add', 'origin', remote, cwd=path, env=env)
Example #17
0
def test_really_long_file_paths(tempdir_factory, store):
    base_path = tempdir_factory.get()
    really_long_path = os.path.join(base_path, 'really_long' * 10)
    cmd_output_b('git', 'init', really_long_path)

    path = make_repo(tempdir_factory, 'python_hooks_repo')
    config = make_config_from_repo(path)

    with cwd(really_long_path):
        _get_hook(config, store, 'foo')
Example #18
0
def install_environment(
    prefix: Prefix,
    version: str,
    additional_dependencies: Sequence[str],
) -> None:
    env_dir = _get_env_dir(prefix, version)
    with clean_path_on_failure(env_dir):
        os.makedirs(env_dir, exist_ok=True)
        shutil.copy(prefix.path('renv.lock'), env_dir)
        shutil.copytree(prefix.path('renv'), os.path.join(env_dir, 'renv'))

        cmd_output_b(
            _rscript_exec(),
            '--vanilla',
            '-e',
            f"""\
            prefix_dir <- {prefix.prefix_dir!r}
            options(
                repos = c(CRAN = "https://cran.rstudio.com"),
                renv.consent = TRUE
            )
            source("renv/activate.R")
            renv::restore()
            activate_statement <- paste0(
              'suppressWarnings({{',
              'old <- setwd("', getwd(), '"); ',
              'source("renv/activate.R"); ',
              'setwd(old); ',
              'renv::load("', getwd(), '");}})'
            )
            writeLines(activate_statement, 'activate.R')
            is_package <- tryCatch(
              {{
                  path_desc <- file.path(prefix_dir, 'DESCRIPTION')
                  suppressWarnings(desc <- read.dcf(path_desc))
                  "Package" %in% colnames(desc)
              }},
              error = function(...) FALSE
            )
            if (is_package) {{
                renv::install(prefix_dir)
            }}
            """,
            cwd=env_dir,
        )
        if additional_dependencies:
            with in_env(prefix, version):
                cmd_output_b(
                    _rscript_exec(),
                    *RSCRIPT_OPTS,
                    '-e',
                    'renv::install(commandArgs(trailingOnly = TRUE))',
                    *additional_dependencies,
                    cwd=env_dir,
                )
Example #19
0
def install_environment(
    prefix: Prefix,
    version: str,
    additional_dependencies: Sequence[str],
) -> None:
    env_dir = _get_env_dir(prefix, version)
    with clean_path_on_failure(env_dir):
        os.makedirs(env_dir, exist_ok=True)
        path_desc_source = prefix.path('DESCRIPTION')
        if os.path.exists(path_desc_source):
            shutil.copy(path_desc_source, env_dir)
        shutil.copy(prefix.path('renv.lock'), env_dir)
        cmd_output_b(
            'Rscript',
            '--vanilla',
            '-e',
            """\
            missing_pkgs <- setdiff(
                "renv", unname(installed.packages()[, "Package"])
            )
            options(
                repos = c(CRAN = "https://cran.rstudio.com"),
                renv.consent = TRUE
            )
            install.packages(missing_pkgs)
            renv::activate()
            renv::restore()
            activate_statement <- paste0(
              'renv::activate("', file.path(getwd()), '"); '
            )
            writeLines(activate_statement, 'activate.R')
            is_package <- tryCatch(
                suppressWarnings(
                    unname(read.dcf('DESCRIPTION')[,'Type'] == "Package")
                ),
                error = function(...) FALSE
            )
            if (is_package) {
                renv::install(normalizePath('.'))
            }
            """,
            cwd=env_dir,
        )
        if additional_dependencies:
            cmd_output_b(
                'Rscript',
                '-e',
                'renv::install(commandArgs(trailingOnly = TRUE))',
                *additional_dependencies,
                cwd=env_dir,
            )
Example #20
0
def install_environment(
    prefix: Prefix,
    version: str,
    additional_dependencies: Sequence[str],
) -> None:
    envdir = prefix.path(helpers.environment_dir(ENVIRONMENT_DIR, version))
    python = norm_version(version)
    venv_cmd = (sys.executable, '-mvirtualenv', envdir, '-p', python)
    install_cmd = ('python', '-mpip', 'install', '.', *additional_dependencies)

    with clean_path_on_failure(envdir):
        cmd_output_b(*venv_cmd, cwd='/')
        with in_env(prefix, version):
            helpers.run_setup_cmd(prefix, install_cmd)
Example #21
0
def _unstaged_changes_cleared(patch_dir: str) -> Generator[None, None, None]:
    tree = cmd_output('git', 'write-tree')[1].strip()
    retcode, diff_stdout_binary, _ = cmd_output_b(
        'git',
        'diff-index',
        '--ignore-submodules',
        '--binary',
        '--exit-code',
        '--no-color',
        '--no-ext-diff',
        tree,
        '--',
        retcode=None,
    )
    if retcode and diff_stdout_binary.strip():
        patch_filename = f'patch{int(time.time())}-{os.getpid()}'
        patch_filename = os.path.join(patch_dir, patch_filename)
        logger.warning('Unstaged files detected.')
        logger.info(f'Stashing unstaged files to {patch_filename}.')
        # Save the current unstaged changes as a patch
        os.makedirs(patch_dir, exist_ok=True)
        with open(patch_filename, 'wb') as patch_file:
            patch_file.write(diff_stdout_binary)

        # prevent recursive post-checkout hooks (#1418)
        no_checkout_env = dict(os.environ, _PRE_COMMIT_SKIP_POST_CHECKOUT='1')

        try:
            cmd_output_b(*_CHECKOUT_CMD, env=no_checkout_env)
            yield
        finally:
            # Try to apply the patch we saved
            try:
                _git_apply(patch_filename)
            except CalledProcessError:
                logger.warning(
                    'Stashed changes conflicted with hook auto-fixes... '
                    'Rolling back fixes...', )
                # We failed to apply the patch, presumably due to fixes made
                # by hooks.
                # Roll back the changes made by hooks.
                cmd_output_b(*_CHECKOUT_CMD, env=no_checkout_env)
                _git_apply(patch_filename)

            logger.info(f'Restored changes from {patch_filename}.')
    else:
        # There weren't any staged files so we don't need to do anything
        # special
        yield
Example #22
0
def install_environment(
    prefix: Prefix,
    version: str,
    additional_dependencies: Sequence[str],
) -> None:
    additional_dependencies = tuple(additional_dependencies)
    assert prefix.exists('package.json')
    envdir = _envdir(prefix, version)

    # https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx?f=255&MSPPError=-2147217396#maxpath
    if sys.platform == 'win32':  # pragma: no cover
        envdir = fr'\\?\{os.path.normpath(envdir)}'
    with clean_path_on_failure(envdir):
        cmd = [
            sys.executable,
            '-mnodeenv',
            '--prebuilt',
            '--clean-src',
            envdir,
        ]
        if version != C.DEFAULT:
            cmd.extend(['-n', version])
        cmd_output_b(*cmd)

        with in_env(prefix, version):
            # https://npm.community/t/npm-install-g-git-vs-git-clone-cd-npm-install-g/5449
            # install as if we installed from git

            local_install_cmd = (
                'npm',
                'install',
                '--dev',
                '--prod',
                '--ignore-prepublish',
                '--no-progress',
                '--no-save',
            )
            helpers.run_setup_cmd(prefix, local_install_cmd)

            _, pkg, _ = cmd_output('npm', 'pack', cwd=prefix.prefix_dir)
            pkg = prefix.path(pkg.strip())

            install = ('npm', 'install', '-g', pkg, *additional_dependencies)
            helpers.run_setup_cmd(prefix, install)

            # clean these up after installation
            if prefix.exists('node_modules'):  # pragma: win32 no cover
                rmtree(prefix.path('node_modules'))
            os.remove(pkg)
def _unstaged_changes_cleared(patch_dir: str) -> Generator[None, None, None]:
    tree = cmd_output("git", "write-tree")[1].strip()
    retcode, diff_stdout_binary, _ = cmd_output_b(
        "git",
        "diff-index",
        "--ignore-submodules",
        "--binary",
        "--exit-code",
        "--no-color",
        "--no-ext-diff",
        tree,
        "--",
        retcode=None,
    )
    if retcode and diff_stdout_binary.strip():
        patch_filename = f"patch{int(time.time())}"
        patch_filename = os.path.join(patch_dir, patch_filename)
        logger.warning("Unstaged files detected.")
        logger.info(f"Stashing unstaged files to {patch_filename}.")
        # Save the current unstaged changes as a patch
        os.makedirs(patch_dir, exist_ok=True)
        with open(patch_filename, "wb") as patch_file:
            patch_file.write(diff_stdout_binary)

        # prevent recursive post-checkout hooks (#1418)
        no_checkout_env = dict(os.environ, _PRE_COMMIT_SKIP_POST_CHECKOUT="1")
        cmd_output_b("git", "checkout", "--", ".", env=no_checkout_env)

        try:
            yield
        finally:
            # Try to apply the patch we saved
            try:
                _git_apply(patch_filename)
            except CalledProcessError:
                logger.warning(
                    "Stashed changes conflicted with hook auto-fixes... "
                    "Rolling back fixes...", )
                # We failed to apply the patch, presumably due to fixes made
                # by hooks.
                # Roll back the changes made by hooks.
                cmd_output_b("git", "checkout", "--", ".", env=no_checkout_env)
                _git_apply(patch_filename)

            logger.info(f"Restored changes from {patch_filename}.")
    else:
        # There weren't any staged files so we don't need to do anything
        # special
        yield
def install_environment(
    prefix: Prefix,
    version: str,
    additional_dependencies: Sequence[str],
) -> None:
    helpers.assert_version_default("rust", version)
    directory = prefix.path(
        helpers.environment_dir(ENVIRONMENT_DIR, C.DEFAULT), )

    # There are two cases where we might want to specify more dependencies:
    # as dependencies for the library being built, and as binary packages
    # to be `cargo install`'d.
    #
    # Unlike e.g. Python, if we just `cargo install` a library, it won't be
    # used for compilation. And if we add a crate providing a binary to the
    # `Cargo.toml`, the binary won't be built.
    #
    # Because of this, we allow specifying "cli" dependencies by prefixing
    # with 'cli:'.
    cli_deps = {
        dep
        for dep in additional_dependencies if dep.startswith("cli:")
    }
    lib_deps = set(additional_dependencies) - cli_deps

    if len(lib_deps) > 0:
        _add_dependencies(prefix.path("Cargo.toml"), lib_deps)

    with clean_path_on_failure(directory):
        packages_to_install: Set[Tuple[str, ...]] = {("--path", ".")}
        for cli_dep in cli_deps:
            cli_dep = cli_dep[len("cli:"):]
            package, _, version = cli_dep.partition(":")
            if version != "":
                packages_to_install.add((package, "--version", version))
            else:
                packages_to_install.add((package, ))

        for args in packages_to_install:
            cmd_output_b(
                "cargo",
                "install",
                "--bins",
                "--root",
                directory,
                *args,
                cwd=prefix.prefix_dir,
            )
Example #25
0
def health_check(prefix: Prefix, language_version: str) -> str | None:
    with in_env(prefix, language_version):
        retcode, _, _ = cmd_output_b('node', '--version', retcode=None)
        if retcode != 0:  # pragma: win32 no cover
            return f'`node --version` returned {retcode}'
        else:
            return None
Example #26
0
def _has_unstaged_config(config_file: str) -> bool:
    retcode, _, _ = cmd_output_b(
        'git', 'diff', '--no-ext-diff', '--exit-code', config_file,
        retcode=None,
    )
    # be explicit, other git errors don't mean it has an unstaged config.
    return retcode == 1
Example #27
0
def _norm_pwd(path):
    # Under windows bash's temp and windows temp is different.
    # This normalizes to the bash /tmp
    return cmd_output_b(
        'bash',
        '-c',
        f"cd '{path}' && pwd",
    )[1].strip()
Example #28
0
def _update_repo(repo_config, store, tags_only):
    """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
    """
    with tmpdir() as repo_path:
        git.init_repo(repo_path, repo_config['repo'])
        cmd_output_b('git', 'fetch', 'origin', 'HEAD', '--tags', cwd=repo_path)

        tag_cmd = ('git', 'describe', 'FETCH_HEAD', '--tags')
        if tags_only:
            tag_cmd += ('--abbrev=0', )
        else:
            tag_cmd += ('--exact', )
        try:
            rev = cmd_output(*tag_cmd, cwd=repo_path)[1].strip()
        except CalledProcessError:
            tag_cmd = ('git', 'rev-parse', 'FETCH_HEAD')
            rev = cmd_output(*tag_cmd, cwd=repo_path)[1].strip()

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

    try:
        path = store.clone(repo_config['repo'], rev)
        manifest = load_manifest(os.path.join(path, C.MANIFEST_FILE))
    except InvalidManifestError as e:
        raise RepositoryCannotBeUpdatedError(six.text_type(e))

    # See if any of our hooks were deleted with the new commits
    hooks = {hook['id'] for hook in repo_config['hooks']}
    hooks_missing = hooks - {hook['id'] for hook in manifest}
    if hooks_missing:
        raise RepositoryCannotBeUpdatedError(
            'Cannot update because the tip of master is missing these hooks:\n'
            '{}'.format(', '.join(sorted(hooks_missing))), )

    # Construct a new config with the head rev
    new_config = repo_config.copy()
    new_config['rev'] = rev
    return new_config
Example #29
0
def install_environment(
        prefix, version, additional_dependencies,
):  # pragma: windows no cover
    helpers.assert_version_default('swift', version)
    helpers.assert_no_additional_deps('swift', additional_dependencies)
    directory = prefix.path(
        helpers.environment_dir(ENVIRONMENT_DIR, C.DEFAULT),
    )

    # Build the swift package
    with clean_path_on_failure(directory):
        os.mkdir(directory)
        cmd_output_b(
            'swift', 'build',
            '-C', prefix.prefix_dir,
            '-c', BUILD_CONFIG,
            '--build-path', os.path.join(directory, BUILD_DIR),
        )
Example #30
0
def _get_diff() -> bytes:
    _, out, _ = cmd_output_b(
        'git',
        'diff',
        '--no-ext-diff',
        '--ignore-submodules',
        retcode=None,
    )
    return out