Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix virtualenv creation when WORKON_HOME lives within a symlink dir #145

Merged
merged 1 commit into from
Oct 1, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions pew/pew.py
Original file line number Diff line number Diff line change
Expand Up @@ -211,8 +211,10 @@ def mkvirtualenv(envname, python=None, packages=[], project=None,
if python:
rest = ["--python=%s" % python] + rest

path = (workon_home / envname).absolute()

try:
check_call(["virtualenv", envname] + rest, cwd=str(workon_home))
check_call(["virtualenv", str(path)] + rest)
except (CalledProcessError, KeyboardInterrupt):
rmvirtualenvs([envname])
raise
Expand Down Expand Up @@ -611,10 +613,11 @@ def restore_cmd(argv):
sys.exit('You must provide a valid virtualenv to target')

env = argv[0]
py = workon_home / env / env_bin_dir / ('python.exe' if windows else 'python')
path = workon_home / env
py = path / env_bin_dir / ('python.exe' if windows else 'python')
exact_py = py.resolve().name

check_call(["virtualenv", env, "--python=%s" % exact_py], cwd=str(workon_home))
check_call(["virtualenv", str(path.absolute()), "--python=%s" % exact_py])


def dir_cmd(argv):
Expand Down
28 changes: 28 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,34 @@ def workon_home():
rmtree(str(workon))


@pytest.yield_fixture()
def workon_sym_home():
# workon_home() fixture assumes it is the only one changing the environ
# so save it and restore it after the test
old_workon = os.environ.get('WORKON_HOME', '')

tmpdir = os.environ.get('TMPDIR', gettempdir())
tmpdir = Path(tmpdir) / 'pew-test-tmp'

# Create the real root and a symlink to it: SYM_ROOT -> REAL_ROOT
real_root = tmpdir / 'REAL_ROOT'
sym_root = tmpdir / 'SYM_ROOT'

real_home = real_root / 'WORKON_HOME'
real_home.mkdir(parents=True)

sym_root.symlink_to(real_root, target_is_directory=True)
sym_home = sym_root / 'WORKON_HOME'

# New WORKON_HOME lives in the symlinked root
os.environ['WORKON_HOME'] = str(sym_home)

workon = Path(os.environ['WORKON_HOME'])
yield workon
rmtree(str(tmpdir))
os.environ['WORKON_HOME'] = old_workon


@pytest.yield_fixture()
def env1(workon_home):
invoke('new', 'env1', '-d')
Expand Down
11 changes: 11 additions & 0 deletions tests/test_mkvirtualenv.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import pytest

from pew._utils import invoke_pew as invoke
from utils import skip_windows


def are_we_connected():
Expand All @@ -34,6 +35,16 @@ def test_create(workon_home):
assert envs < envs2


@skip_windows(reason="symlinks on windows are not well supported")
def test_create_in_symlink(workon_sym_home):
invoke('new', 'env', '-d')
pip_path = Path(invoke('in', 'env', 'which', 'pip').out)
with pip_path.open() as f:
pip_shebang = f.readline()
# check it is using the symlinked path, not the real path
assert str(workon_sym_home) in pip_shebang


def test_no_args(workon_home):
with pytest.raises(CalledProcessError):
check_call(['pew', 'new'])
Expand Down