예제 #1
0
    def _get_nox_session_name(self, python: str) -> str:
        nox_cmd_substring = (f"--noxfile={self.setup_noxfile} "
                             f"--session={self.nox_session_name} "
                             f"--python={python}")

        list_output = asv_util.check_output(
            ["nox", "--list", *nox_cmd_substring.split(" ")],
            display_error=False,
            dots=False,
        )
        list_output = list_output.split("\n")
        list_matches = list(filter(lambda s: s.startswith("*"), list_output))
        matches_count = len(list_matches)

        if matches_count == 0:
            message = f"No Nox sessions found for: {nox_cmd_substring} ."
            log.error(message)
            raise RuntimeError(message)
        elif matches_count > 1:
            message = (
                f"Ambiguous - >1 Nox session found for: {nox_cmd_substring} .")
            log.error(message)
            raise RuntimeError(message)
        else:
            line = list_matches[0]
            session_name = line.split(" ")[1]
            assert isinstance(session_name, str)
            return session_name
예제 #2
0
    def _nox_prep_env(self, setup: bool = False) -> None:
        message = f"Running Nox environment update for: {self.name}"
        log.info(message)

        build_root_path = Path(self._build_root)
        env_path = Path(self._path)

        def copy_asv_files(src_parent: Path, dst_parent: Path) -> None:
            """For copying between self._path and a temporary cache."""
            asv_files = list(src_parent.glob("asv*"))
            # build_root_path.name usually == "project" .
            asv_files += [src_parent / build_root_path.name]
            for src_path in asv_files:
                dst_path = dst_parent / src_path.name
                if not dst_path.exists():
                    # Only cache-ing in case Nox has rebuilt the env @
                    #  self._path. If the dst_path already exists: rebuilding
                    #  hasn't happened. Also a non-issue when copying in the
                    #  reverse direction because the cache dir is temporary.
                    if src_path.is_dir():
                        func = copytree
                    else:
                        func = copy2
                    func(src_path, dst_path)

        with TemporaryDirectory(prefix="nox_asv_cache_") as asv_cache:
            asv_cache_path = Path(asv_cache)
            if setup:
                noxfile = self.setup_noxfile
            else:
                # Cache all of ASV's files as Nox may remove and re-build the environment.
                copy_asv_files(env_path, asv_cache_path)
                # Get location of noxfile in cache.
                noxfile_original = (build_root_path / self._repo_subdir /
                                    self.noxfile_rel_path)
                noxfile_subpath = noxfile_original.relative_to(
                    build_root_path.parent)
                noxfile = asv_cache_path / noxfile_subpath

            nox_cmd = [
                "nox",
                f"--noxfile={noxfile}",
                # Place the env in the ASV env directory, instead of the default.
                f"--envdir={env_path.parent}",
                f"--session={self.nox_session_name}",
                f"--python={self._python}",
                "--install-only",
                "--no-error-on-external-run",
                "--verbose",
            ]

            _ = asv_util.check_output(nox_cmd)
            if not env_path.is_dir():
                message = f"Expected Nox environment not found: {env_path}"
                log.error(message)
                raise RuntimeError(message)

            if not setup:
                # Restore ASV's files from the cache (if necessary).
                copy_asv_files(asv_cache_path, env_path)
예제 #3
0
    def _nox_prep_env(self, setup: bool = False) -> None:
        message = f"Running Nox environment update for: {self.name}"
        log.info(message)

        build_root_path = Path(self._build_root)
        env_path = Path(self._path)

        def copy_asv_files(src_parent: Path, dst_parent: Path) -> None:
            """For copying between self._path and a temporary cache."""
            asv_files = list(src_parent.glob("asv*"))
            # build_root_path.name usually == "project" .
            asv_files += [src_parent / build_root_path.name]
            for src_path in asv_files:
                dst_path = dst_parent / src_path.name
                if not dst_path.exists():
                    # Only cache-ing in case Nox has rebuilt the env @
                    #  self._path. If the dst_path already exists: rebuilding
                    #  hasn't happened. Also a non-issue when copying in the
                    #  reverse direction because the cache dir is temporary.
                    if src_path.is_dir():
                        func = copytree
                    else:
                        func = copy2
                    func(src_path, dst_path)

        with TemporaryDirectory(prefix="nox_asv_cache_") as asv_cache:
            asv_cache_path = Path(asv_cache)
            if setup:
                noxfile_path = self.setup_noxfile
            else:
                # Cache all of ASV's files as Nox may remove and re-build the environment.
                copy_asv_files(env_path, asv_cache_path)
                # Get location of noxfile in cache.
                noxfile_path_build = (build_root_path / self._repo_subdir /
                                      NOXFILE_REL_PATH)
                noxfile_path = asv_cache_path / noxfile_path_build.relative_to(
                    build_root_path.parent)

            nox_cmd = [
                "nox",
                f"--noxfile={noxfile_path}",
                f"--envdir={env_path.parent}",
                f"--session={SESSION_NAME}",
                f"--python={self._python}",
                "--install-only",
                "--no-error-on-external-run",
                "--verbose",
            ]

            _ = asv_util.check_output(nox_cmd)
            if not env_path.is_dir():
                message = f"Expected Nox environment not found: {env_path}"
                log.error(message)

            if not setup:
                # Restore ASV's files from the cache (if necessary).
                copy_asv_files(asv_cache_path, env_path)

        if (not setup) and self._extra_reqs_path.is_file():
            # No need during initial ASV setup - this will be run again before
            #  any benchmarks are run.
            cmd = f"{self.conda} env update -f {self._extra_reqs_path} -p {env_path}"
            asv_util.check_output(cmd.split(" "))
예제 #4
0
    def _prep_env(self) -> None:
        """Run the custom environment script(s) and switch to using that environment."""
        message = f"Running delegated environment management for: {self.name}"
        log.info(message)
        env_path = Path(self._path)

        def copy_asv_files(src_parent: Path, dst_parent: Path) -> None:
            """For copying between self._path and a temporary cache."""
            asv_files = list(src_parent.glob("asv*"))
            # build_root_path.name usually == "project" .
            asv_files += [src_parent / Path(self._build_root).name]
            for src_path in asv_files:
                dst_path = dst_parent / src_path.name
                if not dst_path.exists():
                    # Only caching in case the environment has been rebuilt.
                    #  If the dst_path already exists: rebuilding hasn't
                    #  happened. Also a non-issue when copying in the reverse
                    #  direction because the cache dir is temporary.
                    if src_path.is_dir():
                        func = copytree
                    else:
                        func = copy2
                    func(src_path, dst_path)

        with TemporaryDirectory(prefix="delegated_asv_cache_") as asv_cache:
            asv_cache_path = Path(asv_cache)
            # Cache all of ASV's files as delegated command may remove and
            #  re-build the environment.
            copy_asv_files(env_path.resolve(), asv_cache_path)

            # Adapt the build_dir to the cache location.
            build_root_path = Path(self._build_root)
            build_dir_original = build_root_path / self._repo_subdir
            build_dir_subpath = build_dir_original.relative_to(
                build_root_path.parent)
            build_dir = asv_cache_path / build_dir_subpath

            # Run the script(s) for delegated environment creation/updating.
            # (An adaptation of self._interpolate_and_run_commands).
            for command, env, return_codes, cwd in self._env_commands:
                local_envs = dict(environ)
                local_envs.update(env)
                if cwd is None:
                    cwd = str(build_dir)
                _ = asv_util.check_output(
                    command,
                    timeout=self._install_timeout,
                    cwd=cwd,
                    env=local_envs,
                    valid_return_codes=return_codes,
                )

            # Replace the env that ASV created with a symlink to the env
            #  created/updated by the custom script.
            delegated_env_path = sorted(
                self._delegated_env_parent.glob("*"),
                key=getmtime,
                reverse=True,
            )[0]
            if env_path.resolve() != delegated_env_path:
                try:
                    env_path.unlink(missing_ok=True)
                except IsADirectoryError:
                    rmtree(env_path)
                env_path.symlink_to(delegated_env_path,
                                    target_is_directory=True)

            # Check that environment exists.
            try:
                env_path.resolve(strict=True)
            except FileNotFoundError:
                message = f"Path does not resolve to environment: {env_path}"
                log.error(message)
                raise RuntimeError(message)

            # Restore ASV's files from the cache (if necessary).
            copy_asv_files(asv_cache_path, env_path.resolve())

            # Record new environment information in properties.
            self._update_info()