mirror of
https://github.com/kennethreitz/pipenv.git
synced 2026-06-05 22:50:18 +00:00
Un-vendor Pew
This commit is contained in:
+4
-3
@@ -382,7 +382,7 @@ will detect it.
|
||||
- ``PIPENV_SHELL_FANCY`` — Always use fancy mode when invoking ``pipenv shell``.
|
||||
|
||||
- ``PIPENV_VENV_IN_PROJECT`` — If set, use ``.venv`` in your project directory
|
||||
instead of the global virtualenv manager ``pew``.
|
||||
instead of a global location.
|
||||
|
||||
- ``PIPENV_COLORBLIND`` — Disable terminal colors, for some reason.
|
||||
|
||||
@@ -424,8 +424,9 @@ For example::
|
||||
☤ Custom Virtual Environment Location
|
||||
-------------------------------------
|
||||
|
||||
Pipenv's underlying ``pew`` dependency will automatically honor the ``WORKON_HOME`` environment
|
||||
variable, if you have it set — so you can tell pipenv to store your virtual environments wherever you want, e.g.::
|
||||
Pipenv automatically honors the ``WORKON_HOME`` environment variable, if you
|
||||
have it set — so you can tell pipenv to store your virtual environments
|
||||
wherever you want, e.g.::
|
||||
|
||||
export WORKON_HOME=~/.venvs
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@ imagesize==0.7.1
|
||||
Jinja2==2.9.6
|
||||
MarkupSafe==1.0
|
||||
pbr==3.1.1
|
||||
pew==0.1.26
|
||||
pip-tools==1.9.0
|
||||
-e .
|
||||
Pygments==2.2.0
|
||||
|
||||
+1
-1
@@ -454,7 +454,7 @@ def ensure_python(three=None, python=None):
|
||||
if (not PIPENV_DONT_USE_PYENV) and (SESSION_IS_INTERACTIVE or PIPENV_YES):
|
||||
version_map = {
|
||||
# TODO: Keep this up to date!
|
||||
# These versions appear incompatible with pew:
|
||||
# These versions appear incompatible with virtualenv:
|
||||
# '2.5': '2.5.6',
|
||||
"2.6": "2.6.9",
|
||||
"2.7": "2.7.15",
|
||||
|
||||
@@ -11,7 +11,7 @@ os.environ.pop("__PYVENV_LAUNCHER__", None)
|
||||
PIPENV_SHELL_FANCY = bool(os.environ.get("PIPENV_SHELL_FANCY"))
|
||||
# Support for both Python 2 and Python 3 at the same time.
|
||||
PIPENV_PYTHON = os.environ.get("PIPENV_PYTHON")
|
||||
# Create the virtualenv in the project, instead of with pew.
|
||||
# Create the virtualenv in the project, instead of in WORKON_HOME.
|
||||
PIPENV_VENV_IN_PROJECT = bool(os.environ.get("PIPENV_VENV_IN_PROJECT"))
|
||||
# Overwrite all index funcitonality.
|
||||
PIPENV_TEST_INDEX = os.environ.get("PIPENV_TEST_INDEX")
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
safety
|
||||
git+https://github.com/jumpscale7/python-consistent-toml.git#egg=contoml
|
||||
crayons==0.1.2
|
||||
git+https://github.com/berdario/pew.git@1.1.5#egg=pew
|
||||
pipfile==0.0.2
|
||||
git+https://github.com/jazzband/pip-tools.git@9cb41d828fcb0967a32cc140c1dcaca94e5f4daa#egg=piptools
|
||||
prettytoml==0.3
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
@@ -1,4 +0,0 @@
|
||||
from __future__ import absolute_import
|
||||
|
||||
from . import pew
|
||||
__all__ = ['pew']
|
||||
@@ -1,4 +0,0 @@
|
||||
from . import pew
|
||||
|
||||
if __name__ == '__main__':
|
||||
pew.pew.pew()
|
||||
@@ -1,58 +0,0 @@
|
||||
from __future__ import division, print_function
|
||||
|
||||
import os
|
||||
from functools import partial
|
||||
from math import ceil
|
||||
try:
|
||||
from itertools import zip_longest
|
||||
except ImportError:
|
||||
from itertools import izip_longest as zip_longest
|
||||
try:
|
||||
from shutil import get_terminal_size
|
||||
except ImportError:
|
||||
from pipenv.vendor.backports.shutil_get_terminal_size import get_terminal_size
|
||||
|
||||
SEP = ' '
|
||||
L = len(SEP)
|
||||
|
||||
|
||||
def get_rows(venvs, columns_number):
|
||||
lines_number = int(ceil(len(venvs) / columns_number))
|
||||
for i in range(lines_number):
|
||||
yield venvs[i::lines_number]
|
||||
|
||||
|
||||
def row_len(names):
|
||||
return sum(map(len, names)) + L * len(names) - L
|
||||
|
||||
|
||||
def get_best_columns_number(venvs):
|
||||
max_width, _ = get_terminal_size()
|
||||
longest = partial(max, key=len)
|
||||
columns_number = 1
|
||||
for columns_number in range(1, len(venvs) + 1):
|
||||
rows = get_rows(venvs, columns_number)
|
||||
longest_row = list(map(longest, zip_longest(*rows, fillvalue='')))
|
||||
if row_len(longest_row) > max_width:
|
||||
return (columns_number - 1) or 1
|
||||
else:
|
||||
return columns_number
|
||||
|
||||
|
||||
def align_column(column):
|
||||
m = max(map(len, column))
|
||||
return [name.ljust(m) for name in column]
|
||||
|
||||
|
||||
def columnize(venvs):
|
||||
columns_n = get_best_columns_number(venvs)
|
||||
columns = map(align_column, zip_longest(*get_rows(venvs, columns_n), fillvalue=''))
|
||||
return map(SEP.join, zip(*columns))
|
||||
|
||||
|
||||
def print_virtualenvs(*venvs):
|
||||
venvs = sorted(venvs)
|
||||
if os.isatty(1):
|
||||
print(*columnize(venvs), sep='\n')
|
||||
else:
|
||||
print(*venvs, sep=' ')
|
||||
@@ -1,92 +0,0 @@
|
||||
import os
|
||||
import sys
|
||||
import locale
|
||||
from codecs import getwriter
|
||||
from contextlib import contextmanager
|
||||
from subprocess import check_call, Popen, PIPE
|
||||
from collections import namedtuple
|
||||
from functools import partial, wraps
|
||||
try:
|
||||
from pathlib import Path
|
||||
except ImportError:
|
||||
from pipenv.vendor.pathlib2 import Path
|
||||
from tempfile import NamedTemporaryFile as _ntf
|
||||
try:
|
||||
from shutil import which
|
||||
except ImportError:
|
||||
from shutilwhich import which
|
||||
|
||||
py2 = sys.version_info[0] == 2
|
||||
windows = sys.platform == 'win32'
|
||||
|
||||
if py2 or windows:
|
||||
locale.setlocale(locale.LC_CTYPE, '')
|
||||
|
||||
encoding = locale.getlocale()[1] or 'ascii'
|
||||
|
||||
if py2:
|
||||
@wraps(_ntf)
|
||||
def NamedTemporaryFile(mode):
|
||||
return getwriter(encoding)(_ntf(mode))
|
||||
|
||||
def to_unicode(x):
|
||||
return x.decode(encoding)
|
||||
else:
|
||||
NamedTemporaryFile = _ntf
|
||||
to_unicode = str
|
||||
|
||||
def check_path():
|
||||
parent = os.path.dirname
|
||||
return parent(parent(which('python'))) == os.environ['VIRTUAL_ENV']
|
||||
|
||||
|
||||
def resolve_path(f):
|
||||
def call(cmd, **kwargs):
|
||||
ex = cmd[0]
|
||||
ex = which(ex) or ex
|
||||
return f([ex] + list(cmd[1:]), **kwargs) # list-conversion is required in case `cmd` is a tuple
|
||||
return call
|
||||
|
||||
if windows:
|
||||
check_call = resolve_path(check_call)
|
||||
Popen = resolve_path(Popen)
|
||||
|
||||
Result = namedtuple('Result', 'returncode out err')
|
||||
|
||||
|
||||
# TODO: it's better to fail early, and thus I'd need to check the exit code, but it'll
|
||||
# need a refactoring of a couple of tests
|
||||
def invoke(*args, **kwargs):
|
||||
inp = kwargs.pop('inp', '').encode(encoding)
|
||||
popen = Popen(args, stdin=PIPE, stdout=PIPE, stderr=PIPE, **kwargs)
|
||||
out, err = [o.strip().decode(encoding) for o in popen.communicate(inp)]
|
||||
return Result(popen.returncode, out, err)
|
||||
|
||||
|
||||
invoke_pew = partial(invoke, 'pew')
|
||||
|
||||
env_bin_dir = 'bin' if sys.platform != 'win32' else 'Scripts'
|
||||
|
||||
|
||||
def expandpath(path):
|
||||
return Path(os.path.expanduser(os.path.expandvars(path)))
|
||||
|
||||
|
||||
def own(path):
|
||||
if sys.platform == 'win32':
|
||||
# Even if run by an administrator, the permissions will be set
|
||||
# correctly on Windows, no need to check
|
||||
return True
|
||||
while not path.exists():
|
||||
path = path.parent
|
||||
return path.stat().st_uid == os.getuid()
|
||||
|
||||
|
||||
@contextmanager
|
||||
def temp_environ():
|
||||
environ = dict(os.environ)
|
||||
try:
|
||||
yield
|
||||
finally:
|
||||
os.environ.clear()
|
||||
os.environ.update(environ)
|
||||
@@ -1,121 +0,0 @@
|
||||
# -*- coding=utf-8 -*-
|
||||
# psutil is painfully slow in win32. So to avoid adding big
|
||||
# dependencies like pywin32 a ctypes based solution is preferred
|
||||
|
||||
# Code based on the winappdbg project http://winappdbg.sourceforge.net/
|
||||
# (BSD License) - adapted from Celery
|
||||
# https://github.com/celery/celery/blob/2.5-archived/celery/concurrency/processes/_win.py
|
||||
import os
|
||||
import six
|
||||
from ctypes import (
|
||||
byref, sizeof, windll, Structure, WinError, POINTER,
|
||||
c_size_t, c_char, c_void_p
|
||||
)
|
||||
from ctypes.wintypes import DWORD, LONG
|
||||
|
||||
ERROR_NO_MORE_FILES = 18
|
||||
INVALID_HANDLE_VALUE = c_void_p(-1).value
|
||||
SHELL_NAMES = ['cmd', 'powershell', 'pwsh', 'cmder']
|
||||
|
||||
|
||||
class PROCESSENTRY32(Structure):
|
||||
_fields_ = [
|
||||
('dwSize', DWORD),
|
||||
('cntUsage', DWORD),
|
||||
('th32ProcessID', DWORD),
|
||||
('th32DefaultHeapID', c_size_t),
|
||||
('th32ModuleID', DWORD),
|
||||
('cntThreads', DWORD),
|
||||
('th32ParentProcessID', DWORD),
|
||||
('pcPriClassBase', LONG),
|
||||
('dwFlags', DWORD),
|
||||
('szExeFile', c_char * 260),
|
||||
]
|
||||
|
||||
|
||||
LPPROCESSENTRY32 = POINTER(PROCESSENTRY32)
|
||||
|
||||
|
||||
def CreateToolhelp32Snapshot(dwFlags=2, th32ProcessID=0):
|
||||
hSnapshot = windll.kernel32.CreateToolhelp32Snapshot(
|
||||
dwFlags,
|
||||
th32ProcessID
|
||||
)
|
||||
if hSnapshot == INVALID_HANDLE_VALUE:
|
||||
raise WinError()
|
||||
return hSnapshot
|
||||
|
||||
|
||||
def Process32First(hSnapshot):
|
||||
pe = PROCESSENTRY32()
|
||||
pe.dwSize = sizeof(PROCESSENTRY32)
|
||||
success = windll.kernel32.Process32First(hSnapshot, byref(pe))
|
||||
if not success:
|
||||
if windll.kernel32.GetLastError() == ERROR_NO_MORE_FILES:
|
||||
return
|
||||
raise WinError()
|
||||
return pe
|
||||
|
||||
|
||||
def Process32Next(hSnapshot, pe=None):
|
||||
if pe is None:
|
||||
pe = PROCESSENTRY32()
|
||||
pe.dwSize = sizeof(PROCESSENTRY32)
|
||||
success = windll.kernel32.Process32Next(hSnapshot, byref(pe))
|
||||
if not success:
|
||||
if windll.kernel32.GetLastError() == ERROR_NO_MORE_FILES:
|
||||
return
|
||||
raise WinError()
|
||||
return pe
|
||||
|
||||
|
||||
def get_all_processes():
|
||||
"""Return a dictionary of properties about all processes.
|
||||
|
||||
>>> get_all_processes()
|
||||
{
|
||||
1509: {
|
||||
'parent_pid': 1201,
|
||||
'executable': 'C:\\Program\\\\ Files\\Python36\\python.exe'
|
||||
}
|
||||
}
|
||||
"""
|
||||
h_process = CreateToolhelp32Snapshot()
|
||||
pids = {}
|
||||
pe = Process32First(h_process)
|
||||
while pe:
|
||||
pids[pe.th32ProcessID] = {
|
||||
'executable': str(pe.szExeFile.decode('utf-8'))
|
||||
}
|
||||
if pe.th32ParentProcessID:
|
||||
pids[pe.th32ProcessID]['parent_pid'] = pe.th32ParentProcessID
|
||||
pe = Process32Next(h_process, pe)
|
||||
|
||||
return pids
|
||||
|
||||
|
||||
def _get_executable(process_dict):
|
||||
if hasattr(process_dict, 'keys'):
|
||||
executable = process_dict.get('executable')
|
||||
if isinstance(executable, six.string_types):
|
||||
return executable.lower().rsplit('.', 1)[0]
|
||||
return ''
|
||||
|
||||
|
||||
def get_shell(pid=None, max_depth=6):
|
||||
"""Get the shell that the supplied pid or os.getpid() is running in.
|
||||
"""
|
||||
if not pid:
|
||||
pid = os.getpid()
|
||||
processes = get_all_processes()
|
||||
|
||||
def check_parent(pid, lvl=0):
|
||||
ppid = processes[pid].get('parent_pid')
|
||||
if ppid and _get_executable(processes.get(ppid)) in SHELL_NAMES:
|
||||
return processes[ppid]['executable']
|
||||
if lvl >= max_depth:
|
||||
return
|
||||
return check_parent(ppid, lvl=lvl+1)
|
||||
if _get_executable(processes.get(pid)) in SHELL_NAMES:
|
||||
return processes[pid]['executable']
|
||||
return check_parent(pid)
|
||||
@@ -1,786 +0,0 @@
|
||||
from __future__ import print_function, absolute_import, unicode_literals
|
||||
|
||||
import os
|
||||
import sys
|
||||
import argparse
|
||||
import shutil
|
||||
import random
|
||||
import textwrap
|
||||
from functools import partial
|
||||
from subprocess import CalledProcessError
|
||||
try:
|
||||
from pathlib import Path
|
||||
except ImportError:
|
||||
from pipenv.vendor.pathlib2 import Path
|
||||
|
||||
try:
|
||||
from shutil import get_terminal_size
|
||||
except ImportError:
|
||||
from pipenv.vendor.backports.shutil_get_terminal_size import get_terminal_size
|
||||
|
||||
windows = sys.platform == 'win32'
|
||||
|
||||
from clonevirtualenv import clone_virtualenv
|
||||
if not windows:
|
||||
try:
|
||||
# Try importing these packages if avaiable
|
||||
from pythonz.commands.install import InstallCommand
|
||||
from pythonz.commands.uninstall import UninstallCommand
|
||||
from pythonz.installer.pythoninstaller import PythonInstaller, AlreadyInstalledError
|
||||
from pythonz.commands.list import ListCommand as ListPythons
|
||||
from pythonz.define import PATH_PYTHONS
|
||||
from pythonz.commands.locate import LocateCommand as LocatePython
|
||||
except:
|
||||
# create mock commands
|
||||
InstallCommand = ListPythons = LocatePython = UninstallCommand = \
|
||||
lambda : sys.exit('You need to install the pythonz extra. pip install pew[pythonz]')
|
||||
else:
|
||||
# Pythonz does not support windows
|
||||
InstallCommand = ListPythons = LocatePython = UninstallCommand = \
|
||||
lambda : sys.exit('Command not supported on this platform')
|
||||
|
||||
from ._win_utils import get_shell
|
||||
|
||||
from pew._utils import (check_call, invoke, expandpath, own, env_bin_dir,
|
||||
check_path, temp_environ, NamedTemporaryFile, to_unicode)
|
||||
from pew._print_utils import print_virtualenvs
|
||||
|
||||
if sys.version_info[0] == 2:
|
||||
input = raw_input
|
||||
|
||||
err = partial(print, file=sys.stderr)
|
||||
|
||||
if windows:
|
||||
default_home = '~/.virtualenvs'
|
||||
else:
|
||||
default_home = os.path.join(
|
||||
os.environ.get('XDG_DATA_HOME', '~/.local/share'), 'virtualenvs')
|
||||
|
||||
def get_workon_home():
|
||||
return expandpath(os.environ.get('WORKON_HOME', default_home))
|
||||
|
||||
|
||||
def makedirs_and_symlink_if_needed(workon_home):
|
||||
if not workon_home.exists() and own(workon_home):
|
||||
workon_home.mkdir(parents=True)
|
||||
link = expandpath('~/.virtualenvs')
|
||||
if os.name == 'posix' and 'WORKON_HOME' not in os.environ and \
|
||||
'XDG_DATA_HOME' not in os.environ and not link.exists():
|
||||
link.symlink_to(str(workon_home))
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
pew_site = Path(__file__).parent
|
||||
|
||||
def supported_shell():
|
||||
shell = Path(os.environ.get('SHELL', '')).stem
|
||||
if shell in ('bash', 'zsh', 'fish'):
|
||||
return shell
|
||||
|
||||
|
||||
def shell_config_cmd(argv):
|
||||
"Prints the path for the current $SHELL helper file"
|
||||
shell = supported_shell()
|
||||
if shell:
|
||||
print(pew_site / 'shell_config' / ('init.' + shell))
|
||||
else:
|
||||
err('Completions and prompts are unavailable for %s' %
|
||||
repr(os.environ.get('SHELL', '')))
|
||||
|
||||
|
||||
def deploy_completions():
|
||||
completions = {'complete.bash': Path('/etc/bash_completion.d/pew'),
|
||||
'complete.zsh': Path('/usr/local/share/zsh/site-functions/_pew'),
|
||||
'complete.fish': Path('/etc/fish/completions/pew.fish')}
|
||||
for comp, dest in completions.items():
|
||||
if not dest.parent.exists():
|
||||
dest.parent.mkdir(parents=True)
|
||||
shutil.copy(str(pew_site / 'shell_config' / comp), str(dest))
|
||||
|
||||
|
||||
def get_project_dir(env):
|
||||
project_file = get_workon_home() / env / '.project'
|
||||
if project_file.exists():
|
||||
with project_file.open() as f:
|
||||
project_dir = f.readline().strip()
|
||||
if os.path.exists(project_dir):
|
||||
return project_dir
|
||||
else:
|
||||
err('Corrupted or outdated:', project_file, '\nDirectory',
|
||||
project_dir, "doesn't exist.")
|
||||
|
||||
|
||||
def unsetenv(key):
|
||||
if key in os.environ:
|
||||
del os.environ[key]
|
||||
|
||||
|
||||
def compute_path(env):
|
||||
envdir = get_workon_home() / env
|
||||
return os.pathsep.join([
|
||||
str(envdir / env_bin_dir),
|
||||
os.environ['PATH'],
|
||||
])
|
||||
|
||||
|
||||
def inve(env, command, *args, **kwargs):
|
||||
"""Run a command in the given virtual environment.
|
||||
|
||||
Pass additional keyword arguments to ``subprocess.check_call()``."""
|
||||
# we don't strictly need to restore the environment, since pew runs in
|
||||
# its own process, but it feels like the right thing to do
|
||||
with temp_environ():
|
||||
os.environ['VIRTUAL_ENV'] = str(get_workon_home() / env)
|
||||
os.environ['PATH'] = compute_path(env)
|
||||
|
||||
unsetenv('PYTHONHOME')
|
||||
unsetenv('__PYVENV_LAUNCHER__')
|
||||
|
||||
try:
|
||||
return check_call([command] + list(args), shell=windows, **kwargs)
|
||||
# need to have shell=True on windows, otherwise the PYTHONPATH
|
||||
# won't inherit the PATH
|
||||
except OSError as e:
|
||||
if e.errno == 2:
|
||||
err('Unable to find', command)
|
||||
else:
|
||||
raise
|
||||
|
||||
|
||||
def fork_shell(env, shellcmd, cwd):
|
||||
or_ctrld = '' if windows else "or 'Ctrl+D' "
|
||||
err("Launching subshell in virtual environment. Type 'exit' ", or_ctrld,
|
||||
"to return.", sep='')
|
||||
if 'VIRTUAL_ENV' in os.environ:
|
||||
err("Be aware that this environment will be nested on top "
|
||||
"of '%s'" % Path(os.environ['VIRTUAL_ENV']).name)
|
||||
try:
|
||||
inve(env, *shellcmd, cwd=cwd)
|
||||
except CalledProcessError:
|
||||
# These shells report errors when the last command executed in the
|
||||
# subshell in an error. This causes the subprocess to fail, which is
|
||||
# not what we want. Stay silent for them, there's nothing we can do.
|
||||
shell_name, _ = os.path.splitext(os.path.basename(shellcmd[0]))
|
||||
suppress_error = shell_name.lower() in ('cmd', 'powershell', 'pwsh')
|
||||
if not suppress_error:
|
||||
raise
|
||||
|
||||
|
||||
def fork_bash(env, cwd):
|
||||
# bash is a special little snowflake, and prevent_path_errors cannot work there
|
||||
# https://github.com/berdario/pew/issues/58#issuecomment-102182346
|
||||
bashrcpath = expandpath('~/.bashrc')
|
||||
if bashrcpath.exists():
|
||||
with NamedTemporaryFile('w+') as rcfile:
|
||||
with bashrcpath.open() as bashrc:
|
||||
rcfile.write(bashrc.read())
|
||||
rcfile.write('\nexport PATH="' + to_unicode(compute_path(env)) + '"')
|
||||
rcfile.flush()
|
||||
fork_shell(env, ['bash', '--rcfile', rcfile.name], cwd)
|
||||
else:
|
||||
fork_shell(env, ['bash'], cwd)
|
||||
|
||||
|
||||
def fork_cmder(env, cwd):
|
||||
shell_cmd = ['cmd']
|
||||
escaped_cmder_root = os.environ['CMDER_ROOT'].replace(' ', '^ ')
|
||||
cmderrc_path = r'{0}\vendor\init.bat'.format(escaped_cmder_root)
|
||||
if expandpath(cmderrc_path).exists():
|
||||
shell_cmd += ['/k', cmderrc_path]
|
||||
if cwd:
|
||||
os.environ['CMDER_START'] = cwd
|
||||
fork_shell(env, shell_cmd, cwd)
|
||||
|
||||
def _detect_shell():
|
||||
shell = os.environ.get('SHELL', None)
|
||||
if not shell:
|
||||
if 'CMDER_ROOT' in os.environ:
|
||||
shell = 'Cmder'
|
||||
elif windows:
|
||||
shell = get_shell(os.getpid())
|
||||
else:
|
||||
shell = 'sh'
|
||||
return shell
|
||||
|
||||
def shell(env, cwd=None):
|
||||
env = str(env)
|
||||
shell = _detect_shell()
|
||||
shell_name = Path(shell).stem
|
||||
if shell_name not in ('Cmder', 'bash', 'elvish', 'powershell', 'pwsh', 'klingon', 'cmd'):
|
||||
# On Windows the PATH is usually set with System Utility
|
||||
# so we won't worry about trying to check mistakes there
|
||||
shell_check = (sys.executable + ' -c "from pipenv.patched.pew.pew import '
|
||||
'prevent_path_errors; prevent_path_errors()"')
|
||||
try:
|
||||
inve(env, shell, '-c', shell_check)
|
||||
except CalledProcessError:
|
||||
return
|
||||
if shell_name in ('Cmder', 'cmd'):
|
||||
os.environ['PROMPT'] = '({0}) {1}'.format(env, os.environ['PROMPT'])
|
||||
if shell_name == 'bash':
|
||||
fork_bash(env, cwd)
|
||||
elif shell_name == 'Cmder':
|
||||
fork_cmder(env, cwd)
|
||||
else:
|
||||
fork_shell(env, [shell], cwd)
|
||||
|
||||
|
||||
def mkvirtualenv(envname, python=None, packages=[], project=None,
|
||||
requirements=None, rest=[]):
|
||||
|
||||
if python:
|
||||
rest = ["--python=%s" % python] + rest
|
||||
|
||||
path = (get_workon_home() / envname).absolute()
|
||||
|
||||
try:
|
||||
check_call([sys.executable, "-m", "virtualenv", str(path)] + rest)
|
||||
except (CalledProcessError, KeyboardInterrupt):
|
||||
rmvirtualenvs([envname])
|
||||
raise
|
||||
else:
|
||||
if project:
|
||||
setvirtualenvproject(envname, project.absolute())
|
||||
if requirements:
|
||||
inve(envname, 'pip', 'install', '-r', str(expandpath(requirements)))
|
||||
if packages:
|
||||
inve(envname, 'pip', 'install', *packages)
|
||||
|
||||
|
||||
def mkvirtualenv_argparser():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('-p', '--python')
|
||||
parser.add_argument('-i', action='append', dest='packages', help='Install \
|
||||
a package after the environment is created. This option may be repeated.')
|
||||
parser.add_argument('-r', dest='requirements', help='Provide a pip \
|
||||
requirements file to install a base set of packages into the new environment.')
|
||||
parser.add_argument('-d', '--dont-activate', action='store_false',
|
||||
default=True, dest='activate', help="After \
|
||||
creation, continue with the existing shell (don't \
|
||||
activate the new environment).")
|
||||
return parser
|
||||
|
||||
|
||||
def new_cmd(argv):
|
||||
"""Create a new environment, in $WORKON_HOME."""
|
||||
parser = mkvirtualenv_argparser()
|
||||
parser.add_argument('-a', dest='project', help='Provide a full path to a \
|
||||
project directory to associate with the new environment.')
|
||||
|
||||
parser.add_argument('envname')
|
||||
args, rest = parser.parse_known_args(argv)
|
||||
project = expandpath(args.project) if args.project else None
|
||||
|
||||
mkvirtualenv(args.envname, args.python, args.packages, project,
|
||||
args.requirements, rest)
|
||||
if args.activate:
|
||||
shell(args.envname)
|
||||
|
||||
|
||||
def rmvirtualenvs(envs):
|
||||
error_happened = False
|
||||
for env in envs:
|
||||
env = get_workon_home() / env
|
||||
if os.environ.get('VIRTUAL_ENV') == str(env):
|
||||
err("ERROR: You cannot remove the active environment (%s)." % env)
|
||||
error_happened = True
|
||||
break
|
||||
try:
|
||||
shutil.rmtree(str(env))
|
||||
except OSError as e:
|
||||
err("Error while trying to remove the {0} env: \n{1}".format
|
||||
(env, e.strerror))
|
||||
error_happened = True
|
||||
return error_happened
|
||||
|
||||
|
||||
|
||||
def rm_cmd(argv):
|
||||
"""Remove one or more environment, from $WORKON_HOME."""
|
||||
if len(argv) < 1:
|
||||
sys.exit("Please specify an environment")
|
||||
return rmvirtualenvs(argv)
|
||||
|
||||
|
||||
def packages(site_packages):
|
||||
nodes = site_packages.iterdir()
|
||||
return set([x.stem.split('-')[0] for x in nodes]) - set(['__pycache__'])
|
||||
|
||||
|
||||
def showvirtualenv(env):
|
||||
columns, _ = get_terminal_size()
|
||||
pkgs = sorted(packages(sitepackages_dir(env)))
|
||||
env_python = get_workon_home() / env / env_bin_dir / 'python'
|
||||
l = len(env) + 2
|
||||
version = invoke(str(env_python), '-V')
|
||||
version = ' - '.join((version.out + version.err).splitlines())
|
||||
print(env, ': ', version, sep='')
|
||||
print(textwrap.fill(' '.join(pkgs),
|
||||
width=columns-l,
|
||||
initial_indent=(l * ' '),
|
||||
subsequent_indent=(l * ' ')), '\n')
|
||||
|
||||
|
||||
def show_cmd(argv):
|
||||
try:
|
||||
showvirtualenv(argv[0])
|
||||
except IndexError:
|
||||
if 'VIRTUAL_ENV' in os.environ:
|
||||
showvirtualenv(Path(os.environ['VIRTUAL_ENV']).name)
|
||||
else:
|
||||
sys.exit('pew show [env]')
|
||||
|
||||
|
||||
def lsenvs():
|
||||
items = get_workon_home().glob(os.path.join('*', env_bin_dir, 'python*'))
|
||||
return sorted(set(env.parts[-3] for env in items))
|
||||
|
||||
|
||||
def lsvirtualenv(verbose):
|
||||
envs = lsenvs()
|
||||
|
||||
if not verbose:
|
||||
print_virtualenvs(*envs)
|
||||
else:
|
||||
for env in envs:
|
||||
showvirtualenv(env)
|
||||
|
||||
|
||||
def ls_cmd(argv):
|
||||
"""List available environments."""
|
||||
parser = argparse.ArgumentParser()
|
||||
p_group = parser.add_mutually_exclusive_group()
|
||||
p_group.add_argument('-b', '--brief', action='store_false')
|
||||
p_group.add_argument('-l', '--long', action='store_true')
|
||||
args = parser.parse_args(argv)
|
||||
lsvirtualenv(args.long)
|
||||
|
||||
def parse_envname(argv, no_arg_callback):
|
||||
if len(argv) < 1:
|
||||
no_arg_callback()
|
||||
|
||||
env = argv[0]
|
||||
if env.startswith('/'):
|
||||
sys.exit("ERROR: Invalid environment name '{0}'.".format(env))
|
||||
if not (get_workon_home() / env).exists():
|
||||
sys.exit("ERROR: Environment '{0}' does not exist. Create it with \
|
||||
'pew new {0}'.".format(env))
|
||||
else:
|
||||
return env
|
||||
|
||||
def workon_cmd(argv):
|
||||
"""List or change working virtual environments."""
|
||||
|
||||
def list_and_exit():
|
||||
lsvirtualenv(False)
|
||||
sys.exit(0)
|
||||
|
||||
env = parse_envname(argv, list_and_exit)
|
||||
|
||||
# Check if the virtualenv has an associated project directory and in
|
||||
# this case, use it as the current working directory.
|
||||
project_dir = get_project_dir(env) or os.getcwd()
|
||||
shell(env, cwd=project_dir)
|
||||
|
||||
|
||||
def sitepackages_dir(env=os.environ.get('VIRTUAL_ENV')):
|
||||
if not env:
|
||||
sys.exit('ERROR: no virtualenv active')
|
||||
else:
|
||||
env_python = get_workon_home() / env / env_bin_dir / 'python'
|
||||
return Path(invoke(str(env_python), '-c', 'import distutils; \
|
||||
print(distutils.sysconfig.get_python_lib())').out)
|
||||
|
||||
|
||||
def add_cmd(argv):
|
||||
"""Add the specified directories to the Python path for the currently active virtualenv.
|
||||
|
||||
This will be done by placing the directory names in a path file named
|
||||
"virtualenv_path_extensions.pth" inside the virtualenv's site-packages
|
||||
directory; if this file does not exists, it will be created first.
|
||||
|
||||
"""
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('-d', dest='remove', action='store_true')
|
||||
parser.add_argument('dirs', nargs='+')
|
||||
args = parser.parse_args(argv)
|
||||
|
||||
extra_paths = sitepackages_dir() / '_virtualenv_path_extensions.pth'
|
||||
new_paths = [os.path.abspath(d) + "\n" for d in args.dirs]
|
||||
if not extra_paths.exists():
|
||||
with extra_paths.open('w') as extra:
|
||||
extra.write('''import sys; sys.__plen = len(sys.path)
|
||||
import sys; new=sys.path[sys.__plen:]; del sys.path[sys.__plen:]; p=getattr(sys,'__egginsert',0); sys.path[p:p]=new; sys.__egginsert = p+len(new)
|
||||
''')
|
||||
|
||||
def rewrite(f):
|
||||
with extra_paths.open('r+') as extra:
|
||||
to_write = f(extra.readlines())
|
||||
extra.seek(0)
|
||||
extra.truncate()
|
||||
extra.writelines(to_write)
|
||||
|
||||
if args.remove:
|
||||
rewrite(lambda ls: [line for line in ls if line not in new_paths])
|
||||
else:
|
||||
rewrite(lambda lines: lines[0:1] + new_paths + lines[1:])
|
||||
|
||||
|
||||
def sitepackages_dir_cmd(argv):
|
||||
print(sitepackages_dir())
|
||||
|
||||
|
||||
def lssitepackages_cmd(argv):
|
||||
"""Show the content of the site-packages directory of the current virtualenv."""
|
||||
site = sitepackages_dir()
|
||||
print(*sorted(site.iterdir()), sep=os.linesep)
|
||||
extra_paths = site / '_virtualenv_path_extensions.pth'
|
||||
if extra_paths.exists():
|
||||
print('from _virtualenv_path_extensions.pth:')
|
||||
with extra_paths.open() as extra:
|
||||
print(''.join(extra.readlines()))
|
||||
|
||||
|
||||
def toggleglobalsitepackages_cmd(argv):
|
||||
"""Toggle the current virtualenv between having and not having access to the global site-packages."""
|
||||
quiet = argv == ['-q']
|
||||
site = sitepackages_dir()
|
||||
ngsp_file = site.parent / 'no-global-site-packages.txt'
|
||||
if ngsp_file.exists():
|
||||
ngsp_file.unlink()
|
||||
if not quiet:
|
||||
print('Enabled global site-packages')
|
||||
else:
|
||||
with ngsp_file.open('w'):
|
||||
if not quiet:
|
||||
print('Disabled global site-packages')
|
||||
|
||||
|
||||
def cp_cmd(argv):
|
||||
"""Duplicate the named virtualenv to make a new one."""
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('source')
|
||||
parser.add_argument('target', nargs='?')
|
||||
parser.add_argument('-d', '--dont-activate', action='store_false',
|
||||
default=True, dest='activate', help="After \
|
||||
creation, continue with the existing shell (don't \
|
||||
activate the new environment).")
|
||||
|
||||
args = parser.parse_args(argv)
|
||||
target_name = copy_virtualenv_project(args.source, args.target)
|
||||
if args.activate:
|
||||
shell(target_name)
|
||||
|
||||
|
||||
def copy_virtualenv_project(source, target):
|
||||
source = expandpath(source)
|
||||
workon_home = get_workon_home()
|
||||
if not source.exists():
|
||||
source = workon_home / source
|
||||
if not source.exists():
|
||||
sys.exit('Please provide a valid virtualenv to copy')
|
||||
|
||||
target_name = target or source.name
|
||||
|
||||
target = workon_home / target_name
|
||||
|
||||
if target.exists():
|
||||
sys.exit('%s virtualenv already exists in %s.' % (
|
||||
target_name, workon_home
|
||||
))
|
||||
|
||||
print('Copying {0} in {1}'.format(source, target_name))
|
||||
clone_virtualenv(str(source), str(target))
|
||||
return target_name
|
||||
|
||||
|
||||
def rename_cmd(argv):
|
||||
"""Rename a virtualenv"""
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('source')
|
||||
parser.add_argument('target')
|
||||
pargs = parser.parse_args(argv)
|
||||
copy_virtualenv_project(pargs.source, pargs.target)
|
||||
return rmvirtualenvs([pargs.source])
|
||||
|
||||
|
||||
def setvirtualenvproject(env, project):
|
||||
print('Setting project for {0} to {1}'.format(env, project))
|
||||
with (get_workon_home() / env / '.project').open('wb') as prj:
|
||||
prj.write(str(project).encode())
|
||||
|
||||
|
||||
def setproject_cmd(argv):
|
||||
"""Given a virtualenv directory and a project directory, set the
|
||||
virtualenv up to be associated with the project."""
|
||||
args = dict(enumerate(argv))
|
||||
project = os.path.abspath(args.get(1, '.'))
|
||||
env = args.get(0, os.environ.get('VIRTUAL_ENV'))
|
||||
if not env:
|
||||
sys.exit('pew setproject [virtualenv] [project_path]')
|
||||
if not (get_workon_home() / env).exists():
|
||||
sys.exit("Environment '%s' doesn't exist." % env)
|
||||
if not os.path.isdir(project):
|
||||
sys.exit('pew setproject: %s does not exist' % project)
|
||||
setvirtualenvproject(env, project)
|
||||
|
||||
|
||||
def mkproject_cmd(argv):
|
||||
"""Create a new project directory and its associated virtualenv."""
|
||||
if '-l' in argv or '--list' in argv:
|
||||
templates = [t.name[9:] for t in get_workon_home().glob("template_*")]
|
||||
print("Available project templates:", *templates, sep='\n')
|
||||
return
|
||||
|
||||
parser = mkvirtualenv_argparser()
|
||||
parser.add_argument('envname')
|
||||
parser.add_argument(
|
||||
'-t', action='append', default=[], dest='templates', help='Multiple \
|
||||
templates may be selected. They are applied in the order specified on the \
|
||||
command line.')
|
||||
parser.add_argument(
|
||||
'-l', '--list', action='store_true', help='List available templates.')
|
||||
|
||||
args, rest = parser.parse_known_args(argv)
|
||||
|
||||
projects_home = Path(os.environ.get('PROJECT_HOME', '.'))
|
||||
if not projects_home.exists():
|
||||
sys.exit('ERROR: Projects directory %s does not exist. \
|
||||
Create it or set PROJECT_HOME to an existing directory.' % projects_home)
|
||||
|
||||
project = (projects_home / args.envname).absolute()
|
||||
if project.exists():
|
||||
sys.exit('Project %s already exists.' % args.envname)
|
||||
|
||||
mkvirtualenv(args.envname, args.python, args.packages, project.absolute(),
|
||||
args.requirements, rest)
|
||||
|
||||
project.mkdir()
|
||||
|
||||
for template_name in args.templates:
|
||||
template = get_workon_home() / ("template_" + template_name)
|
||||
inve(args.envname, str(template), args.envname, str(project))
|
||||
if args.activate:
|
||||
shell(args.envname, cwd=str(project))
|
||||
|
||||
|
||||
def mktmpenv_cmd(argv):
|
||||
"""Create a temporary virtualenv."""
|
||||
parser = mkvirtualenv_argparser()
|
||||
env = '.'
|
||||
while (get_workon_home() / env).exists():
|
||||
env = hex(random.getrandbits(64))[2:-1]
|
||||
|
||||
args, rest = parser.parse_known_args(argv)
|
||||
|
||||
mkvirtualenv(env, args.python, args.packages, requirements=args.requirements,
|
||||
rest=rest)
|
||||
print('This is a temporary environment. It will be deleted when you exit')
|
||||
try:
|
||||
if args.activate:
|
||||
# only used for testing on windows
|
||||
shell(env)
|
||||
finally:
|
||||
return rmvirtualenvs([env])
|
||||
|
||||
|
||||
def wipeenv_cmd(argv):
|
||||
"""Remove all installed packages from the current (or supplied) env."""
|
||||
env = argv[0] if argv else os.environ.get('VIRTUAL_ENV')
|
||||
|
||||
if not env:
|
||||
sys.exit('ERROR: no virtualenv active')
|
||||
elif not (get_workon_home() / env).exists():
|
||||
sys.exit("ERROR: Environment '{0}' does not exist.".format(env))
|
||||
else:
|
||||
env_pip = str(get_workon_home() / env / env_bin_dir / 'pip')
|
||||
all_pkgs = set(invoke(env_pip, 'freeze').out.splitlines())
|
||||
pkgs = set(p for p in all_pkgs if len(p.split("==")) == 2)
|
||||
ignored = sorted(all_pkgs - pkgs)
|
||||
pkgs = set(p.split("==")[0] for p in pkgs)
|
||||
to_remove = sorted(pkgs - set(['distribute', 'wsgiref']))
|
||||
if to_remove:
|
||||
print("Ignoring:\n %s" % "\n ".join(ignored))
|
||||
print("Uninstalling packages:\n %s" % "\n ".join(to_remove))
|
||||
inve(env, 'pip', 'uninstall', '-y', *to_remove)
|
||||
else:
|
||||
print("Nothing to remove")
|
||||
|
||||
|
||||
def inall_cmd(argv):
|
||||
"""Run a command in each virtualenv."""
|
||||
envs = lsenvs()
|
||||
errors = False
|
||||
for env in envs:
|
||||
print("\n%s:" % env)
|
||||
try:
|
||||
inve(env, *argv)
|
||||
except CalledProcessError as e:
|
||||
errors = True
|
||||
err(e)
|
||||
sys.exit(errors)
|
||||
|
||||
|
||||
def in_cmd(argv):
|
||||
"""Run a command in the given virtualenv."""
|
||||
|
||||
if len(argv) == 1:
|
||||
return workon_cmd(argv)
|
||||
|
||||
parse_envname(argv, lambda : sys.exit('You must provide a valid virtualenv to target'))
|
||||
|
||||
inve(*argv)
|
||||
|
||||
|
||||
def restore_cmd(argv):
|
||||
"""Try to restore a broken virtualenv by reinstalling the same python version on top of it"""
|
||||
|
||||
if len(argv) < 1:
|
||||
sys.exit('You must provide a valid virtualenv to target')
|
||||
|
||||
env = argv[0]
|
||||
path = get_workon_home() / env
|
||||
path = workon_home / env
|
||||
py = path / env_bin_dir / ('python.exe' if windows else 'python')
|
||||
exact_py = py.resolve().name
|
||||
|
||||
check_call([sys.executable, "-m", "virtualenv", str(path.absolute()), "--python=%s" % exact_py])
|
||||
|
||||
|
||||
def dir_cmd(argv):
|
||||
"""Print the path for the virtualenv directory"""
|
||||
env = parse_envname(argv, lambda : sys.exit('You must provide a valid virtualenv to target'))
|
||||
print(get_workon_home() / env)
|
||||
|
||||
|
||||
def install_cmd(argv):
|
||||
'''Use Pythonz to download and build the specified Python version'''
|
||||
installer = InstallCommand()
|
||||
options, versions = installer.parser.parse_args(argv)
|
||||
if len(versions) != 1:
|
||||
installer.parser.print_help()
|
||||
sys.exit(1)
|
||||
else:
|
||||
try:
|
||||
actual_installer = PythonInstaller.get_installer(versions[0], options)
|
||||
actual_installer.install()
|
||||
except AlreadyInstalledError as e:
|
||||
print(e)
|
||||
|
||||
|
||||
def uninstall_cmd(argv):
|
||||
'''Use Pythonz to uninstall the specified Python version'''
|
||||
UninstallCommand().run(argv)
|
||||
|
||||
|
||||
def list_pythons_cmd(argv):
|
||||
'''List the pythons installed by Pythonz (or all the installable ones)'''
|
||||
try:
|
||||
Path(PATH_PYTHONS).mkdir(parents=True)
|
||||
except OSError:
|
||||
pass
|
||||
ListPythons().run(argv)
|
||||
|
||||
|
||||
def locate_python_cmd(argv):
|
||||
'''Locate the path for the python version installed by Pythonz'''
|
||||
LocatePython().run(argv)
|
||||
|
||||
|
||||
def version_cmd(argv):
|
||||
"""Prints current pew version"""
|
||||
import pkg_resources
|
||||
|
||||
try:
|
||||
__version__ = pkg_resources.get_distribution('pew').version
|
||||
except pkg_resources.DistributionNotFound:
|
||||
__version__ = 'unknown'
|
||||
print('Setuptools has some issues here, failed to get our own package.', file=sys.stderr)
|
||||
|
||||
print(__version__)
|
||||
|
||||
|
||||
def prevent_path_errors():
|
||||
if 'VIRTUAL_ENV' in os.environ and not check_path():
|
||||
sys.exit('''ERROR: The virtualenv hasn't been activated correctly.
|
||||
Either the env is corrupted (try running `pew restore env`),
|
||||
Or an upgrade of your Python version broke your env,
|
||||
Or check the contents of your $PATH. You might be adding new directories to it
|
||||
from inside your shell's configuration file.
|
||||
In this case, for further details please see: https://github.com/berdario/pew#the-environment-doesnt-seem-to-be-activated''')
|
||||
|
||||
|
||||
def first_run_setup():
|
||||
shell = supported_shell()
|
||||
if shell:
|
||||
if shell == 'fish':
|
||||
source_cmd = 'source (pew shell_config)'
|
||||
else:
|
||||
source_cmd = 'source $(pew shell_config)'
|
||||
rcpath = expandpath({'bash': '~/.bashrc'
|
||||
, 'zsh': '~/.zshrc'
|
||||
, 'fish': '~/.config/fish/config.fish'}[shell])
|
||||
if rcpath.exists():
|
||||
update_config_file(rcpath, source_cmd)
|
||||
else:
|
||||
print("It seems that you're running pew for the first time\n"
|
||||
"If you want source shell competions and update your prompt, "
|
||||
"Add the following line to your shell config file:\n %s" % source_cmd)
|
||||
print('\nWill now continue with the command:', *sys.argv[1:])
|
||||
input('[enter]')
|
||||
|
||||
def update_config_file(rcpath, source_cmd):
|
||||
with rcpath.open('r+') as rcfile:
|
||||
if source_cmd not in (line.strip() for line in rcfile.readlines()):
|
||||
choice = 'X'
|
||||
while choice not in ('y', '', 'n'):
|
||||
choice = input("It seems that you're running pew for the first time\n"
|
||||
"do you want to modify %s to source completions and"
|
||||
" update your prompt? [y/N]\n> " % rcpath).lower()
|
||||
if choice == 'y':
|
||||
rcfile.write('\n# added by Pew\n%s\n' % source_cmd)
|
||||
print('Done')
|
||||
else:
|
||||
print('\nOk, if you want to do it manually, just add\n %s\nat'
|
||||
' the end of %s' % (source_cmd, rcpath))
|
||||
|
||||
|
||||
def print_commands(cmds):
|
||||
longest = max(map(len, cmds)) + 3
|
||||
columns, _ = get_terminal_size()
|
||||
|
||||
print('Available commands:\n')
|
||||
for cmd, fun in sorted(cmds.items()):
|
||||
if fun.__doc__:
|
||||
print(textwrap.fill(
|
||||
fun.__doc__.splitlines()[0],
|
||||
columns or 1000,
|
||||
initial_indent=(' {0}: '.format(cmd)).ljust(longest),
|
||||
subsequent_indent=longest * ' '))
|
||||
else:
|
||||
print(' ' + cmd)
|
||||
|
||||
|
||||
def pew():
|
||||
first_run = makedirs_and_symlink_if_needed(get_workon_home())
|
||||
if first_run and sys.stdin.isatty():
|
||||
first_run_setup()
|
||||
|
||||
cmds = dict((cmd[:-4], fun)
|
||||
for cmd, fun in globals().items() if cmd.endswith('_cmd'))
|
||||
if sys.argv[1:]:
|
||||
if sys.argv[1] in cmds:
|
||||
command = cmds[sys.argv[1]]
|
||||
try:
|
||||
return command(sys.argv[2:])
|
||||
except CalledProcessError as e:
|
||||
return e.returncode
|
||||
except KeyboardInterrupt:
|
||||
pass
|
||||
else:
|
||||
err("ERROR: command", sys.argv[1], "does not exist.")
|
||||
print_commands(cmds)
|
||||
sys.exit(1)
|
||||
else:
|
||||
print_commands(cmds)
|
||||
@@ -1,107 +0,0 @@
|
||||
#compdef pew
|
||||
|
||||
_pew_list_venvs () {
|
||||
local expl
|
||||
local -a venvs
|
||||
|
||||
venvs=(${(f)"$(_call_program venvs pew ls | tr " " "\n" 2>/dev/null)"})
|
||||
_wanted venvs expl 'virtual envs' compadd -a venvs
|
||||
}
|
||||
|
||||
|
||||
local curcontext="$curcontext" state line
|
||||
typeset -A opt_args
|
||||
|
||||
_arguments -C \
|
||||
':subcommand:->subcommand' \
|
||||
'*::option:->option'
|
||||
|
||||
case $state in
|
||||
(subcommand)
|
||||
local -a subcommands
|
||||
subcommands=(
|
||||
'add:Add directories to python path of active virtualenv'
|
||||
'cp:Duplicate the named virtualenv to make a new one'
|
||||
'inall:Run a command in each virtualenv:command'
|
||||
'install:Use Pythonz to download and build the specified Python version'
|
||||
'list_pythons:List the pythons installed by Pythonz (or all the installable ones)'
|
||||
'locate_python:Locate the path for the python version installed by Pythonz'
|
||||
'ls:List all existing virtual environments'
|
||||
'lssitepackages:List currently active site-packages'
|
||||
'mkproject:Create environment with an associated project directory'
|
||||
'mktmpenv:Create a temporary virtualenv'
|
||||
'new:Create a new environment'
|
||||
'rename:Rename a virtualenv'
|
||||
'restore:Try to restore a broken virtualenv by reinstalling the same python version on top of it'
|
||||
'rm:Remove one or more environments'
|
||||
'setproject:Bind an existing virtualenv to an existing project directory'
|
||||
'show:Display currently active virtualenv'
|
||||
'sitepackages_dir:Location of the currently active site-packages'
|
||||
'toggleglobalsitepackages:Toggle access to global site-packages for current virtualenv'
|
||||
'wipeenv:Remove all installed packages from current env'
|
||||
'workon:Activates an existing virtual environment'
|
||||
)
|
||||
_describe -t commands 'pew subcommands' subcommands
|
||||
;;
|
||||
|
||||
(option)
|
||||
local -a new_env_options
|
||||
new_env_options=(
|
||||
'-h[Show help]'
|
||||
'-p[Python executable]:python:_command_names'
|
||||
'*-i[Install a package after the environment is created]:package name'
|
||||
'-a[Project directory to associate]:project directory:_path_files -/'
|
||||
'-r[Pip requirements file]:requirements file:_files'
|
||||
)
|
||||
|
||||
case "$line[1]" in
|
||||
(mktmpenv)
|
||||
_arguments \
|
||||
$new_env_options
|
||||
;;
|
||||
(new)
|
||||
_arguments \
|
||||
$new_env_options \
|
||||
'1:new env name'
|
||||
;;
|
||||
(mkproject)
|
||||
_arguments \
|
||||
$new_env_options \
|
||||
'*-t[Apply templates]' \
|
||||
'-l[List available templates]' \
|
||||
'1:new env name'
|
||||
;;
|
||||
|
||||
(ls)
|
||||
_arguments \
|
||||
'(-l --long)--long[Verbose ls]' \
|
||||
'(-b --brief)--brief[One line ls]'
|
||||
;;
|
||||
(inall)
|
||||
_arguments \
|
||||
'*:command'
|
||||
;;
|
||||
|
||||
(show|workon|rm|wipeenv|restore)
|
||||
_arguments \
|
||||
'1:virtual env:_pew_list_venvs'
|
||||
;;
|
||||
(cp)
|
||||
_arguments \
|
||||
'1:virtual env:_pew_list_venvs' \
|
||||
'2:new env name'
|
||||
;;
|
||||
|
||||
(add)
|
||||
_arguments \
|
||||
'-h[Show help]' \
|
||||
'-d[Removes previously added directories]' \
|
||||
'*: :_directories -/'
|
||||
;;
|
||||
(setproject)
|
||||
_arguments \
|
||||
'1:virtual env:_pew_list_venvs' \
|
||||
'*:project directory:_directories -/'
|
||||
;;
|
||||
esac
|
||||
esac
|
||||
@@ -1,46 +0,0 @@
|
||||
# Homebrew on Macs have version 1.3 of bash-completion which doesn't include
|
||||
# _init_completion. This is a very minimal version of that function.
|
||||
__my_init_completion()
|
||||
{
|
||||
COMPREPLY=()
|
||||
_get_comp_words_by_ref cur prev words cword
|
||||
}
|
||||
|
||||
_pew()
|
||||
{
|
||||
local cur prev words cword args commands
|
||||
if declare -F _init_completions >/dev/null 2>&1; then
|
||||
_init_completion || return
|
||||
else
|
||||
__my_init_completion || return
|
||||
fi
|
||||
args="--help --python -i -a -r"
|
||||
commands="ls add mkproject rm lssitepackages cp workon new mktmpenv setproject show wipeenv sitepackages_dir inall toggleglobalsitepackages rename restore install list_pythons locate_python"
|
||||
|
||||
case $prev in
|
||||
ls|show|rm|workon|cp|setproject|rename|wipeenv)
|
||||
COMPREPLY=( $(compgen -W "$(pew ls)" -- ${cur}) )
|
||||
return 0
|
||||
;;
|
||||
inall)
|
||||
_command_offset 2
|
||||
return 0
|
||||
;;
|
||||
mktmpenv|new)
|
||||
COMPREPLY=( $(compgen -W "${args}" -- ${cur}) )
|
||||
return 0
|
||||
;;
|
||||
mkproject)
|
||||
COMPREPLY=( $(compgen -W "${args} -t --list" -- ${cur}) )
|
||||
return 0
|
||||
;;
|
||||
add)
|
||||
COMPREPLY=( $(compgen -W "--help -d" -- ${cur}) )
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
|
||||
COMPREPLY=( $(compgen -W "${commands}" -- ${cur}) )
|
||||
|
||||
} &&
|
||||
complete -o default -F _pew pew
|
||||
@@ -1,116 +0,0 @@
|
||||
set pew pew
|
||||
|
||||
|
||||
function __pew_needs_command
|
||||
set cmd (commandline -opc)
|
||||
if [ (count $cmd) -eq 1 -a $cmd[1] = "$pew" ]
|
||||
return 0
|
||||
end
|
||||
return 1
|
||||
end
|
||||
|
||||
|
||||
|
||||
function __pew_list_envs
|
||||
eval "$pew ls" | tr " " "\n"
|
||||
end
|
||||
|
||||
function __pew_using_command
|
||||
set cmd (commandline -opc)
|
||||
if test (count $cmd) -gt 1
|
||||
if test $argv[1] = $cmd[2]
|
||||
return 0
|
||||
end
|
||||
end
|
||||
return 1
|
||||
end
|
||||
|
||||
|
||||
#### new
|
||||
complete -f -c $pew -n '__pew_needs_command' -a new -d 'Create a new environment'
|
||||
complete -f -c $pew -n '__pew_using_command new' -s h -d 'Show help'
|
||||
complete -f -c $pew -n '__pew_using_command new' -s p -l python -d 'Python executable'
|
||||
complete -f -c $pew -n '__pew_using_command new' -s i -d 'Install a package after the environment is created'
|
||||
complete -f -c $pew -n '__pew_using_command new' -s a -a '(__fish_complete_directories (commandline -ct))' -d 'Project directory to associate'
|
||||
complete -f -c $pew -n '__pew_using_command new' -s r -d 'Pip requirements file'
|
||||
|
||||
|
||||
#### workon
|
||||
complete -f -c $pew -n '__pew_needs_command' -a workon -d 'Activates an existing virtual environment'
|
||||
complete -f -c $pew -n '__pew_using_command workon' -a '(__pew_list_envs)' -d 'Virtual env'
|
||||
|
||||
#### mktmpenv
|
||||
complete -f -c $pew -n '__pew_needs_command' -a mktmpenv -d 'Create a temporary virtualenv'
|
||||
complete -f -c $pew -n '__pew_using_command mktmpenv' -s h -d 'Show help'
|
||||
complete -f -c $pew -n '__pew_using_command mktmpenv' -s p -l python -d 'Python executable'
|
||||
complete -f -c $pew -n '__pew_using_command mktmpenv' -s i -d 'Install a package after the environment is created'
|
||||
complete -f -c $pew -n '__pew_using_command mktmpenv' -s a -d 'Project directory to associate'
|
||||
complete -f -c $pew -n '__pew_using_command mktmpenv' -s r -d 'Pip requirements file'
|
||||
|
||||
#### ls
|
||||
complete -f -c $pew -n '__pew_needs_command' -a ls -d 'List all existing virtual environments'
|
||||
complete -f -c $pew -n '__pew_using_command ls' -s l -l long -d 'Verbose ls'
|
||||
complete -f -c $pew -n '__pew_using_command ls' -s b -l brief -d 'One line ls'
|
||||
|
||||
#### show
|
||||
complete -f -c $pew -n '__pew_needs_command' -a show -d 'Show'
|
||||
complete -f -c $pew -n '__pew_using_command show' -a '(__pew_list_envs)' -d 'Virtual env'
|
||||
|
||||
#### rm
|
||||
complete -f -c $pew -n '__pew_needs_command' -a rm -d 'Remove one or more environments'
|
||||
complete -f -c $pew -n '__pew_using_command rm' -a '(__pew_list_envs)' -d 'Virtual env'
|
||||
|
||||
#### cp
|
||||
complete -f -c $pew -n '__pew_needs_command' -a cp -d 'Duplicate an existing virtualenv environment'
|
||||
|
||||
#### sitepackages_dir
|
||||
complete -f -c $pew -n '__pew_needs_command' -a sitepackages_dir -d 'Location of the currently active site-packages'
|
||||
|
||||
#### lssitepackages
|
||||
complete -f -c $pew -n '__pew_needs_command' -a lssitepackages -d 'List currently active site-packages'
|
||||
|
||||
|
||||
#### add
|
||||
complete -f -c $pew -n '__pew_needs_command' -a add -d 'Adds the specified directories'
|
||||
complete -f -c $pew -n '__pew_using_command add' -s h -d 'Show help'
|
||||
complete -f -c $pew -n '__pew_using_command add' -s d -d 'Removes previously added directiories'
|
||||
|
||||
#### toggleglobalsitepackages
|
||||
complete -f -c $pew -n '__pew_needs_command' -a toggleglobalsitepackages -d 'Active virtualenv can access global site-packages'
|
||||
|
||||
#### mkproject
|
||||
complete -f -c $pew -n '__pew_needs_command' -a mkproject -d 'Create a new environment with a project directory'
|
||||
complete -f -c $pew -n '__pew_using_command mkproject' -s h -d 'Show help'
|
||||
complete -f -c $pew -n '__pew_using_command mkproject' -s p -l python -d 'Python executable'
|
||||
complete -f -c $pew -n '__pew_using_command mkproject' -s i -d 'Install a package after the environment is created'
|
||||
complete -f -c $pew -n '__pew_using_command mkproject' -s a -d 'Project directory to associate'
|
||||
complete -f -c $pew -n '__pew_using_command mkproject' -s r -d 'Pip requirements file'
|
||||
complete -f -c $pew -n '__pew_using_command mkproject' -s t -d 'Apply templates'
|
||||
complete -f -c $pew -n '__pew_using_command mkproject' -s l -l list -d 'List available templates'
|
||||
|
||||
|
||||
#### setproject
|
||||
complete -f -c $pew -n '__pew_needs_command' -a setproject -d 'Bind an existing virtualenv to an existing project'
|
||||
|
||||
#### version
|
||||
complete -f -c $pew -n '__pew_needs_command' -a version -d 'Prints current version'
|
||||
|
||||
#### wipeenv
|
||||
complete -f -c $pew -n '__pew_needs_command' -a wipeenv -d 'Remove all installed packages from a virtualenv'
|
||||
complete -f -c $pew -n '__pew_using_command workon' -a '(__pew_list_envs)' -d 'Virtual env'
|
||||
|
||||
#### restore
|
||||
complete -f -c $pew -n '__pew_needs_command' -a restore -d 'Try to restore a broken virtualenv'
|
||||
complete -f -c $pew -n '__pew_using_command workon' -a '(__pew_list_envs)' -d 'Virtual env'
|
||||
|
||||
#### rename
|
||||
complete -f -c $pew -n '__pew_needs_command' -a rename -d 'Rename a virtualenv'
|
||||
|
||||
#### install
|
||||
complete -f -c $pew -n '__pew_needs_command' -a install -d 'Use Pythonz to download and build a Python vm'
|
||||
|
||||
#### list_pythons
|
||||
complete -f -c $pew -n '__pew_needs_command' -a list_pythons -d 'List the pythons installed by Pythonz'
|
||||
|
||||
#### locate_python
|
||||
complete -f -c $pew -n '__pew_needs_command' -a locate_python -d 'Locate the path for the python version installed by Pythonz'
|
||||
@@ -1,107 +0,0 @@
|
||||
#compdef pew
|
||||
|
||||
_pew_list_venvs () {
|
||||
local expl
|
||||
local -a venvs
|
||||
|
||||
venvs=(${(f)"$(_call_program venvs pew ls | tr " " "\n" 2>/dev/null)"})
|
||||
_wanted venvs expl 'virtual envs' compadd -a venvs
|
||||
}
|
||||
|
||||
|
||||
local curcontext="$curcontext" state line
|
||||
typeset -A opt_args
|
||||
|
||||
_arguments -C \
|
||||
':subcommand:->subcommand' \
|
||||
'*::option:->option'
|
||||
|
||||
case $state in
|
||||
(subcommand)
|
||||
local -a subcommands
|
||||
subcommands=(
|
||||
'add:Add directories to python path of active virtualenv'
|
||||
'cp:Duplicate the named virtualenv to make a new one'
|
||||
'inall:Run a command in each virtualenv:command'
|
||||
'install:Use Pythonz to download and build the specified Python version'
|
||||
'list_pythons:List the pythons installed by Pythonz (or all the installable ones)'
|
||||
'locate_python:Locate the path for the python version installed by Pythonz'
|
||||
'ls:List all existing virtual environments'
|
||||
'lssitepackages:List currently active site-packages'
|
||||
'mkproject:Create environment with an associated project directory'
|
||||
'mktmpenv:Create a temporary virtualenv'
|
||||
'new:Create a new environment'
|
||||
'rename:Rename a virtualenv'
|
||||
'restore:Try to restore a broken virtualenv by reinstalling the same python version on top of it'
|
||||
'rm:Remove one or more environments'
|
||||
'setproject:Bind an existing virtualenv to an existing project directory'
|
||||
'show:Display currently active virtualenv'
|
||||
'sitepackages_dir:Location of the currently active site-packages'
|
||||
'toggleglobalsitepackages:Toggle access to global site-packages for current virtualenv'
|
||||
'wipeenv:Remove all installed packages from current env'
|
||||
'workon:Activates an existing virtual environment'
|
||||
)
|
||||
_describe -t commands 'pew subcommands' subcommands
|
||||
;;
|
||||
|
||||
(option)
|
||||
local -a new_env_options
|
||||
new_env_options=(
|
||||
'-h[Show help]'
|
||||
'-p[Python executable]:python:_command_names'
|
||||
'*-i[Install a package after the environment is created]:package name'
|
||||
'-a[Project directory to associate]:project directory:_path_files -/'
|
||||
'-r[Pip requirements file]:requirements file:_files'
|
||||
)
|
||||
|
||||
case "$line[1]" in
|
||||
(mktmpenv)
|
||||
_arguments \
|
||||
$new_env_options
|
||||
;;
|
||||
(new)
|
||||
_arguments \
|
||||
$new_env_options \
|
||||
'1:new env name'
|
||||
;;
|
||||
(mkproject)
|
||||
_arguments \
|
||||
$new_env_options \
|
||||
'*-t[Apply templates]' \
|
||||
'-l[List available templates]' \
|
||||
'1:new env name'
|
||||
;;
|
||||
|
||||
(ls)
|
||||
_arguments \
|
||||
'(-l --long)--long[Verbose ls]' \
|
||||
'(-b --brief)--brief[One line ls]'
|
||||
;;
|
||||
(inall)
|
||||
_arguments \
|
||||
'*:command'
|
||||
;;
|
||||
|
||||
(show|workon|rm|wipeenv|restore)
|
||||
_arguments \
|
||||
'1:virtual env:_pew_list_venvs'
|
||||
;;
|
||||
(cp)
|
||||
_arguments \
|
||||
'1:virtual env:_pew_list_venvs' \
|
||||
'2:new env name'
|
||||
;;
|
||||
|
||||
(add)
|
||||
_arguments \
|
||||
'-h[Show help]' \
|
||||
'-d[Removes previously added directories]' \
|
||||
'*: :_directories -/'
|
||||
;;
|
||||
(setproject)
|
||||
_arguments \
|
||||
'1:virtual env:_pew_list_venvs' \
|
||||
'*:project directory:_directories -/'
|
||||
;;
|
||||
esac
|
||||
esac
|
||||
@@ -1,4 +0,0 @@
|
||||
#! /usr/bin/env python
|
||||
from pew.pew import deploy_completions
|
||||
if __name__ == '__main__':
|
||||
deploy_completions()
|
||||
@@ -1,3 +0,0 @@
|
||||
source "$( dirname "${BASH_SOURCE[0]}" )"/complete.bash
|
||||
|
||||
[[ -z "${VIRTUAL_ENV}" ]] || PS1="\[\033[01;34m\]\$(basename '$VIRTUAL_ENV')\[\e[0m\] $PS1"
|
||||
@@ -1,9 +0,0 @@
|
||||
. (dirname (status --current-filename))/complete.fish
|
||||
|
||||
function pew_prompt
|
||||
if [ -n "$VIRTUAL_ENV" ]
|
||||
echo -n (set_color --bold -b blue white) (basename "$VIRTUAL_ENV") (set_color normal)" "
|
||||
end
|
||||
end
|
||||
|
||||
# Remember to use (pew_prompt) inside fish_prompt if you want your prompt to display the active environment
|
||||
@@ -1,12 +0,0 @@
|
||||
fpath=( ${0:a:h} "${fpath[@]}" )
|
||||
compinit
|
||||
|
||||
function virtualenv_prompt_info() {
|
||||
if [ -n "$VIRTUAL_ENV" ]; then
|
||||
local name=$(basename $VIRTUAL_ENV)
|
||||
echo "($name) "
|
||||
fi
|
||||
}
|
||||
PS1="$(virtualenv_prompt_info)$PS1"
|
||||
|
||||
# be sure to disable promptinit if the prompt is not updated
|
||||
@@ -1,6 +0,0 @@
|
||||
#! /bin/sh
|
||||
# put this inside $WORKON_HOME
|
||||
project=$1
|
||||
project_dir=$2
|
||||
pip install django
|
||||
django-admin.py startproject "$project"
|
||||
@@ -341,7 +341,7 @@ def fs_str(string):
|
||||
_fs_encoding = sys.getfilesystemencoding() or sys.getdefaultencoding()
|
||||
|
||||
|
||||
# Borrowed from pew to avoid importing pew which imports psutil
|
||||
# Borrowed from Pew.
|
||||
# See https://github.com/berdario/pew/blob/master/pew/_utils.py#L82
|
||||
@contextmanager
|
||||
def temp_environ():
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
PIPENV_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
PIPENV_VENDOR = os.sep.join([PIPENV_ROOT, 'vendor'])
|
||||
PIPENV_PATCHED = os.sep.join([PIPENV_ROOT, 'patched'])
|
||||
|
||||
import pew
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.path.insert(0, PIPENV_VENDOR)
|
||||
sys.path.insert(0, PIPENV_PATCHED)
|
||||
pew.pew.pew()
|
||||
+3
-4
@@ -326,7 +326,6 @@ Then, simply run:
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
$ pipsi install pew
|
||||
$ pipsi install pipenv
|
||||
.ft P
|
||||
.fi
|
||||
@@ -345,7 +344,7 @@ $ pipsi upgrade pipenv
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
This will install both \fBpipenv\fP and \fBpew\fP (one of our dependencies) in an isolated virtualenv, so it doesn\(aqt interfere with the rest of your Python installation!
|
||||
This will install \fBpipenv\fP in an isolated virtualenv, so it doesn\(aqt interfere with the rest of your Python installation!
|
||||
.SS ☤ Pragmatic Installation of Pipenv
|
||||
.sp
|
||||
If you have a working installation of pip, and maintain certain "toolchain" type Python modules as global utilities in your user environment, pip \fI\%user installs\fP allow for installation into your home directory. Note that due to interaction between dependencies, you should limit tools installed in this way to basic building blocks for a Python workflow like virtualenv, pipenv, tox, and similar software.
|
||||
@@ -1172,7 +1171,7 @@ will detect it.
|
||||
\fBPIPENV_SHELL_FANCY\fP — Always use fancy mode when invoking \fBpipenv shell\fP\&.
|
||||
.IP \(bu 2
|
||||
\fBPIPENV_VENV_IN_PROJECT\fP — If set, use \fB\&.venv\fP in your project directory
|
||||
instead of the global virtualenv manager \fBpew\fP\&.
|
||||
instead of the global location.
|
||||
.IP \(bu 2
|
||||
\fBPIPENV_COLORBLIND\fP — Disable terminal colors, for some reason.
|
||||
.IP \(bu 2
|
||||
@@ -1205,7 +1204,7 @@ $ PIP_INSTALL_OPTION="\-\- \-DCMAKE_BUILD_TYPE=Release" pipenv install \-e .
|
||||
.UNINDENT
|
||||
.SS ☤ Custom Virtual Environment Location
|
||||
.sp
|
||||
Pipenv\(aqs underlying \fBpew\fP dependency will automatically honor the \fBWORKON_HOME\fP environment
|
||||
Pipenv will automatically honor the \fBWORKON_HOME\fP environment
|
||||
variable, if you have it set —\ so you can tell pipenv to store your virtual environments wherever you want, e.g.:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
|
||||
+1
-1
@@ -920,7 +920,7 @@ def find_requirements(max_depth=3):
|
||||
raise RuntimeError("No requirements.txt found!")
|
||||
|
||||
|
||||
# Borrowed from pew to avoid importing pew which imports psutil
|
||||
# Borrowed from Pew.
|
||||
# See https://github.com/berdario/pew/blob/master/pew/_utils.py#L82
|
||||
@contextmanager
|
||||
def temp_environ():
|
||||
|
||||
@@ -111,7 +111,6 @@ setup(
|
||||
entry_points={
|
||||
"console_scripts": [
|
||||
"pipenv=pipenv:cli",
|
||||
"pewtwo=pipenv.patched.pew.pew:pew",
|
||||
"pipenv-resolver=pipenv.resolver:main",
|
||||
]
|
||||
},
|
||||
|
||||
@@ -8,7 +8,6 @@ from pipenv.utils import mkdir_p
|
||||
# from tempfile import TemporaryDirectory
|
||||
import tarfile
|
||||
import zipfile
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
import sys
|
||||
@@ -41,7 +40,6 @@ HARDCODED_LICENSE_URLS = {
|
||||
'semver': 'https://raw.githubusercontent.com/k-bx/python-semver/master/LICENSE.txt',
|
||||
'crayons': 'https://raw.githubusercontent.com/kennethreitz/crayons/master/LICENSE',
|
||||
'pip-tools': 'https://raw.githubusercontent.com/jazzband/pip-tools/master/LICENSE',
|
||||
'pew': 'https://raw.githubusercontent.com/berdario/pew/master/LICENSE',
|
||||
'pytoml': 'https://github.com/avakar/pytoml/raw/master/LICENSE',
|
||||
'webencodings': 'https://github.com/SimonSapin/python-webencodings/raw/'
|
||||
'master/LICENSE',
|
||||
@@ -141,7 +139,7 @@ def rewrite_imports(package_dir, vendored_libs, vendor_dir):
|
||||
def rewrite_file_imports(item, vendored_libs, vendor_dir):
|
||||
"""Rewrite 'import xxx' and 'from xxx import' for vendored_libs"""
|
||||
log('Reading file: %s' % item)
|
||||
try:
|
||||
try:
|
||||
text = item.read_text(encoding='utf-8')
|
||||
except UnicodeDecodeError:
|
||||
text = item.read_text(encoding='cp1252')
|
||||
@@ -489,7 +487,7 @@ def extract_license_member(vendor_dir, tar, member, name):
|
||||
def generate_patch(ctx, package_path, patch_description, base='HEAD'):
|
||||
pkg = Path(package_path)
|
||||
if len(pkg.parts) != 2 or pkg.parts[0] not in ('vendor', 'patched'):
|
||||
raise ValueError('example usage: generate-patch patched/pew some-description')
|
||||
raise ValueError('example usage: generate-patch patched/piptools some-description')
|
||||
if patch_description:
|
||||
patch_fn = '{0}-{1}.patch'.format(pkg.parts[1], patch_description)
|
||||
else:
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
diff --git a/pipenv/patched/pew/pew.py b/pipenv/patched/pew/pew.py
|
||||
index 2d3889a0..91f313c1 100644
|
||||
--- a/pipenv/patched/pew/pew.py
|
||||
+++ b/pipenv/patched/pew/pew.py
|
||||
@@ -184,7 +184,8 @@ def fork_bash(env, cwd):
|
||||
|
||||
def fork_cmder(env, cwd):
|
||||
shell_cmd = ['cmd']
|
||||
- cmderrc_path = r'%CMDER_ROOT%\vendor\init.bat'
|
||||
+ escaped_cmder_root = os.environ['CMDER_ROOT'].replace(' ', '^ ')
|
||||
+ cmderrc_path = r'{0}\vendor\init.bat'.format(escaped_cmder_root)
|
||||
if expandpath(cmderrc_path).exists():
|
||||
shell_cmd += ['/k', cmderrc_path]
|
||||
if cwd:
|
||||
@@ -1,13 +0,0 @@
|
||||
diff --git a/pipenv/patched/pew/pew.py b/pipenv/patched/pew/pew.py
|
||||
index 2d3889a0..07dbdf4f 100644
|
||||
--- a/pipenv/patched/pew/pew.py
|
||||
+++ b/pipenv/patched/pew/pew.py
|
||||
@@ -215,6 +215,8 @@ def shell(env, cwd=None):
|
||||
inve(env, shell, '-c', shell_check)
|
||||
except CalledProcessError:
|
||||
return
|
||||
+ if shell_name in ('Cmder', 'cmd'):
|
||||
+ os.environ['PROMPT'] = '({0}) {1}'.format(env, os.environ['PROMPT'])
|
||||
if shell_name == 'bash':
|
||||
fork_bash(env, cwd)
|
||||
elif shell_name == 'Cmder':
|
||||
@@ -1,287 +0,0 @@
|
||||
diff --git a/pipenv/patched/pew/_print_utils.py b/pipenv/patched/pew/_print_utils.py
|
||||
index 91a1d2b..05584e0 100644
|
||||
--- a/pipenv/patched/pew/_print_utils.py
|
||||
+++ b/pipenv/patched/pew/_print_utils.py
|
||||
@@ -9,7 +9,7 @@ except ImportError:
|
||||
try:
|
||||
from shutil import get_terminal_size
|
||||
except ImportError:
|
||||
- from backports.shutil_get_terminal_size import get_terminal_size
|
||||
+ from pipenv.vendor.backports.shutil_get_terminal_size import get_terminal_size
|
||||
|
||||
SEP = ' '
|
||||
L = len(SEP)
|
||||
diff --git a/pipenv/patched/pew/_utils.py b/pipenv/patched/pew/_utils.py
|
||||
index d1d8e0a..c45c37e 100644
|
||||
--- a/pipenv/patched/pew/_utils.py
|
||||
+++ b/pipenv/patched/pew/_utils.py
|
||||
@@ -6,7 +6,10 @@ from contextlib import contextmanager
|
||||
from subprocess import check_call, Popen, PIPE
|
||||
from collections import namedtuple
|
||||
from functools import partial, wraps
|
||||
-from pathlib import Path
|
||||
+try:
|
||||
+ from pathlib import Path
|
||||
+except ImportError:
|
||||
+ from pipenv.vendor.pathlib2 import Path
|
||||
from tempfile import NamedTemporaryFile as _ntf
|
||||
try:
|
||||
from shutil import which
|
||||
diff --git a/pipenv/patched/pew/pew.py b/pipenv/patched/pew/pew.py
|
||||
index bcaabad..b8fc3e7 100644
|
||||
--- a/pipenv/patched/pew/pew.py
|
||||
+++ b/pipenv/patched/pew/pew.py
|
||||
@@ -8,12 +8,15 @@ import random
|
||||
import textwrap
|
||||
from functools import partial
|
||||
from subprocess import CalledProcessError
|
||||
-from pathlib import Path
|
||||
+try:
|
||||
+ from pathlib import Path
|
||||
+except ImportError:
|
||||
+ from pipenv.vendor.pathlib2 import Path
|
||||
|
||||
try:
|
||||
from shutil import get_terminal_size
|
||||
except ImportError:
|
||||
- from backports.shutil_get_terminal_size import get_terminal_size
|
||||
+ from pipenv.vendor.backports.shutil_get_terminal_size import get_terminal_size
|
||||
|
||||
windows = sys.platform == 'win32'
|
||||
|
||||
@@ -36,7 +39,7 @@ else:
|
||||
InstallCommand = ListPythons = LocatePython = UninstallCommand = \
|
||||
lambda : sys.exit('Command not supported on this platform')
|
||||
|
||||
- import psutil
|
||||
+ from ._win_utils import get_shell
|
||||
|
||||
from pew._utils import (check_call, invoke, expandpath, own, env_bin_dir,
|
||||
check_path, temp_environ, NamedTemporaryFile, to_unicode)
|
||||
@@ -52,8 +55,9 @@ if windows:
|
||||
else:
|
||||
default_home = os.path.join(
|
||||
os.environ.get('XDG_DATA_HOME', '~/.local/share'), 'virtualenvs')
|
||||
-workon_home = expandpath(
|
||||
- os.environ.get('WORKON_HOME', default_home))
|
||||
+
|
||||
+def get_workon_home():
|
||||
+ return expandpath(os.environ.get('WORKON_HOME', default_home))
|
||||
|
||||
|
||||
def makedirs_and_symlink_if_needed(workon_home):
|
||||
@@ -96,7 +100,7 @@ def deploy_completions():
|
||||
|
||||
|
||||
def get_project_dir(env):
|
||||
- project_file = workon_home / env / '.project'
|
||||
+ project_file = get_workon_home() / env / '.project'
|
||||
if project_file.exists():
|
||||
with project_file.open() as f:
|
||||
project_dir = f.readline().strip()
|
||||
@@ -113,7 +117,7 @@ def unsetenv(key):
|
||||
|
||||
|
||||
def compute_path(env):
|
||||
- envdir = workon_home / env
|
||||
+ envdir = get_workon_home() / env
|
||||
return os.pathsep.join([
|
||||
str(envdir / env_bin_dir),
|
||||
os.environ['PATH'],
|
||||
@@ -127,7 +131,7 @@ def inve(env, command, *args, **kwargs):
|
||||
# we don't strictly need to restore the environment, since pew runs in
|
||||
# its own process, but it feels like the right thing to do
|
||||
with temp_environ():
|
||||
- os.environ['VIRTUAL_ENV'] = str(workon_home / env)
|
||||
+ os.environ['VIRTUAL_ENV'] = str(get_workon_home() / env)
|
||||
os.environ['PATH'] = compute_path(env)
|
||||
|
||||
unsetenv('PYTHONHOME')
|
||||
@@ -151,7 +155,16 @@ def fork_shell(env, shellcmd, cwd):
|
||||
if 'VIRTUAL_ENV' in os.environ:
|
||||
err("Be aware that this environment will be nested on top "
|
||||
"of '%s'" % Path(os.environ['VIRTUAL_ENV']).name)
|
||||
- inve(env, *shellcmd, cwd=cwd)
|
||||
+ try:
|
||||
+ inve(env, *shellcmd, cwd=cwd)
|
||||
+ except CalledProcessError:
|
||||
+ # These shells report errors when the last command executed in the
|
||||
+ # subshell in an error. This causes the subprocess to fail, which is
|
||||
+ # not what we want. Stay silent for them, there's nothing we can do.
|
||||
+ shell_name, _ = os.path.splitext(os.path.basename(shellcmd[0]))
|
||||
+ suppress_error = shell_name.lower() in ('cmd', 'powershell', 'pwsh')
|
||||
+ if not suppress_error:
|
||||
+ raise
|
||||
|
||||
|
||||
def fork_bash(env, cwd):
|
||||
@@ -184,7 +197,7 @@ def _detect_shell():
|
||||
if 'CMDER_ROOT' in os.environ:
|
||||
shell = 'Cmder'
|
||||
elif windows:
|
||||
- shell = psutil.Process(os.getpid()).parent().parent().name()
|
||||
+ shell = get_shell(os.getpid())
|
||||
else:
|
||||
shell = 'sh'
|
||||
return shell
|
||||
@@ -193,10 +206,10 @@ def shell(env, cwd=None):
|
||||
env = str(env)
|
||||
shell = _detect_shell()
|
||||
shell_name = Path(shell).stem
|
||||
- if shell_name not in ('Cmder', 'bash', 'elvish', 'powershell', 'klingon', 'cmd'):
|
||||
+ if shell_name not in ('Cmder', 'bash', 'elvish', 'powershell', 'pwsh', 'klingon', 'cmd'):
|
||||
# On Windows the PATH is usually set with System Utility
|
||||
# so we won't worry about trying to check mistakes there
|
||||
- shell_check = (sys.executable + ' -c "from pew.pew import '
|
||||
+ shell_check = (sys.executable + ' -c "from pipenv.patched.pew.pew import '
|
||||
'prevent_path_errors; prevent_path_errors()"')
|
||||
try:
|
||||
inve(env, shell, '-c', shell_check)
|
||||
@@ -216,7 +229,7 @@ def mkvirtualenv(envname, python=None, packages=[], project=None,
|
||||
if python:
|
||||
rest = ["--python=%s" % python] + rest
|
||||
|
||||
- path = (workon_home / envname).absolute()
|
||||
+ path = (get_workon_home() / envname).absolute()
|
||||
|
||||
try:
|
||||
check_call([sys.executable, "-m", "virtualenv", str(path)] + rest)
|
||||
@@ -265,7 +278,7 @@ project directory to associate with the new environment.')
|
||||
def rmvirtualenvs(envs):
|
||||
error_happened = False
|
||||
for env in envs:
|
||||
- env = workon_home / env
|
||||
+ env = get_workon_home() / env
|
||||
if os.environ.get('VIRTUAL_ENV') == str(env):
|
||||
err("ERROR: You cannot remove the active environment (%s)." % env)
|
||||
error_happened = True
|
||||
@@ -295,7 +308,7 @@ def packages(site_packages):
|
||||
def showvirtualenv(env):
|
||||
columns, _ = get_terminal_size()
|
||||
pkgs = sorted(packages(sitepackages_dir(env)))
|
||||
- env_python = workon_home / env / env_bin_dir / 'python'
|
||||
+ env_python = get_workon_home() / env / env_bin_dir / 'python'
|
||||
l = len(env) + 2
|
||||
version = invoke(str(env_python), '-V')
|
||||
version = ' - '.join((version.out + version.err).splitlines())
|
||||
@@ -317,8 +330,8 @@ def show_cmd(argv):
|
||||
|
||||
|
||||
def lsenvs():
|
||||
- return sorted(set(env.parts[-3] for env in
|
||||
- workon_home.glob(os.path.join('*', env_bin_dir, 'python*'))))
|
||||
+ items = get_workon_home().glob(os.path.join('*', env_bin_dir, 'python*'))
|
||||
+ return sorted(set(env.parts[-3] for env in items))
|
||||
|
||||
|
||||
def lsvirtualenv(verbose):
|
||||
@@ -347,7 +360,7 @@ def parse_envname(argv, no_arg_callback):
|
||||
env = argv[0]
|
||||
if env.startswith('/'):
|
||||
sys.exit("ERROR: Invalid environment name '{0}'.".format(env))
|
||||
- if not (workon_home / env).exists():
|
||||
+ if not (get_workon_home() / env).exists():
|
||||
sys.exit("ERROR: Environment '{0}' does not exist. Create it with \
|
||||
'pew new {0}'.".format(env))
|
||||
else:
|
||||
@@ -372,7 +385,7 @@ def sitepackages_dir(env=os.environ.get('VIRTUAL_ENV')):
|
||||
if not env:
|
||||
sys.exit('ERROR: no virtualenv active')
|
||||
else:
|
||||
- env_python = workon_home / env / env_bin_dir / 'python'
|
||||
+ env_python = get_workon_home() / env / env_bin_dir / 'python'
|
||||
return Path(invoke(str(env_python), '-c', 'import distutils; \
|
||||
print(distutils.sysconfig.get_python_lib())').out)
|
||||
|
||||
@@ -459,6 +472,7 @@ def cp_cmd(argv):
|
||||
|
||||
def copy_virtualenv_project(source, target):
|
||||
source = expandpath(source)
|
||||
+ workon_home = get_workon_home()
|
||||
if not source.exists():
|
||||
source = workon_home / source
|
||||
if not source.exists():
|
||||
@@ -490,7 +504,7 @@ def rename_cmd(argv):
|
||||
|
||||
def setvirtualenvproject(env, project):
|
||||
print('Setting project for {0} to {1}'.format(env, project))
|
||||
- with (workon_home / env / '.project').open('wb') as prj:
|
||||
+ with (get_workon_home() / env / '.project').open('wb') as prj:
|
||||
prj.write(str(project).encode())
|
||||
|
||||
|
||||
@@ -502,7 +516,7 @@ def setproject_cmd(argv):
|
||||
env = args.get(0, os.environ.get('VIRTUAL_ENV'))
|
||||
if not env:
|
||||
sys.exit('pew setproject [virtualenv] [project_path]')
|
||||
- if not (workon_home / env).exists():
|
||||
+ if not (get_workon_home() / env).exists():
|
||||
sys.exit("Environment '%s' doesn't exist." % env)
|
||||
if not os.path.isdir(project):
|
||||
sys.exit('pew setproject: %s does not exist' % project)
|
||||
@@ -512,7 +526,7 @@ def setproject_cmd(argv):
|
||||
def mkproject_cmd(argv):
|
||||
"""Create a new project directory and its associated virtualenv."""
|
||||
if '-l' in argv or '--list' in argv:
|
||||
- templates = [t.name[9:] for t in workon_home.glob("template_*")]
|
||||
+ templates = [t.name[9:] for t in get_workon_home().glob("template_*")]
|
||||
print("Available project templates:", *templates, sep='\n')
|
||||
return
|
||||
|
||||
@@ -542,7 +556,7 @@ Create it or set PROJECT_HOME to an existing directory.' % projects_home)
|
||||
project.mkdir()
|
||||
|
||||
for template_name in args.templates:
|
||||
- template = workon_home / ("template_" + template_name)
|
||||
+ template = get_workon_home() / ("template_" + template_name)
|
||||
inve(args.envname, str(template), args.envname, str(project))
|
||||
if args.activate:
|
||||
shell(args.envname, cwd=str(project))
|
||||
@@ -552,7 +566,7 @@ def mktmpenv_cmd(argv):
|
||||
"""Create a temporary virtualenv."""
|
||||
parser = mkvirtualenv_argparser()
|
||||
env = '.'
|
||||
- while (workon_home / env).exists():
|
||||
+ while (get_workon_home() / env).exists():
|
||||
env = hex(random.getrandbits(64))[2:-1]
|
||||
|
||||
args, rest = parser.parse_known_args(argv)
|
||||
@@ -574,10 +588,10 @@ def wipeenv_cmd(argv):
|
||||
|
||||
if not env:
|
||||
sys.exit('ERROR: no virtualenv active')
|
||||
- elif not (workon_home / env).exists():
|
||||
+ elif not (get_workon_home() / env).exists():
|
||||
sys.exit("ERROR: Environment '{0}' does not exist.".format(env))
|
||||
else:
|
||||
- env_pip = str(workon_home / env / env_bin_dir / 'pip')
|
||||
+ env_pip = str(get_workon_home() / env / env_bin_dir / 'pip')
|
||||
all_pkgs = set(invoke(env_pip, 'freeze').out.splitlines())
|
||||
pkgs = set(p for p in all_pkgs if len(p.split("==")) == 2)
|
||||
ignored = sorted(all_pkgs - pkgs)
|
||||
@@ -623,6 +637,7 @@ def restore_cmd(argv):
|
||||
sys.exit('You must provide a valid virtualenv to target')
|
||||
|
||||
env = argv[0]
|
||||
+ path = get_workon_home() / env
|
||||
path = workon_home / env
|
||||
py = path / env_bin_dir / ('python.exe' if windows else 'python')
|
||||
exact_py = py.resolve().name
|
||||
@@ -633,7 +648,7 @@ def restore_cmd(argv):
|
||||
def dir_cmd(argv):
|
||||
"""Print the path for the virtualenv directory"""
|
||||
env = parse_envname(argv, lambda : sys.exit('You must provide a valid virtualenv to target'))
|
||||
- print(workon_home / env)
|
||||
+ print(get_workon_home() / env)
|
||||
|
||||
|
||||
def install_cmd(argv):
|
||||
@@ -745,7 +760,7 @@ def print_commands(cmds):
|
||||
|
||||
|
||||
def pew():
|
||||
- first_run = makedirs_and_symlink_if_needed(workon_home)
|
||||
+ first_run = makedirs_and_symlink_if_needed(get_workon_home())
|
||||
if first_run and sys.stdin.isatty():
|
||||
first_run_setup()
|
||||
|
||||
@@ -1,151 +0,0 @@
|
||||
diff --git a/pipenv/patched/pew/__main__.py b/pipenv/patched/pew/__main__.py
|
||||
index e35cf68..2267b8d 100644
|
||||
--- a/pipenv/patched/pew/__main__.py
|
||||
+++ b/pipenv/patched/pew/__main__.py
|
||||
@@ -1,3 +1,4 @@
|
||||
-from pew.pew import pew
|
||||
+from . import pew
|
||||
|
||||
-pew()
|
||||
+if __name__ == '__main__':
|
||||
+ pew.pew.pew()
|
||||
diff --git a/pipenv/patched/pew/_win_utils.py b/pipenv/patched/pew/_win_utils.py
|
||||
new file mode 100644
|
||||
index 0000000..8ab7a0b
|
||||
--- /dev/null
|
||||
+++ b/pipenv/patched/pew/_win_utils.py
|
||||
@@ -0,0 +1,121 @@
|
||||
+# -*- coding=utf-8 -*-
|
||||
+# psutil is painfully slow in win32. So to avoid adding big
|
||||
+# dependencies like pywin32 a ctypes based solution is preferred
|
||||
+
|
||||
+# Code based on the winappdbg project http://winappdbg.sourceforge.net/
|
||||
+# (BSD License) - adapted from Celery
|
||||
+# https://github.com/celery/celery/blob/2.5-archived/celery/concurrency/processes/_win.py
|
||||
+import os
|
||||
+import six
|
||||
+from ctypes import (
|
||||
+ byref, sizeof, windll, Structure, WinError, POINTER,
|
||||
+ c_size_t, c_char, c_void_p
|
||||
+)
|
||||
+from ctypes.wintypes import DWORD, LONG
|
||||
+
|
||||
+ERROR_NO_MORE_FILES = 18
|
||||
+INVALID_HANDLE_VALUE = c_void_p(-1).value
|
||||
+SHELL_NAMES = ['cmd', 'powershell', 'pwsh', 'cmder']
|
||||
+
|
||||
+
|
||||
+class PROCESSENTRY32(Structure):
|
||||
+ _fields_ = [
|
||||
+ ('dwSize', DWORD),
|
||||
+ ('cntUsage', DWORD),
|
||||
+ ('th32ProcessID', DWORD),
|
||||
+ ('th32DefaultHeapID', c_size_t),
|
||||
+ ('th32ModuleID', DWORD),
|
||||
+ ('cntThreads', DWORD),
|
||||
+ ('th32ParentProcessID', DWORD),
|
||||
+ ('pcPriClassBase', LONG),
|
||||
+ ('dwFlags', DWORD),
|
||||
+ ('szExeFile', c_char * 260),
|
||||
+ ]
|
||||
+
|
||||
+
|
||||
+LPPROCESSENTRY32 = POINTER(PROCESSENTRY32)
|
||||
+
|
||||
+
|
||||
+def CreateToolhelp32Snapshot(dwFlags=2, th32ProcessID=0):
|
||||
+ hSnapshot = windll.kernel32.CreateToolhelp32Snapshot(
|
||||
+ dwFlags,
|
||||
+ th32ProcessID
|
||||
+ )
|
||||
+ if hSnapshot == INVALID_HANDLE_VALUE:
|
||||
+ raise WinError()
|
||||
+ return hSnapshot
|
||||
+
|
||||
+
|
||||
+def Process32First(hSnapshot):
|
||||
+ pe = PROCESSENTRY32()
|
||||
+ pe.dwSize = sizeof(PROCESSENTRY32)
|
||||
+ success = windll.kernel32.Process32First(hSnapshot, byref(pe))
|
||||
+ if not success:
|
||||
+ if windll.kernel32.GetLastError() == ERROR_NO_MORE_FILES:
|
||||
+ return
|
||||
+ raise WinError()
|
||||
+ return pe
|
||||
+
|
||||
+
|
||||
+def Process32Next(hSnapshot, pe=None):
|
||||
+ if pe is None:
|
||||
+ pe = PROCESSENTRY32()
|
||||
+ pe.dwSize = sizeof(PROCESSENTRY32)
|
||||
+ success = windll.kernel32.Process32Next(hSnapshot, byref(pe))
|
||||
+ if not success:
|
||||
+ if windll.kernel32.GetLastError() == ERROR_NO_MORE_FILES:
|
||||
+ return
|
||||
+ raise WinError()
|
||||
+ return pe
|
||||
+
|
||||
+
|
||||
+def get_all_processes():
|
||||
+ """Return a dictionary of properties about all processes.
|
||||
+
|
||||
+ >>> get_all_processes()
|
||||
+ {
|
||||
+ 1509: {
|
||||
+ 'parent_pid': 1201,
|
||||
+ 'executable': 'C:\\Program\\\\ Files\\Python36\\python.exe'
|
||||
+ }
|
||||
+ }
|
||||
+ """
|
||||
+ h_process = CreateToolhelp32Snapshot()
|
||||
+ pids = {}
|
||||
+ pe = Process32First(h_process)
|
||||
+ while pe:
|
||||
+ pids[pe.th32ProcessID] = {
|
||||
+ 'executable': str(pe.szExeFile.decode('utf-8'))
|
||||
+ }
|
||||
+ if pe.th32ParentProcessID:
|
||||
+ pids[pe.th32ProcessID]['parent_pid'] = pe.th32ParentProcessID
|
||||
+ pe = Process32Next(h_process, pe)
|
||||
+
|
||||
+ return pids
|
||||
+
|
||||
+
|
||||
+def _get_executable(process_dict):
|
||||
+ if hasattr(process_dict, 'keys'):
|
||||
+ executable = process_dict.get('executable')
|
||||
+ if isinstance(executable, six.string_types):
|
||||
+ return executable.lower().rsplit('.', 1)[0]
|
||||
+ return ''
|
||||
+
|
||||
+
|
||||
+def get_shell(pid=None, max_depth=6):
|
||||
+ """Get the shell that the supplied pid or os.getpid() is running in.
|
||||
+ """
|
||||
+ if not pid:
|
||||
+ pid = os.getpid()
|
||||
+ processes = get_all_processes()
|
||||
+
|
||||
+ def check_parent(pid, lvl=0):
|
||||
+ ppid = processes[pid].get('parent_pid')
|
||||
+ if ppid and _get_executable(processes.get(ppid)) in SHELL_NAMES:
|
||||
+ return processes[ppid]['executable']
|
||||
+ if lvl >= max_depth:
|
||||
+ return
|
||||
+ return check_parent(ppid, lvl=lvl+1)
|
||||
+ if _get_executable(processes.get(pid)) in SHELL_NAMES:
|
||||
+ return processes[pid]['executable']
|
||||
+ return check_parent(pid)
|
||||
diff --git a/pipenv/patched/pew/template_django b/pipenv/patched/pew/template_django
|
||||
new file mode 100644
|
||||
index 0000000..4fec88e
|
||||
--- /dev/null
|
||||
+++ b/pipenv/patched/pew/template_django
|
||||
@@ -0,0 +1,6 @@
|
||||
+#! /bin/sh
|
||||
+# put this inside $WORKON_HOME
|
||||
+project=$1
|
||||
+project_dir=$2
|
||||
+pip install django
|
||||
+django-admin.py startproject "$project"
|
||||
\ No newline at end of file
|
||||
@@ -39,48 +39,3 @@ def test_reuse_previous_venv(PipenvInstance, pypi):
|
||||
c = p.pipenv('install requests')
|
||||
assert c.return_code == 0
|
||||
assert normalize_drive(p.path) in p.pipenv('--venv').out
|
||||
|
||||
|
||||
@pytest.mark.dotvenv
|
||||
@pytest.mark.install
|
||||
@pytest.mark.complex
|
||||
@pytest.mark.shell
|
||||
@pytest.mark.windows
|
||||
@pytest.mark.pew
|
||||
@pytest.mark.skip('Not mocking this.')
|
||||
def test_shell_nested_venv_in_project(PipenvInstance, pypi):
|
||||
import subprocess
|
||||
with temp_environ():
|
||||
os.environ['PIPENV_VENV_IN_PROJECT'] = '1'
|
||||
os.environ['PIPENV_IGNORE_VIRTUALENVS'] = '1'
|
||||
with PipenvInstance(chdir=True, pypi=pypi) as p:
|
||||
# Signal to pew to look in the project directory for the environment
|
||||
os.environ['WORKON_HOME'] = p.path
|
||||
c = p.pipenv('install requests')
|
||||
assert c.return_code == 0
|
||||
assert 'requests' in p.pipfile['packages']
|
||||
assert 'requests' in p.lockfile['default']
|
||||
# Check that .venv now shows in pew's managed list
|
||||
pew_list = delegator.run('pewtwo ls')
|
||||
assert '.venv' in pew_list.out
|
||||
# Check for the venv directory
|
||||
c = delegator.run('pewtwo dir .venv')
|
||||
# Compare pew's virtualenv path to what we expect
|
||||
venv_path = get_windows_path(Project().project_directory, '.venv')
|
||||
# os.path.normpath will normalize slashes
|
||||
assert venv_path == normalize_drive(os.path.normpath(c.out.strip()))
|
||||
# Have pew run 'pip freeze' in the virtualenv
|
||||
# This is functionally the same as spawning a subshell
|
||||
# If we can do this we can theoretically make a subshell
|
||||
# This test doesn't work on *nix
|
||||
if os.name == 'nt':
|
||||
process = subprocess.Popen(
|
||||
'pewtwo in .venv pip freeze',
|
||||
shell=True,
|
||||
universal_newlines=True,
|
||||
stdin=subprocess.PIPE,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE
|
||||
)
|
||||
out, _ = process.communicate()
|
||||
assert any(req.startswith('requests') for req in out.splitlines()) is True
|
||||
|
||||
@@ -350,10 +350,7 @@ def test_editable_no_args(PipenvInstance):
|
||||
@pytest.mark.install
|
||||
@pytest.mark.virtualenv
|
||||
def test_install_venv_project_directory(PipenvInstance, pypi):
|
||||
"""Test pew's project functionality during virtualenv creation.
|
||||
|
||||
Since .venv virtualenvs are not created with pew, we need to swap to a
|
||||
workon_home based virtualenv for this test.
|
||||
"""Test the project functionality during virtualenv creation.
|
||||
"""
|
||||
with PipenvInstance(pypi=pypi, chdir=True) as p:
|
||||
with temp_environ(), TemporaryDirectory(
|
||||
|
||||
@@ -84,7 +84,7 @@ def test_update_locks(PipenvInstance, pypi):
|
||||
@pytest.mark.project
|
||||
@pytest.mark.proper_names
|
||||
def test_proper_names_unamanged_virtualenv(PipenvInstance, pypi):
|
||||
with PipenvInstance(chdir=True, pypi=pypi) as p:
|
||||
with PipenvInstance(chdir=True, pypi=pypi):
|
||||
c = delegator.run('python -m virtualenv .venv')
|
||||
assert c.return_code == 0
|
||||
project = Project()
|
||||
@@ -100,8 +100,6 @@ def test_directory_with_leading_dash(PipenvInstance):
|
||||
|
||||
with mock.patch('pipenv._compat.mkdtemp', side_effect=mocked_mkdtemp):
|
||||
with temp_environ(), PipenvInstance(chdir=True) as p:
|
||||
# This environment variable is set in the context manager and will
|
||||
# cause pipenv to use virtualenv, not pew.
|
||||
del os.environ['PIPENV_VENV_IN_PROJECT']
|
||||
p.pipenv('--python python')
|
||||
venv_path = p.pipenv('--venv').out.strip()
|
||||
|
||||
Reference in New Issue
Block a user