From 2c4b64ad1665e10ae484e449436b4f4ee1cf15ed Mon Sep 17 00:00:00 2001 From: Caleb Hattingh Date: Sat, 3 Aug 2019 12:11:22 +1000 Subject: [PATCH 01/10] vox activate - use absolute path in $PATH --- xontrib/voxapi.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xontrib/voxapi.py b/xontrib/voxapi.py index 348757a3e..7b274596d 100644 --- a/xontrib/voxapi.py +++ b/xontrib/voxapi.py @@ -358,7 +358,7 @@ class Vox(collections.abc.Mapping): self.deactivate() type(self).oldvars = {"PATH": list(env["PATH"])} - env["PATH"].insert(0, ve.bin) + env["PATH"].insert(0, os.path.abspath(ve.bin)) env["VIRTUAL_ENV"] = ve.env if "PYTHONHOME" in env: type(self).oldvars["PYTHONHOME"] = env.pop("PYTHONHOME") From ce6a86155849818227262653c6bc4b7d6af77713 Mon Sep 17 00:00:00 2001 From: Caleb Hattingh Date: Sat, 3 Aug 2019 12:32:02 +1000 Subject: [PATCH 02/10] Update news and AUTHORS --- AUTHORS.rst | 1 + news/vox-activate-absolute-path.rst | 3 +++ 2 files changed, 4 insertions(+) create mode 100644 news/vox-activate-absolute-path.rst diff --git a/AUTHORS.rst b/AUTHORS.rst index 6a98edc00..08d5f0e3f 100644 --- a/AUTHORS.rst +++ b/AUTHORS.rst @@ -202,5 +202,6 @@ Authors are sorted by number of commits. * Daniel Smith * goodboy * Atsushi Morimoto +* Caleb Hattingh diff --git a/news/vox-activate-absolute-path.rst b/news/vox-activate-absolute-path.rst new file mode 100644 index 000000000..c32b8add2 --- /dev/null +++ b/news/vox-activate-absolute-path.rst @@ -0,0 +1,3 @@ +**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. From 287eb5a9af72f3821cdc47ef2437e6fa17dd49c0 Mon Sep 17 00:00:00 2001 From: Caleb Hattingh Date: Sat, 3 Aug 2019 12:37:23 +1000 Subject: [PATCH 03/10] Fix news file to be valid *.rst --- news/vox-activate-absolute-path.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/news/vox-activate-absolute-path.rst b/news/vox-activate-absolute-path.rst index c32b8add2..3ebef8ddd 100644 --- a/news/vox-activate-absolute-path.rst +++ b/news/vox-activate-absolute-path.rst @@ -1,3 +1,3 @@ **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. +* ``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. From b89bada694cd7798699ba6bb50624bb30bbbe543 Mon Sep 17 00:00:00 2001 From: Caleb Hattingh Date: Sat, 3 Aug 2019 12:43:17 +1000 Subject: [PATCH 04/10] Trying to solve the test_news failure. --- news/vox-activate-absolute-path.rst | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/news/vox-activate-absolute-path.rst b/news/vox-activate-absolute-path.rst index 3ebef8ddd..e23334c14 100644 --- a/news/vox-activate-absolute-path.rst +++ b/news/vox-activate-absolute-path.rst @@ -1,3 +1,24 @@ +**Added:** + +* + **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:** + +* + +**Removed:** + +* + +**Fixed:** + +* + +**Security:** + +* + From 3e79a958c743ed9dea043e776163584daab37447 Mon Sep 17 00:00:00 2001 From: Caleb Hattingh Date: Sun, 4 Aug 2019 12:19:05 +1000 Subject: [PATCH 05/10] Add xontrib/ to coverage --- .coveragerc | 1 + 1 file changed, 1 insertion(+) diff --git a/.coveragerc b/.coveragerc index ad3d8fd04..8076ebd38 100644 --- a/.coveragerc +++ b/.coveragerc @@ -2,6 +2,7 @@ branch = true source = xonsh/ + xontrib/ omit = */__amalgam__.py xonsh/lazyasd.py From 16edba8fe8f8a07943cfc4c224b8c59b213da2c1 Mon Sep 17 00:00:00 2001 From: Caleb Hattingh Date: Sun, 4 Aug 2019 12:20:04 +1000 Subject: [PATCH 06/10] Apply abspath() to the env_dir, and add a test to verify. --- tests/test_vox.py | 44 +++++++++++++++++++++++++++++++++++++++++++- xontrib/voxapi.py | 4 ++-- 2 files changed, 45 insertions(+), 3 deletions(-) diff --git a/tests/test_vox.py b/tests/test_vox.py index 80ee59803..b74abfbac 100644 --- a/tests/test_vox.py +++ b/tests/test_vox.py @@ -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,47 @@ 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, **_): + nonlocal last_event + last_event = "activate", name + + @xonsh_builtins.events.vox_on_deactivate + def deactivate(name, **_): + nonlocal last_event + last_event = "deactivate", name + + 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) + + vox.deactivate() + assert not env["PATH"] + assert "VIRTUAL_ENV" not in env + assert last_event == ("deactivate", tmpdir.join(venv_dirname)) + + @skip_if_on_msys @skip_if_on_conda def test_path(xonsh_builtins, tmpdir): diff --git a/xontrib/voxapi.py b/xontrib/voxapi.py index 7b274596d..414a6c7fc 100644 --- a/xontrib/voxapi.py +++ b/xontrib/voxapi.py @@ -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") @@ -358,7 +358,7 @@ class Vox(collections.abc.Mapping): self.deactivate() type(self).oldvars = {"PATH": list(env["PATH"])} - env["PATH"].insert(0, os.path.abspath(ve.bin)) + env["PATH"].insert(0, ve.bin) env["VIRTUAL_ENV"] = ve.env if "PYTHONHOME" in env: type(self).oldvars["PYTHONHOME"] = env.pop("PYTHONHOME") From 220923f0844b0e9ed4f11ac9ec9447be5e9af9b7 Mon Sep 17 00:00:00 2001 From: Caleb Hattingh Date: Wed, 14 Aug 2019 17:50:06 +1000 Subject: [PATCH 07/10] Include path as a kwarg on activate and deactivate events --- tests/test_vox.py | 8 ++++---- xontrib/voxapi.py | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/test_vox.py b/tests/test_vox.py index b74abfbac..1f9bf0f51 100644 --- a/tests/test_vox.py +++ b/tests/test_vox.py @@ -95,12 +95,12 @@ def test_activate_non_vox_venv(xonsh_builtins, tmpdir): @xonsh_builtins.events.vox_on_activate def activate(name, **_): nonlocal last_event - last_event = "activate", name + last_event = "activate", name, _['path'] @xonsh_builtins.events.vox_on_deactivate def deactivate(name, **_): nonlocal last_event - last_event = "deactivate", name + last_event = "deactivate", name, _['path'] with tmpdir.as_cwd(): venv_dirname = 'venv' @@ -114,12 +114,12 @@ def test_activate_non_vox_venv(xonsh_builtins, tmpdir): assert env["PATH"][0] == vxv.bin assert os.path.isabs(vxv.env) assert env["VIRTUAL_ENV"] == vxv.env - assert last_event == ("activate", venv_dirname) + assert last_event == ("activate", venv_dirname, str(pathlib.Path(tmpdir) / 'venv')) vox.deactivate() assert not env["PATH"] assert "VIRTUAL_ENV" not in env - assert last_event == ("deactivate", tmpdir.join(venv_dirname)) + assert last_event == ("deactivate", tmpdir.join(venv_dirname), str(pathlib.Path(tmpdir) / 'venv')) @skip_if_on_msys diff --git a/xontrib/voxapi.py b/xontrib/voxapi.py index 414a6c7fc..d7d253ab5 100644 --- a/xontrib/voxapi.py +++ b/xontrib/voxapi.py @@ -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): From eb8971dc7befc80dd3ceb722e18689c293f6aabe Mon Sep 17 00:00:00 2001 From: Caleb Hattingh Date: Thu, 15 Aug 2019 23:23:09 +1000 Subject: [PATCH 08/10] Make the new path parameter explicit in the tests. --- tests/test_vox.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/test_vox.py b/tests/test_vox.py index 1f9bf0f51..14542448a 100644 --- a/tests/test_vox.py +++ b/tests/test_vox.py @@ -93,14 +93,14 @@ def test_activate_non_vox_venv(xonsh_builtins, tmpdir): last_event = None @xonsh_builtins.events.vox_on_activate - def activate(name, **_): + def activate(name, path, **_): nonlocal last_event - last_event = "activate", name, _['path'] + last_event = "activate", name, path @xonsh_builtins.events.vox_on_deactivate - def deactivate(name, **_): + def deactivate(name, path, **_): nonlocal last_event - last_event = "deactivate", name, _['path'] + last_event = "deactivate", name, path with tmpdir.as_cwd(): venv_dirname = 'venv' From b4b5d262c7d3bdbff0e1975bc6f528e3e75f70ba Mon Sep 17 00:00:00 2001 From: Caleb Hattingh Date: Thu, 15 Aug 2019 23:23:26 +1000 Subject: [PATCH 09/10] Add the new path parameter to the documentation. --- xontrib/voxapi.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/xontrib/voxapi.py b/xontrib/voxapi.py index d7d253ab5..920e7bef6 100644 --- a/xontrib/voxapi.py +++ b/xontrib/voxapi.py @@ -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. """, From 3b8d8472cbbbe145e658e2f398ffea9b547690b8 Mon Sep 17 00:00:00 2001 From: Caleb Hattingh Date: Fri, 16 Aug 2019 20:33:51 +1000 Subject: [PATCH 10/10] Trying to fix CI failure on Windows Python 3.5 --- tests/test_vox.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/tests/test_vox.py b/tests/test_vox.py index 14542448a..9d84f390b 100644 --- a/tests/test_vox.py +++ b/tests/test_vox.py @@ -114,12 +114,20 @@ def test_activate_non_vox_venv(xonsh_builtins, tmpdir): 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(tmpdir) / 'venv')) + 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(tmpdir) / 'venv')) + assert last_event == ( + "deactivate", + tmpdir.join(venv_dirname), + str(pathlib.Path(str(tmpdir)) / 'venv') + ) @skip_if_on_msys