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 invalid fish-shell script generation with a python virtualenv #212

Merged
merged 2 commits into from
Jun 13, 2018
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
32 changes: 23 additions & 9 deletions nodeenv.py
Original file line number Diff line number Diff line change
Expand Up @@ -412,11 +412,7 @@ def writefile(dest, content, overwrite=True, append=False):
if append:
logger.info(' * Appending data to %s', dest)
with open(dest, 'ab') as f:
if not is_WIN:
f.write(DISABLE_PROMPT.encode('utf-8'))
f.write(content)
if not is_WIN:
f.write(ENABLE_PROMPT.encode('utf-8'))
return

logger.info(' * Overwriting %s with new content', dest)
Expand Down Expand Up @@ -869,7 +865,12 @@ def install_activate(env_dir, opt):
# we should get `bin/node` not as binary+string.
# `bin/activate` should be appended if we inside
# existing python's virtual environment
need_append = 0 if name in ('node', 'shim') else opt.python_virtualenv
need_append = False
if opt.python_virtualenv:
disable_prompt = DISABLE_PROMPT.get(name, '')
enable_prompt = ENABLE_PROMPT.get(name, '')
content = disable_prompt + content + enable_prompt
need_append = bool(disable_prompt)
writefile(file_path, content, append=need_append)

if not os.path.exists(shim_nodejs):
Expand Down Expand Up @@ -1077,16 +1078,29 @@ def main():
# ---------------------------------------------------------
# Shell scripts content

DISABLE_PROMPT = """
DISABLE_PROMPT = {
'activate': """
# disable nodeenv's prompt
# (prompt already changed by original virtualenv's script)
# https://github.com/ekalinin/nodeenv/issues/26
NODE_VIRTUAL_ENV_DISABLE_PROMPT=1
"""
""",
'activate.fish': """
# disable nodeenv's prompt
# (prompt already changed by original virtualenv's script)
# https://github.com/ekalinin/nodeenv/issues/26
set NODE_VIRTUAL_ENV_DISABLE_PROMPT 1
""",
}

ENABLE_PROMPT = """
ENABLE_PROMPT = {
'activate': """
unset NODE_VIRTUAL_ENV_DISABLE_PROMPT
"""
""",
'activate.fish': """
set -e NODE_VIRTUAL_ENV_DISABLE_PROMPT
""",
}

SHIM = """#!/usr/bin/env bash
export NODE_PATH=__NODE_VIRTUAL_ENV__/lib/node_modules
Expand Down
84 changes: 84 additions & 0 deletions tests/test_install_activate.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import sys
import os

import mock
import pytest

import nodeenv

if nodeenv.is_WIN:
FILES = {
'activate.bat': 'ACTIVATE_BAT',
"deactivate.bat": 'DEACTIVATE_BAT',
"Activate.ps1": 'ACTIVATE_PS1',
}
else:
FILES = {
'activate': 'ACTIVATE_SH',
'activate.fish': 'ACTIVATE_FISH',
'shim': 'SHIM',
}


def fix_content(content, tmpdir):
if nodeenv.is_WIN:
bin_name = 'Scripts'
node_name = 'node.exe'
else:
bin_name = 'bin'
node_name = 'node'
tmpdir.join('Scripts').join('node.exe')

content = content.replace(
'__NODE_VIRTUAL_PROMPT__', '({})'.format(tmpdir.basename))
content = content.replace('__NODE_VIRTUAL_ENV__', str(tmpdir))
content = content.replace(
'__SHIM_NODE__', str(tmpdir.join(bin_name).join(node_name)))
content = content.replace('__BIN_NAME__', bin_name)
content = content.replace(
'__MOD_NAME__', os.path.join('lib', 'node_modules'))
content = content.replace('__NPM_CONFIG_PREFIX__', '$NODE_VIRTUAL_ENV')
return content


@pytest.mark.parametrize('name, content_var', FILES.items())
def test_write(tmpdir, name, content_var):
if nodeenv.is_WIN:
bin_dir = tmpdir.join('Scripts')
else:
bin_dir = tmpdir.join('bin')
bin_dir.mkdir()
for n in FILES:
bin_dir.join(n).write(n)

with mock.patch.object(sys, 'argv', ['nodeenv', str(tmpdir)]):
opts = nodeenv.parse_args()[0]
nodeenv.install_activate(str(tmpdir), opts)

content = getattr(nodeenv, content_var)
assert bin_dir.join(name).read() == fix_content(content, tmpdir)


@pytest.mark.parametrize('name, content_var', FILES.items())
def test_python_virtualenv(tmpdir, name, content_var):
if nodeenv.is_WIN:
bin_dir = tmpdir.join('Scripts')
else:
bin_dir = tmpdir.join('bin')
bin_dir.mkdir()
for n in FILES:
bin_dir.join(n).write(n)

with mock.patch.object(sys, 'argv', ['nodeenv', '-p']):
opts = nodeenv.parse_args()[0]
nodeenv.install_activate(str(tmpdir), opts)

content = getattr(nodeenv, content_var)
# If there's disable prompt content to be added, we're appending to
# the file so prepend the original content (and the wrapped
# disable/enable prompt content).
disable_prompt = nodeenv.DISABLE_PROMPT.get(name)
if disable_prompt:
enable_prompt = nodeenv.ENABLE_PROMPT.get(name, '')
content = name + disable_prompt + content + enable_prompt
assert bin_dir.join(name).read() == fix_content(content, tmpdir)