Merge pull request #3251 from cjrh/vox-activate-absolute-path

vox activate: use absolute path in $PATH
This commit is contained in:
Anthony Scopatz 2019-08-25 13:21:16 -04:00 committed by GitHub
commit dd16d59d86
Failed to generate hash of commit
5 changed files with 84 additions and 8 deletions

View file

@ -2,6 +2,7 @@
branch = true
source =
xonsh/
xontrib/
omit =
*/__amalgam__.py
xonsh/lazyasd.py

View file

@ -207,5 +207,6 @@ Authors are sorted by number of commits.
* chengxuncc
* goodboy
* Atsushi Morimoto
* Caleb Hattingh

View file

@ -0,0 +1,24 @@
**Added:**
* <news item>
**Changed:**
* ``vox activate`` will now prepend the absolute path of the virtualenv ``bin/`` directory (or ``Scripts/`` on Windows) to ``$PATH``; before this was a relative path.
**Deprecated:**
* <news item>
**Removed:**
* <news item>
**Fixed:**
* <news item>
**Security:**
* <news item>

View file

@ -1,9 +1,10 @@
"""Vox tests"""
import builtins
import stat
import os
import subprocess as sp
import pytest
import sys
from xontrib.voxapi import Vox
from tools import skip_if_on_conda, skip_if_on_msys
@ -80,6 +81,55 @@ def test_activate(xonsh_builtins, tmpdir):
assert last_event == ("deactivate", "spam")
@skip_if_on_msys
@skip_if_on_conda
def test_activate_non_vox_venv(xonsh_builtins, tmpdir):
"""
Create a virtual environment using Python's built-in venv module
(not in VIRTUALENV_HOME) and verify that vox can activate it correctly.
"""
xonsh_builtins.__xonsh__.env.setdefault("PATH", [])
last_event = None
@xonsh_builtins.events.vox_on_activate
def activate(name, path, **_):
nonlocal last_event
last_event = "activate", name, path
@xonsh_builtins.events.vox_on_deactivate
def deactivate(name, path, **_):
nonlocal last_event
last_event = "deactivate", name, path
with tmpdir.as_cwd():
venv_dirname = 'venv'
sp.run([sys.executable, '-m', 'venv', venv_dirname])
vox = Vox()
vox.activate(venv_dirname)
vxv = vox[venv_dirname]
env = xonsh_builtins.__xonsh__.env
assert os.path.isabs(vxv.bin)
assert env["PATH"][0] == vxv.bin
assert os.path.isabs(vxv.env)
assert env["VIRTUAL_ENV"] == vxv.env
assert last_event == (
"activate",
venv_dirname,
str(pathlib.Path(str(tmpdir)) / 'venv')
)
vox.deactivate()
assert not env["PATH"]
assert "VIRTUAL_ENV" not in env
assert last_event == (
"deactivate",
tmpdir.join(venv_dirname),
str(pathlib.Path(str(tmpdir)) / 'venv')
)
@skip_if_on_msys
@skip_if_on_conda
def test_path(xonsh_builtins, tmpdir):

View file

@ -4,8 +4,8 @@ API for Vox, the Python virtual environment manager for xonsh.
Vox defines several events related to the life cycle of virtual environments:
* ``vox_on_create(env: str) -> None``
* ``vox_on_activate(env: str) -> None``
* ``vox_on_deactivate(env: str) -> None``
* ``vox_on_activate(env: str, path: pathlib.Path) -> None``
* ``vox_on_deactivate(env: str, path: pathlib.Path) -> None``
* ``vox_on_delete(env: str) -> None``
"""
import os
@ -37,7 +37,7 @@ Fired after an environment is created.
events.doc(
"vox_on_activate",
"""
vox_on_activate(env: str) -> None
vox_on_activate(env: str, path: pathlib.Path) -> None
Fired after an environment is activated.
""",
@ -46,7 +46,7 @@ Fired after an environment is activated.
events.doc(
"vox_on_deactivate",
"""
vox_on_deactivate(env: str) -> None
vox_on_deactivate(env: str, path: pathlib.Path) -> None
Fired after an environment is deactivated.
""",
@ -88,7 +88,7 @@ def _mkvenv(env_dir):
This only cares about the platform. No filesystem calls are made.
"""
env_dir = os.path.normpath(env_dir)
env_dir = os.path.abspath(env_dir)
if ON_WINDOWS:
binname = os.path.join(env_dir, "Scripts")
incpath = os.path.join(env_dir, "Include")
@ -363,7 +363,7 @@ class Vox(collections.abc.Mapping):
if "PYTHONHOME" in env:
type(self).oldvars["PYTHONHOME"] = env.pop("PYTHONHOME")
events.vox_on_activate.fire(name=name)
events.vox_on_activate.fire(name=name, path=ve.env)
def deactivate(self):
"""
@ -382,7 +382,7 @@ class Vox(collections.abc.Mapping):
env.pop("VIRTUAL_ENV")
events.vox_on_deactivate.fire(name=env_name)
events.vox_on_deactivate.fire(name=env_name, path=self[env_name].env)
return env_name
def __delitem__(self, name):