Esempio n. 1
0
    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
Esempio n. 2
0
    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
Esempio n. 3
0
    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
Esempio n. 4
0
    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
Esempio n. 5
0
    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
Esempio n. 6
0
    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
Esempio n. 7
0
    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)
Esempio n. 8
0
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
Esempio n. 9
0
    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)
Esempio n. 10
0
    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)
Esempio n. 11
0
    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
Esempio n. 12
0
    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)
Esempio n. 13
0
    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
Esempio n. 14
0
    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
Esempio n. 15
0
    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
Esempio n. 16
0
 def log(self, *args, **kwargs):
     logger.info(*args, **kwargs)
Esempio n. 17
0
 def log(self, *args: Any, **kwargs: Any) -> None:
     """Outputs a log during the session."""
     logger.info(*args, **kwargs)
Esempio n. 18
0
 def log(self, *args, **kwargs):
     """Outputs a log during the session."""
     logger.info(*args, **kwargs)
Esempio n. 19
0
 def __call__(self, session, **kwargs):
     logger.info('Notifying session: %s' % self.target)
     session.manifest.notify(self.target)
Esempio n. 20
0
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
Esempio n. 21
0
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
Esempio n. 22
0
 def log(self, *args, **kwargs):
     """Outputs a log during the session."""
     logger.info(*args, **kwargs)
Esempio n. 23
0
    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)