def create(self) -> bool: """Create the conda env.""" if not self._clean_location(): logger.debug( "Re-using existing conda env at {}.".format(self.location_name) ) return False cmd = [ "conda", "create", "--yes", "--prefix", self.location, # Ensure the pip package is installed. "pip", ] cmd.extend(self.venv_params) if self.interpreter: python_dep = "python={}".format(self.interpreter) else: python_dep = "python" cmd.append(python_dep) logger.info( "Creating conda env in {} with {}".format(self.location_name, python_dep) ) nox.command.run(cmd, silent=True, log=False) return True
def create(self) -> bool: """Create the virtualenv or venv.""" if not self._clean_location(): logger.debug( "Re-using existing virtual environment at {}.".format( self.location_name ) ) return False if self.venv_or_virtualenv == "virtualenv": cmd = [sys.executable, "-m", "virtualenv", self.location] if self.interpreter: cmd.extend(["-p", self._resolved_interpreter]) else: cmd = [self._resolved_interpreter, "-m", "venv", self.location] cmd.extend(self.venv_params) logger.info( "Creating virtual environment ({}) using {} in {}".format( self.venv_or_virtualenv, os.path.basename(self._resolved_interpreter), self.location_name, ) ) nox.command.run(cmd, silent=True, log=False) return True
def execute(self): logger.warning('Running session {}'.format(self.signature or self.name)) try: self._create_config() self._create_venv() self._install_dependencies() if self.config._dir != '.': logger.info('Changing directory to {}'.format( self.config._dir)) cwd = py.path.local(self.config._dir).as_cwd() with cwd: self._run_commands() logger.success('Session {} successful. :)'.format(self.name)) return True except CommandFailed: logger.error('Session {} failed. :('.format(self.name)) return False except KeyboardInterrupt: logger.error('Session {} interrupted.'.format(self.name)) raise
def run(self): cmd, args = self.args[0], self.args[1:] full_cmd = ' '.join(self.args) logger.info(full_cmd) cmd_path = which(cmd, self.path) try: return_code, output = popen([cmd_path] + list(args), silent=self.silent, env=self.env) if return_code not in self.success_codes: logger.error('Command {} failed with exit code {}{}'.format( full_cmd, return_code, ':' if self.silent else '')) if self.silent: sys.stderr.write(output) raise CommandFailed('Returned code {}'.format(return_code)) return output if self.silent else True except KeyboardInterrupt: logger.error('Interrupted...') raise
def create(self) -> bool: """Create the virtualenv or venv.""" if not self._clean_location(): logger.debug( f"Re-using existing virtual environment at {self.location_name}." ) self._reused = True return False if self.venv_or_virtualenv == "virtualenv": cmd = [sys.executable, "-m", "virtualenv", self.location] if self.interpreter: cmd.extend(["-p", self._resolved_interpreter]) else: cmd = [self._resolved_interpreter, "-m", "venv", self.location] cmd.extend(self.venv_params) resolved_interpreter_name = os.path.basename( self._resolved_interpreter) logger.info( f"Creating virtual environment ({self.venv_or_virtualenv}) using" f" {resolved_interpreter_name} in {self.location_name}") nox.command.run(cmd, silent=True, log=nox.options.verbose or False) return True
def create(self) -> bool: """Create the conda env.""" if not self._clean_location(): logger.debug( f"Re-using existing conda env at {self.location_name}.") self._reused = True return False cmd = [self.conda_cmd, "create", "--yes", "--prefix", self.location] cmd.extend(self.venv_params) # Ensure the pip package is installed. cmd.append("pip") if self.interpreter: python_dep = f"python={self.interpreter}" else: python_dep = "python" cmd.append(python_dep) logger.info( f"Creating conda env in {self.location_name} with {python_dep}") nox.command.run(cmd, silent=True, log=nox.options.verbose or False) return True
def run(self, *args: str, env: Mapping[str, str] = None, **kwargs: Any) -> Optional[Any]: """Run a command. Commands must be specified as a list of strings, for example:: session.run('pytest', '-k', 'fast', 'tests/') session.run('flake8', '--import-order-style=google') You **can not** just pass everything as one string. For example, this **will not work**:: session.run('pytest -k fast tests/') You can set environment variables for the command using ``env``:: session.run( 'bash', '-c', 'echo $SOME_ENV', env={'SOME_ENV': 'Hello'}) You can also tell nox to treat non-zero exit codes as success using ``success_codes``. For example, if you wanted to treat the ``pytest`` "tests discovered, but none selected" error as success:: session.run( 'pytest', '-k', 'not slow', success_codes=[0, 5]) On Windows, builtin commands like ``del`` cannot be directly invoked, but you can use ``cmd /c`` to invoke them:: session.run('cmd', '/c', 'del', 'docs/modules.rst') :param env: A dictionary of environment variables to expose to the command. By default, all environment variables are passed. :type env: dict or None :param bool silent: Silence command output, unless the command fails. ``False`` by default. :param success_codes: A list of return codes that are considered successful. By default, only ``0`` is considered success. :type success_codes: list, tuple, or None :param external: If False (the default) then programs not in the virtualenv path will cause a warning. If True, no warning will be emitted. These warnings can be turned into errors using ``--error-on-external-run``. This has no effect for sessions that do not have a virtualenv. :type external: bool """ if not args: raise ValueError("At least one argument required to run().") if self._runner.global_config.install_only: logger.info("Skipping {} run, as --install-only is set.".format( args[0])) return None return self._run(*args, env=env, **kwargs)
def run(args, *, env=None, silent=False, path=None, success_codes=None, log=True, external=False, **popen_kws): """Run a command-line program.""" if success_codes is None: success_codes = [0] cmd, args = args[0], args[1:] full_cmd = "{} {}".format(cmd, " ".join(args)) cmd_path = which(cmd, path) if log: logger.info(full_cmd) is_external_tool = path is not None and not cmd_path.startswith(path) if is_external_tool: if external == "error": logger.error( "Error: {} is not installed into the virtualenv, it is located at {}. " "Pass external=True into run() to explicitly allow this.". format(cmd, cmd_path)) raise CommandFailed("External program disallowed.") elif external is False: logger.warning( "Warning: {} is not installed into the virtualenv, it is located at {}. This might cause issues! " "Pass external=True into run() to silence this message.". format(cmd, cmd_path)) env = _clean_env(env) try: return_code, output = popen([cmd_path] + list(args), silent=silent, env=env, **popen_kws) if return_code not in success_codes: logger.error("Command {} failed with exit code {}{}".format( full_cmd, return_code, ":" if silent else "")) if silent: sys.stderr.write(output) raise CommandFailed("Returned code {}".format(return_code)) return output if silent else True except KeyboardInterrupt: logger.error("Interrupted...") raise
def run(self): func_name = self.func.__name__ logger.info('{}()'.format(func_name)) try: self.func() return True except Exception as e: logger.exception('Function {} raised {}.'.format(func_name, e)) raise CommandFailed(e)
def run(self): logger.info(str(self)) try: self.func(*self.args, **self.kwargs) return True except Exception as e: logger.exception('Function {} raised {}.'.format( self._func_name, e)) raise CommandFailed(e)
def run(self, path_override=None, env_fallback=None, **kwargs): path = self.path if path_override is None else path_override env = env_fallback.copy() if env_fallback is not None else None if self.env is not None: if env is None: env = self.env else: env.update(self.env) cmd, args = self.args[0], self.args[1:] full_cmd = ' '.join(self.args) logger.info(full_cmd) cmd_path = which(cmd, path) # Environment variables must be the "str" type. # In other words, they must be bytestrings in Python 2, and Unicode # text strings in Python 3. clean_env = {} if env is not None else None if clean_env is not None: # Ensure systemroot is passed down, otherwise Windows will explode. clean_env[str('SYSTEMROOT')] = os.environ.get( 'SYSTEMROOT', str('')) for key, value in six.iteritems(env): key = coerce_str(key) value = coerce_str(value) clean_env[key] = value try: return_code, output = popen( [cmd_path] + list(args), silent=self.silent, env=clean_env) if return_code not in self.success_codes: logger.error('Command {} failed with exit code {}{}'.format( full_cmd, return_code, ':' if self.silent else '')) if self.silent: sys.stderr.write(output) raise CommandFailed('Returned code {}'.format(return_code)) return output if self.silent else True except KeyboardInterrupt: logger.error('Interrupted...') raise
def run(self, *args, env=None, **kwargs): """Run a command. Commands must be specified as a list of strings, for example:: session.run('py.test', '-k', 'fast', 'tests/') session.run('flake8', '--import-order-style=google') You **can not** just pass everything as one string. For example, this **will not work**:: session.run('py.test -k fast tests/') You can set environment variables for the command using ``env``:: session.run( 'bash', '-c', 'echo $SOME_ENV', env={'SOME_ENV': 'Hello'}) You can also tell nox to treat non-zero exit codes as success using ``success_codes``. For example, if you wanted to treat the ``py.test`` "tests discovered, but none selected" error as success:: session.run( 'py.test', '-k', 'not slow', success_codes=[0, 5]) :param env: A dictionary of environment variables to expose to the command. By default, all environment variables are passed. :type env: dict or None :param bool silent: Silence command output, unless the command fails. ``False`` by default. :param success_codes: A list of return codes that are considered successful. By default, only ``0`` is considered success. :type success_codes: list, tuple, or None :param external: If False (the default) then programs not in the virtualenv path will cause a warning. If True, no warning will be emitted. These warnings can be turned into errors using ``--error-on-external-run``. This has no effect for sessions that do not have a virtualenv. :type external: bool """ if not args: raise ValueError("At least one argument required to run().") if self._runner.global_config.install_only: logger.info("Skipping {} run, as --install-only is set.".format(args[0])) return return self._run(*args, env=env, **kwargs)
def create(self): """Create the virtualenv.""" if not self._clean_location(): logger.debug("Re-using existing virtualenv at {}.".format( self.location_name)) return False cmd = [sys.executable, "-m", "virtualenv", self.location] if self.interpreter: cmd.extend(["-p", self._resolved_interpreter]) logger.info("Creating virtualenv using {} in {}".format( os.path.basename(self._resolved_interpreter), self.location)) nox.command.run(cmd, silent=True, log=False) return True
def run(self, path_override=None, env_override=None): path = self.path if path_override is None else path_override env = self.env if env_override is None else env_override cmd, args = self.args[0], self.args[1:] full_cmd = ' '.join(self.args) logger.info(full_cmd) cmd_path = which(cmd, path) # Environment variables must be bytestrings. clean_env = {} if env is not None else None if clean_env is not None: # Ensure systemroot is passed down, otherwise Windows will explode. clean_env[str('SYSTEMROOT')] = os.environ.get( 'SYSTEMROOT', str('')) for key, value in six.iteritems(env): if not isinstance(key, six.text_type): key = key.decode('utf-8') if not isinstance(value, six.text_type): value = value.decode('utf-8') clean_env[key] = value try: return_code, output = popen([cmd_path] + list(args), silent=self.silent, env=clean_env) if return_code not in self.success_codes: logger.error('Command {} failed with exit code {}{}'.format( full_cmd, return_code, ':' if self.silent else '')) if self.silent: sys.stderr.write(output) raise CommandFailed('Returned code {}'.format(return_code)) return output if self.silent else True except KeyboardInterrupt: logger.error('Interrupted...') raise
def create(self): """Create the virtualenv.""" if not self._clean_location(): logger.debug("Re-using existing virtualenv at {}.".format(self.location)) return False cmd = [sys.executable, "-m", "virtualenv", self.location] if self.interpreter: cmd.extend(["-p", self._resolved_interpreter]) logger.info( "Creating virtualenv using {} in {}".format( os.path.basename(self._resolved_interpreter), self.location ) ) nox.command.run(cmd, silent=True, log=False) return True
def log(self, *args, **kwargs): logger.info(*args, **kwargs)
def log(self, *args: Any, **kwargs: Any) -> None: """Outputs a log during the session.""" logger.info(*args, **kwargs)
def log(self, *args, **kwargs): """Outputs a log during the session.""" logger.info(*args, **kwargs)
def __call__(self, session, **kwargs): logger.info('Notifying session: %s' % self.target) session.manifest.notify(self.target)
def run( args: Sequence[str], *, env: Optional[dict] = None, silent: bool = False, paths: Optional[List[str]] = None, success_codes: Optional[Iterable[int]] = None, log: bool = True, external: Union[Literal["error"], bool] = False, **popen_kws: Any, ) -> Union[str, bool]: """Run a command-line program.""" if success_codes is None: success_codes = [0] cmd, args = args[0], args[1:] full_cmd = f"{cmd} {_shlex_join(args)}" cmd_path = which(cmd, paths) if log: logger.info(full_cmd) is_external_tool = paths is not None and not any( cmd_path.startswith(path) for path in paths) if is_external_tool: if external == "error": logger.error( f"Error: {cmd} is not installed into the virtualenv, it is located at {cmd_path}. " "Pass external=True into run() to explicitly allow this.") raise CommandFailed("External program disallowed.") elif external is False: logger.warning( f"Warning: {cmd} is not installed into the virtualenv, it is located at {cmd_path}. This might cause issues! " "Pass external=True into run() to silence this message.") env = _clean_env(env) try: return_code, output = popen([cmd_path] + list(args), silent=silent, env=env, **popen_kws) if return_code not in success_codes: suffix = ":" if silent else "" logger.error( f"Command {full_cmd} failed with exit code {return_code}{suffix}" ) if silent: sys.stderr.write(output) raise CommandFailed(f"Returned code {return_code}") if output: logger.output(output) return output if silent else True except KeyboardInterrupt: logger.error("Interrupted...") raise
def run( args, *, env=None, silent=False, path=None, success_codes=None, log=True, external=False ): """Run a command-line program.""" if success_codes is None: success_codes = [0] cmd, args = args[0], args[1:] full_cmd = "{} {}".format(cmd, " ".join(args)) cmd_path = which(cmd, path) if log: logger.info(full_cmd) is_external_tool = path is not None and not cmd_path.startswith(path) if is_external_tool: if external == "error": logger.error( "Error: {} is not installed into the virtualenv, it is located at {}. " "Pass external=True into run() to explicitly allow this.".format( cmd, cmd_path ) ) raise CommandFailed("External program disallowed.") elif external is False: logger.warning( "Warning: {} is not installed into the virtualenv, is it located at {}. This might cause issues! " "Pass external=True into run() to silence this message.".format( cmd, cmd_path ) ) env = _clean_env(env) try: return_code, output = popen([cmd_path] + list(args), silent=silent, env=env) if return_code not in success_codes: logger.error( "Command {} failed with exit code {}{}".format( full_cmd, return_code, ":" if silent else "" ) ) if silent: sys.stderr.write(output) raise CommandFailed("Returned code {}".format(return_code)) return output if silent else True except KeyboardInterrupt: logger.error("Interrupted...") raise
def run(self, *args: str, env: Mapping[str, str] | None = None, **kwargs: Any) -> Any | None: """Run a command. Commands must be specified as a list of strings, for example:: session.run('pytest', '-k', 'fast', 'tests/') session.run('flake8', '--import-order-style=google') You **can not** just pass everything as one string. For example, this **will not work**:: session.run('pytest -k fast tests/') You can set environment variables for the command using ``env``:: session.run( 'bash', '-c', 'echo $SOME_ENV', env={'SOME_ENV': 'Hello'}) You can extend the shutdown timeout to allow long-running cleanup tasks to complete before being terminated. For example, if you wanted to allow ``pytest`` extra time to clean up large projects in the case that Nox receives an interrupt signal from your build system and needs to terminate its child processes:: session.run( 'pytest', '-k', 'long_cleanup', interrupt_timeout=10.0, terminate_timeout=2.0) You can also tell Nox to treat non-zero exit codes as success using ``success_codes``. For example, if you wanted to treat the ``pytest`` "tests discovered, but none selected" error as success:: session.run( 'pytest', '-k', 'not slow', success_codes=[0, 5]) On Windows, builtin commands like ``del`` cannot be directly invoked, but you can use ``cmd /c`` to invoke them:: session.run('cmd', '/c', 'del', 'docs/modules.rst') If ``session.run`` fails, it will stop the session and will not run the next steps. Basically, this will raise a Python exception. Taking this in count, you can use a ``try...finally`` block for cleanup runs, that will run even if the other runs fail:: try: session.run("coverage", "run", "-m", "pytest") finally: # Display coverage report even when tests fail. session.run("coverage", "report") :param env: A dictionary of environment variables to expose to the command. By default, all environment variables are passed. :type env: dict or None :param bool silent: Silence command output, unless the command fails. If ``True``, returns the command output (unless the command fails). ``False`` by default. :param success_codes: A list of return codes that are considered successful. By default, only ``0`` is considered success. :type success_codes: list, tuple, or None :param external: If False (the default) then programs not in the virtualenv path will cause a warning. If True, no warning will be emitted. These warnings can be turned into errors using ``--error-on-external-run``. This has no effect for sessions that do not have a virtualenv. :type external: bool :param interrupt_timeout: The timeout (in seconds) that Nox should wait after it and its children receive an interrupt signal before sending a terminate signal to its children. Set to ``None`` to never send a terminate signal. Default: ``0.3`` :type interrupt_timeout: float or None :param terminate_timeout: The timeout (in seconds) that Nox should wait after it sends a terminate signal to its children before sending a kill signal to them. Set to ``None`` to never send a kill signal. Default: ``0.2`` :type terminate_timeout: float or None """ if not args: raise ValueError("At least one argument required to run().") if self._runner.global_config.install_only: logger.info(f"Skipping {args[0]} run, as --install-only is set.") return None return self._run(*args, env=env, **kwargs)