Ejemplo n.º 1
0
    def runin(
        self,
        venv: xcli.Annotated[
            str,
            xcli.Arg(completer=venv_names_completer),
        ],
        args: xcli.Annotated[tp.List[str], xcli.Arg(nargs="...")],
    ):
        """Run the command in the given environment

        Parameters
        ----------
        venv
            The environment to run the command for
        args
            The actual command to run

        Examples
        --------
          vox runin venv1 black --check-only
        """
        env_dir = self._get_env_dir(venv)
        if not args:
            self.parser.error("No command is passed")
        self._in_venv(env_dir, *args)
Ejemplo n.º 2
0
    def remove(
        self,
        names: xcli.Annotated[
            tp.List[str],
            xcli.Arg(metavar="ENV", nargs="+", completer=venv_names_completer
                     ), ],
        force=False,
    ):
        """Remove virtual environments.

        Parameters
        ----------
        names
            The environments to remove. ENV can be either a name from the venvs shown by vox
            list or the path to an arbitrary venv
        force : -f, --force
            Delete virtualenv without prompt
        """
        self.vox.force_removals = force
        for name in names:
            try:
                del self.vox[name]
            except voxapi.EnvironmentInUse:
                raise self.Error(
                    f'The "{name}" environment is currently active. '
                    'In order to remove it, deactivate it first with "vox deactivate".\n',
                )
            except KeyError:
                raise self.Error(f'"{name}" environment doesn\'t exist.\n')
            else:
                self.out(f'Environment "{name}" removed.')
        self.out()
Ejemplo n.º 3
0
    def complete(
        self,
        line: xcli.Annotated["list[str]", xcli.Arg(nargs="...")],
        prefix: "str | None" = None,
    ):
        """Output the completions to stdout

        Parameters
        ----------
        line
            pass the CLI arguments as if they were typed
        prefix : -p, --prefix
            word at cursor

        Examples
        --------
        To get completions such as `git checkout`

        $ completer complete --prefix=check git
        """
        from xonsh.completer import Completer

        completer = Completer()
        completions, prefix_length = completer.complete_line(" ".join(line),
                                                             prefix=prefix)

        self.out(f"Prefix Length: {prefix_length}")
        for comp in completions:
            self.out(repr(comp))
Ejemplo n.º 4
0
    def remove(
        self,
        names: xcli.Annotated[
            list,
            xcli.Arg(metavar="ENV", nargs="+", completer=venv_names_completer
                     ), ],
    ):
        """Remove virtual environments.

        Parameters
        ----------
        names
            The environments to remove. ENV can be either a name from the venvs shown by vox
            list or the path to an arbitrary venv
        """
        for name in names:
            try:
                del self.vox[name]
            except voxapi.EnvironmentInUse:
                self.parser.error(
                    f'The "{name}" environment is currently active. '
                    'In order to remove it, deactivate it first with "vox deactivate".\n',
                )
            except KeyError:
                self.parser.error(f'"{name}" environment doesn\'t exist.\n')
            else:
                print(f'Environment "{name}" removed.')
        print()
Ejemplo n.º 5
0
    def activate(
        self,
        name: xcli.Annotated[
            str,
            xcli.Arg(metavar="ENV", nargs="?", completer=venv_names_completer
                     ), ] = None,
    ):
        """Activate a virtual environment.

        Parameters
        ----------
        name
            The environment to activate.
            ENV can be either a name from the venvs shown by ``vox list``
            or the path to an arbitrary venv
        """

        if name is None:
            return self.list()

        try:
            self.vox.activate(name)
        except KeyError:
            self.parser.error(
                f'This environment doesn\'t exist. Create it with "vox new {name}".\n',
            )
            return None
        else:
            print(f'Activated "{name}".\n')
Ejemplo n.º 6
0
    def new(
        self,
        name: xcli.Annotated[str, xcli.Arg(metavar="ENV")],
        interpreter: xcli.Annotated[
            str,
            xcli.
            Arg("-p", "--interpreter", completer=py_interpreter_path_completer
                ), ] = None,
        system_site_packages=False,
        symlinks: bool = False,
        with_pip: bool = True,
        activate=False,
    ):
        """Create a virtual environment in $VIRTUALENV_HOME with python3's ``venv``.

        Parameters
        ----------
        name : str
            Virtual environment name
        interpreter: str
            Python interpreter used to create the virtual environment.
            Can be configured via the $VOX_DEFAULT_INTERPRETER environment variable.
        system_site_packages : --system-site-packages, --ssp
            If True, the system (global) site-packages dir is available to
            created environments.
        symlinks : bool
            If True, attempt to symlink rather than copy files into virtual
            environment.
        with_pip : bool
            If True, ensure pip is installed in the virtual environment. (Default is True)
        activate : -a, --activate
            Activate the newly created virtual environment.
        """
        print("Creating environment...")
        self.vox.create(
            name,
            system_site_packages=system_site_packages,
            symlinks=symlinks,
            with_pip=with_pip,
            interpreter=interpreter,
        )
        if activate:
            self.vox.activate(name)
            print(f"Environment {name!r} created and activated.\n")
        else:
            print(
                f'Environment {name!r} created. Activate it with "vox activate {name}".\n'
            )
Ejemplo n.º 7
0
Archivo: main.py Proyecto: dyuri/xonsh
    def gc(
        size: xcli.Annotated[tp.Tuple[int, str], xcli.Arg(nargs=2)] = None,
        force=False,
        _blocking=True,
    ):
        """Launches a new history garbage collector

        Parameters
        ----------
        size : -s, --size
            Next two arguments represent the history size and units; e.g. "--size 8128 commands"
        force : -f, --force
            perform garbage collection even if history much bigger than configured limit
        """
        hist = XSH.history
        hist.run_gc(size=size, blocking=_blocking, force=force)
Ejemplo n.º 8
0
    def gc(
        size: xcli.Annotated[tp.Tuple[int, str],
                             xcli.Arg(nargs=2)] = None,
        force=False,
        blocking=True,
    ):
        """Launches a new history garbage collector

        Parameters
        ----------
        size : -s, --size
            Next two arguments represent the history size and units; e.g. "--size 8128 commands"
        force : -f, --force
            perform garbage collection even if history much bigger than configured limit
        blocking : -n, --non-blocking
            makes the gc non-blocking, and thus return sooner. By default it runs on main thread blocking input.
        """
        hist = XSH.history
        hist.run_gc(size=size, blocking=blocking, force=force)
Ejemplo n.º 9
0
    def runin_all(
        self,
        args: xcli.Annotated[tp.List[str], xcli.Arg(nargs="...")],
    ):
        """Run the command in all environments found under $VIRTUALENV_HOME

        Parameters
        ----------
        args
            The actual command to run with arguments
        """
        errors = False
        for env in self.vox:
            print("\n%s:" % env)
            try:
                self.runin(env, *args)
            except subprocess.CalledProcessError as e:
                errors = True
                print(e, file=sys.stderr)
        sys.exit(errors)
Ejemplo n.º 10
0
    def new(
        self,
        name: xcli.Annotated[str, xcli.Arg(metavar="ENV")],
        interpreter: "str|None" = None,
        system_site_packages=False,
        symlinks=True,
        without_pip=False,
        activate=False,
        temporary=False,
        packages: xcli.Annotated[tp.Sequence[str],
                                 xcli.Arg(nargs="*")] = (),
        requirements: xcli.Annotated[tp.Sequence[str],
                                     xcli.Arg(action="append")] = (),
        link_project_dir=False,
        prompt: "str|None" = None,
    ):
        """Create a virtual environment in $VIRTUALENV_HOME with python3's ``venv``.

        Parameters
        ----------
        name : str
            Virtual environment name
        interpreter: -p, --interpreter
            Python interpreter used to create the virtual environment.
            Can be configured via the $VOX_DEFAULT_INTERPRETER environment variable.
        system_site_packages : --system-site-packages, --ssp
            If True, the system (global) site-packages dir is available to
            created environments.
        symlinks : --copies
            Try to use copies rather than symlinks.
        without_pip : --without-pip, --wp
            Skips installing or upgrading pip in the virtual environment
        activate : -a, --activate
            Activate the newly created virtual environment.
        temporary: -t, --temp
            Create the virtualenv under a temporary directory.
        packages: -i, --install
            Install one or more packages (by repeating the option) after the environment is created using pip
        requirements: -r, --requirements
            The argument value is passed to ``pip -r`` to be installed.
        link_project_dir: -l, --link, --link-project
            Associate the current directory with the new environment.
        prompt: --prompt
            Provides an alternative prompt prefix for this environment.
        """

        self.out("Creating environment...")

        if temporary:
            path = tempfile.mkdtemp(prefix=f"vox-env-{name}")
            name = os.path.join(path, name)

        self.vox.create(
            name,
            system_site_packages=system_site_packages,
            symlinks=symlinks,
            with_pip=(not without_pip),
            interpreter=interpreter,
            prompt=prompt,
        )
        if link_project_dir:
            self.project_set(name)

        if packages:
            self.runin(name, ["pip", "install", *packages])

        if requirements:

            def _generate_args():
                for req in requirements:
                    yield "-r"
                    yield req

            self.runin(name, ["pip", "install"] + list(_generate_args()))

        if activate:
            self.activate(name)
            self.out(f"Environment {name!r} created and activated.\n")
        else:
            self.out(
                f'Environment {name!r} created. Activate it with "vox activate {name}".\n'
            )
Ejemplo n.º 11
0
    yield from envs

    paths, _ = complete_dir(command)
    yield from paths


def py_interpreter_path_completer(xsh, **_):
    for _, (path, is_alias) in xsh.commands_cache.all_commands.items():
        if not is_alias and ("/python" in path or "/pypy" in path):
            yield path


_venv_option = xcli.Annotated[
    tp.Optional[str],
    xcli.Arg(metavar="ENV", nargs="?", completer=venv_names_completer), ]


class VoxHandler(xcli.ArgParserAlias):
    """Vox is a virtual environment manager for xonsh."""
    def build(self):
        """lazily called during dispatch"""
        self.vox = voxapi.Vox()
        parser = self.create_parser(prog="vox")

        parser.add_command(self.new, aliases=["create"])
        parser.add_command(self.activate, aliases=["workon", "enter"])
        parser.add_command(self.deactivate, aliases=["exit"])
        parser.add_command(self.list, aliases=["ls"])
        parser.add_command(self.remove, aliases=["rm", "delete", "del"])
        parser.add_command(self.info)
Ejemplo n.º 12
0
    def show(
        self,
        session: xcli.Annotated[
            str, xcli.Arg(nargs="?", choices=tuple(_XH_HISTORY_SESSIONS)
                          )] = "session",
        slices: xcli.Annotated[tp.List[int], xcli.Arg(nargs="*")] = None,
        datetime_format: tp.Optional[str] = None,
        start_time: tp.Optional[str] = None,
        end_time: tp.Optional[str] = None,
        location: tp.Optional[str] = None,
        reverse=False,
        numerate=False,
        timestamp=False,
        null_byte=False,
        _stdout=None,
        _stderr=None,
        _unparsed=None,
    ):
        """Display history of a session, default command

        Parameters
        ----------
        session:
            The history session to get. (all is an alias for xonsh)
        slices:
            integer or slice notation to get only portions of history.
        datetime_format : -f
            the datetime format to be used for filtering and printing
        start_time: --start-time, +T
            show only commands after timestamp
        end_time: -T, --end-time
            show only commands before timestamp
        location: -l, --location
            The history file location (bash or zsh)
        reverse: -r, --reverse
            Reverses the direction
        numerate: -n, --numerate
            Numerate each command
        timestamp: -t, --ts, --time-stamp
            show command timestamps
        null_byte: -0, --nb, --null-byte
            separate commands by the null character for piping history to external filters
        _unparsed
            remaining args from ``parser.parse_known_args``
        """
        slices = list(slices or ())
        if _unparsed:
            slices.extend(_unparsed)
        try:
            commands = _xh_get_history(
                session,
                slices=slices,
                start_time=start_time,
                end_time=end_time,
                datetime_format=datetime_format,
                location=location,
            )
        except Exception as err:
            self.parser.error(err)
            return

        if reverse:
            commands = reversed(list(commands))
        end = "\0" if null_byte else "\n"
        if numerate and timestamp:
            for c in commands:
                dt = datetime.datetime.fromtimestamp(c["ts"])
                print(
                    "{}:({}) {}".format(c["ind"], xt.format_datetime(dt),
                                        c["inp"]),
                    file=_stdout,
                    end=end,
                )
        elif numerate:
            for c in commands:
                print("{}: {}".format(c["ind"], c["inp"]),
                      file=_stdout,
                      end=end)
        elif timestamp:
            for c in commands:
                dt = datetime.datetime.fromtimestamp(c["ts"])
                print(
                    "({}) {}".format(xt.format_datetime(dt), c["inp"]),
                    file=_stdout,
                    end=end,
                )
        else:
            for c in commands:
                print(c["inp"], file=_stdout, end=end)
Ejemplo n.º 13
0
def _register_completer(
    name: str,
    func: xcli.Annotated[str,
                         xcli.Arg(completer=complete_func_name_choices)],
    pos: xcli.Annotated[str,
                        xcli.Arg(completer=complete_completer_pos_choices,
                                 nargs="?")] = "start",
    _stack=None,
):
    """Add a new completer to xonsh

    Parameters
    ----------
    name
        unique name to use in the listing (run "completer list" to see the
        current completers in order)

    func
        the name of a completer function to use.  This should be a function
         that takes a Completion Context object and marked with the
         ``xonsh.completers.tools.contextual_completer`` decorator.
         It should return a set of valid completions
         for the given prefix.  If this completer should not be used in a given
         context, it should return an empty set or None.

         For more information see https://xon.sh/tutorial_completers.html#writing-a-new-completer.

    pos
        position into the list of completers at which the new
        completer should be added.  It can be one of the following values:
        * "start" indicates that the completer should be added to the start of
                 the list of completers (it should be run before all other exclusive completers)
        * "end" indicates that the completer should be added to the end of the
               list of completers (it should be run after all others)
        * ">KEY", where KEY is a pre-existing name, indicates that this should
                 be added after the completer named KEY
        * "<KEY", where KEY is a pre-existing name, indicates that this should
                 be added before the completer named KEY
    """
    err = None
    func_name = func
    xsh = XSH
    if name in xsh.completers:
        err = f"The name {name} is already a registered completer function."
    else:
        if func_name in xsh.ctx:
            func = xsh.ctx[func_name]
            if not callable(func):
                err = f"{func_name} is not callable"
        else:
            for frame_info in _stack:
                frame = frame_info[0]
                if func_name in frame.f_locals:
                    func = frame.f_locals[func_name]
                    break
                elif func_name in frame.f_globals:
                    func = frame.f_globals[func_name]
                    break
            else:
                err = "No such function: %s" % func_name
    if err is None:
        _add_one_completer(name, func, pos)
    else:
        return None, err + "\n", 1