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
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)
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(" "))
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()