xonsh/xontrib/vox.py

232 lines
7 KiB
Python
Raw Normal View History

"""Python virtual environment manager for xonsh."""
2016-08-04 19:19:28 -04:00
import sys
2018-12-21 14:40:31 -08:00
import textwrap
2016-08-04 19:19:28 -04:00
import xontrib.voxapi as voxapi
import xonsh.lazyasd as lazyasd
2016-08-04 19:19:28 -04:00
__all__ = ()
2016-07-21 14:36:46 -04:00
2016-08-04 22:31:45 -04:00
2016-08-04 19:19:28 -04:00
class VoxHandler:
"""Vox is a virtual environment manager for xonsh."""
2016-07-21 13:54:58 -04:00
def parser():
from argparse import ArgumentParser
2019-04-26 11:11:11 -04:00
parser = ArgumentParser(prog="vox", description=__doc__)
subparsers = parser.add_subparsers(dest="command")
2016-07-21 13:54:58 -04:00
create = subparsers.add_parser(
2019-04-26 11:11:11 -04:00
"new",
aliases=["create"],
help="Create a new virtual environment in $VIRTUALENV_HOME",
2018-07-15 17:26:22 -05:00
)
2019-04-26 11:11:11 -04:00
create.add_argument("name", metavar="ENV", help="The environments to create")
2016-07-21 13:54:58 -04:00
2019-04-26 11:11:11 -04:00
create.add_argument(
"--system-site-packages",
default=False,
action="store_true",
dest="system_site_packages",
help="Give the virtual environment access to the "
"system site-packages dir.",
)
2016-07-21 13:54:58 -04:00
2018-12-20 20:36:41 -08:00
create.add_argument(
"-p",
"--interpreter",
2018-12-21 14:40:31 -08:00
default=None,
help=textwrap.dedent(
"""
2018-12-21 18:39:26 -08:00
The Python interpreter used to create the virtual environment.
2018-12-21 14:40:31 -08:00
Can be configured via the $VOX_DEFAULT_INTERPRETER environment variable.
"""
).strip(),
2018-12-20 20:36:41 -08:00
)
2016-07-21 13:54:58 -04:00
from xonsh.platform import ON_WINDOWS
2019-04-26 11:11:11 -04:00
2016-07-21 13:54:58 -04:00
group = create.add_mutually_exclusive_group()
2019-04-26 11:11:11 -04:00
group.add_argument(
"--symlinks",
default=not ON_WINDOWS,
action="store_true",
dest="symlinks",
help="Try to use symlinks rather than copies, "
"when symlinks are not the default for "
"the platform.",
)
group.add_argument(
"--copies",
default=ON_WINDOWS,
action="store_false",
dest="symlinks",
help="Try to use copies rather than symlinks, "
"even when symlinks are the default for "
"the platform.",
)
create.add_argument(
"--without-pip",
dest="with_pip",
default=True,
action="store_false",
help="Skips installing or upgrading pip in the "
"virtual environment (pip is bootstrapped "
"by default)",
)
2016-07-21 13:54:58 -04:00
activate = subparsers.add_parser(
2019-04-26 11:11:11 -04:00
"activate", aliases=["workon", "enter"], help="Activate virtual environment"
)
activate.add_argument(
"name",
metavar="ENV",
help=(
"The environment to activate. ENV can be "
"either a name from the venvs shown by vox"
"list or the path to an arbitrary venv"
),
)
subparsers.add_parser(
"deactivate",
aliases=["exit"],
help="Deactivate current virtual environment",
)
subparsers.add_parser(
"list",
aliases=["ls"],
help=("List environments available in " "$VIRTUALENV_HOME"),
)
remove = subparsers.add_parser(
"remove", aliases=["rm", "delete", "del"], help="Remove virtual environment"
)
remove.add_argument(
"names",
metavar="ENV",
nargs="+",
help=(
"The environments to remove. ENV can be "
"either a name from the venvs shown by vox"
"list or the path to an arbitrary venv"
),
2018-07-15 17:26:22 -05:00
)
2019-04-26 11:11:11 -04:00
subparsers.add_parser("help", help="Show this help message")
return parser
2019-04-26 11:11:11 -04:00
parser = lazyasd.LazyObject(parser, locals(), "parser")
2016-07-21 00:36:35 -04:00
aliases = {
2019-04-26 11:11:11 -04:00
"create": "new",
"workon": "activate",
"enter": "activate",
"exit": "deactivate",
"ls": "list",
"rm": "remove",
"delete": "remove",
"del": "remove",
2016-07-21 00:36:35 -04:00
}
def __init__(self):
2016-08-04 19:19:28 -04:00
self.vox = voxapi.Vox()
def __call__(self, args, stdin=None):
"""Call the right handler method for a given command."""
args = self.parser.parse_args(args)
2016-07-21 00:36:35 -04:00
cmd = self.aliases.get(args.command, args.command)
if cmd is None:
self.parser.print_usage()
else:
2019-04-26 11:11:11 -04:00
getattr(self, "cmd_" + cmd)(args, stdin)
def cmd_new(self, args, stdin=None):
2016-02-12 16:17:15 +03:00
"""Create a virtual environment in $VIRTUALENV_HOME with python3's ``venv``.
"""
print("Creating environment...")
self.vox.create(
args.name,
system_site_packages=args.system_site_packages,
symlinks=args.symlinks,
with_pip=args.with_pip,
interpreter=args.interpreter,
)
2016-06-15 20:53:13 -04:00
msg = 'Environment {0!r} created. Activate it with "vox activate {0}".\n'
print(msg.format(args.name))
def cmd_activate(self, args, stdin=None):
"""Activate a virtual environment.
"""
2016-07-20 15:02:56 -04:00
try:
self.vox.activate(args.name)
2016-07-20 15:02:56 -04:00
except KeyError:
2019-04-26 11:11:11 -04:00
print(
'This environment doesn\'t exist. Create it with "vox new %s".\n'
% args.name,
file=sys.stderr,
)
return None
else:
print('Activated "%s".\n' % args.name)
def cmd_deactivate(self, args, stdin=None):
"""Deactivate the active virtual environment."""
2016-07-20 15:02:56 -04:00
if self.vox.active() is None:
2019-04-26 11:11:11 -04:00
print(
'No environment currently active. Activate one with "vox activate".\n',
file=sys.stderr,
)
return None
2016-07-20 15:02:56 -04:00
env_name = self.vox.deactivate()
print('Deactivated "%s".\n' % env_name)
def cmd_list(self, args, stdin=None):
"""List available virtual environments."""
try:
envs = sorted(self.vox.keys())
except PermissionError:
2019-04-26 11:11:11 -04:00
print("No permissions on VIRTUALENV_HOME")
return None
2016-07-20 15:02:56 -04:00
if not envs:
2019-04-26 11:11:11 -04:00
print(
'No environments available. Create one with "vox new".\n',
file=sys.stderr,
)
return None
2019-04-26 11:11:11 -04:00
print("Available environments:")
print("\n".join(envs))
def cmd_remove(self, args, stdin=None):
"""Remove virtual environments.
"""
2016-07-21 00:36:35 -04:00
for name in args.names:
2016-07-20 15:02:56 -04:00
try:
2016-07-21 00:36:35 -04:00
del self.vox[name]
2016-08-04 19:19:28 -04:00
except voxapi.EnvironmentInUse:
2019-04-26 11:11:11 -04:00
print(
'The "%s" environment is currently active. In order to remove it, deactivate it first with "vox deactivate %s".\n'
% (name, name),
file=sys.stderr,
)
return
2016-07-20 15:02:56 -04:00
else:
print('Environment "%s" removed.' % name)
print()
def cmd_help(self, args, stdin=None):
self.parser.print_help()
@classmethod
def handle(cls, args, stdin=None):
"""Runs Vox environment manager."""
vox = cls()
return vox(args, stdin=stdin)
2016-07-20 15:45:14 -04:00
2019-04-26 11:11:11 -04:00
aliases["vox"] = VoxHandler.handle