mirror of
https://github.com/kennethreitz/pipenv.git
synced 2026-06-05 22:50:18 +00:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
+12
@@ -1,3 +1,15 @@
|
||||
6.1.5:
|
||||
- Grab hashes for un-grabbable hashes.
|
||||
6.1.4:
|
||||
- New update via $ pipenv --update, instead.
|
||||
6.1.3:
|
||||
- Skip validation of Pipfiles, massive speedup for far-away users.
|
||||
- Other speed-ups.
|
||||
6.1.1:
|
||||
- Bug fix.
|
||||
6.1.0:
|
||||
- Self–updating! Very fancy. $ pipenv update.
|
||||
- Verbose mode for update, install.
|
||||
6.0.3:
|
||||
- Major bug fix.
|
||||
- Fix for Daniel Ryan's weird corner case.
|
||||
|
||||
+1
-1
@@ -48,7 +48,7 @@ install:
|
||||
# about it being out of date.
|
||||
- "pip install --disable-pip-version-check --user --upgrade pip"
|
||||
- "pip install -e . --upgrade"
|
||||
- "pipenv install --dev"
|
||||
- "pipenv install --dev --skip-lock"
|
||||
|
||||
test_script:
|
||||
- "pipenv run pytest test_windows/ tests/test_utils.py tests/test_project.py"
|
||||
|
||||
@@ -253,7 +253,6 @@ $ pipenv lock
|
||||
variables. To activate them, simply create the variable in your shell and pipenv
|
||||
will detect it.
|
||||
|
||||
- ``PIPENV_SKIP_VALIDATION`` — Tells Pipenv to skip ``Pipfile`` validation (case-checking) — useful for slow internet connections.
|
||||
- ``PIPENV_SHELL_COMPAT`` — Toggle from our default ``pipenv shell`` mode to classic.
|
||||
(Suggested for use with pyenv).
|
||||
|
||||
|
||||
@@ -3,4 +3,4 @@
|
||||
# //___/ / / / //___/ / // // / / || / /
|
||||
# // / / // ((____ // / / ||/ /
|
||||
|
||||
__version__ = '6.0.3'
|
||||
__version__ = '6.1.5'
|
||||
|
||||
+84
-29
@@ -73,14 +73,45 @@ def check_for_updates():
|
||||
current = semver.parse_version_info(__version__)
|
||||
|
||||
if latest > current:
|
||||
click.echo('{0}: {1} is now available. You get bonus points for upgrading!'.format(
|
||||
click.echo('{0}: {1} is now available. You get bonus points for upgrading ($ {})!'.format(
|
||||
crayons.green('Courtesy Notice'),
|
||||
crayons.yellow('Pipenv v{v.major}.{v.minor}.{v.patch}'.format(v=latest)),
|
||||
crayons.yellow('Pipenv {v.major}.{v.minor}.{v.patch}'.format(v=latest)),
|
||||
crayons.red('pipenv --update')
|
||||
), err=True)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
def enhance(user=False):
|
||||
r = requests.get('https://pypi.python.org/pypi/pipenv/json', timeout=0.5)
|
||||
latest = sorted([semver.parse_version_info(v) for v in list(r.json()['releases'].keys())])[-1]
|
||||
current = semver.parse_version_info(__version__)
|
||||
|
||||
if current < latest:
|
||||
|
||||
import site
|
||||
|
||||
click.echo('{0}: {1} is now available. Automatically upgrading!'.format(
|
||||
crayons.green('Courtesy Notice'),
|
||||
crayons.yellow('Pipenv {v.major}.{v.minor}.{v.patch}'.format(v=latest)),
|
||||
), err=True)
|
||||
|
||||
# Resolve user site, enable user mode automatically.
|
||||
if site.ENABLE_USER_SITE and site.USER_SITE in sys.modules['pipenv'].__file__:
|
||||
args = ['install', '--upgrade', 'pipenv']
|
||||
else:
|
||||
args = ['install', '--user', '--upgrade', 'pipenv']
|
||||
|
||||
sys.modules['pip'].main(args)
|
||||
|
||||
click.echo('{0} to {1}!'.format(
|
||||
crayons.green('Pipenv updated'),
|
||||
crayons.yellow('{v.major}.{v.minor}.{v.patch}'.format(v=latest))
|
||||
))
|
||||
else:
|
||||
click.echo(crayons.green('All good!'))
|
||||
|
||||
|
||||
def cleanup_virtualenv(bare=True):
|
||||
"""Removes the virtualenv directory from the system."""
|
||||
|
||||
@@ -104,7 +135,10 @@ def ensure_latest_pip():
|
||||
if 'however' in c.err:
|
||||
# If version is out of date, update.
|
||||
click.echo(crayons.yellow('Pip is out of date... updating to latest.'))
|
||||
c = delegator.run('"{0}" install pip --upgrade'.format(which_pip()), block=False)
|
||||
|
||||
windows = '-m' if os.name == 'nt' else ''
|
||||
|
||||
c = delegator.run('"{0}" install {1} pip --upgrade'.format(which_pip()), windows, block=False)
|
||||
click.echo(crayons.blue(c.out))
|
||||
|
||||
|
||||
@@ -135,6 +169,8 @@ def ensure_pipfile(validate=True):
|
||||
else:
|
||||
project.add_package_to_pipfile(str(package.req))
|
||||
|
||||
project.recase_pipfile()
|
||||
|
||||
else:
|
||||
click.echo(crayons.yellow('Creating a Pipfile for this project...'), err=True)
|
||||
# Create the pipfile if it doesn't exist.
|
||||
@@ -242,7 +278,7 @@ def do_where(virtualenv=False, bare=True):
|
||||
click.echo(location)
|
||||
|
||||
|
||||
def do_install_dependencies(dev=False, only=False, bare=False, requirements=False, allow_global=False, ignore_hashes=False, skip_lock=False):
|
||||
def do_install_dependencies(dev=False, only=False, bare=False, requirements=False, allow_global=False, ignore_hashes=False, skip_lock=False, verbose=False):
|
||||
""""Executes the install functionality."""
|
||||
|
||||
if requirements:
|
||||
@@ -259,6 +295,7 @@ def do_install_dependencies(dev=False, only=False, bare=False, requirements=Fals
|
||||
with open(project.lockfile_location) as f:
|
||||
lockfile = split_vcs(json.load(f))
|
||||
|
||||
# Allow pip to resolve dependencies when in skip-lock mode.
|
||||
no_deps = (not skip_lock)
|
||||
|
||||
# Install default dependencies, always.
|
||||
@@ -289,7 +326,7 @@ def do_install_dependencies(dev=False, only=False, bare=False, requirements=Fals
|
||||
# pip install:
|
||||
for dep, ignore_hash in progress.bar(deps_list):
|
||||
|
||||
c = pip_install(dep, ignore_hashes=ignore_hash, allow_global=allow_global, no_deps=no_deps)
|
||||
c = pip_install(dep, ignore_hashes=ignore_hash, allow_global=allow_global, no_deps=no_deps, verbose=verbose)
|
||||
|
||||
if c.return_code != 0:
|
||||
click.echo(crayons.red('An error occured while installing!'))
|
||||
@@ -620,7 +657,7 @@ def do_purge(bare=False, downloads=False, allow_global=False):
|
||||
click.echo(crayons.yellow('Environment now purged and fresh!'))
|
||||
|
||||
|
||||
def do_init(dev=False, requirements=False, allow_global=False, ignore_hashes=False, no_hashes=True, ignore_pipfile=False, skip_lock=False):
|
||||
def do_init(dev=False, requirements=False, allow_global=False, ignore_hashes=False, no_hashes=True, ignore_pipfile=False, skip_lock=False, verbose=False):
|
||||
"""Executes the init functionality."""
|
||||
|
||||
ensure_pipfile()
|
||||
@@ -663,14 +700,14 @@ def do_init(dev=False, requirements=False, allow_global=False, ignore_hashes=Fal
|
||||
ignore_hashes = False
|
||||
|
||||
do_install_dependencies(dev=dev, requirements=requirements, allow_global=allow_global,
|
||||
ignore_hashes=ignore_hashes, skip_lock=skip_lock)
|
||||
ignore_hashes=ignore_hashes, skip_lock=skip_lock, verbose=verbose)
|
||||
|
||||
# Activate virtualenv instructions.
|
||||
if not allow_global:
|
||||
do_activate_virtualenv()
|
||||
|
||||
|
||||
def pip_install(package_name=None, r=None, allow_global=False, ignore_hashes=False, no_deps=True):
|
||||
def pip_install(package_name=None, r=None, allow_global=False, ignore_hashes=False, no_deps=True, verbose=False):
|
||||
|
||||
# Create files for hash mode.
|
||||
if (not ignore_hashes) and (r is None):
|
||||
@@ -702,6 +739,10 @@ def pip_install(package_name=None, r=None, allow_global=False, ignore_hashes=Fal
|
||||
no_deps = '--no-deps' if no_deps else ''
|
||||
|
||||
pip_command = '"{0}" install {3} {1} -i {2}'.format(which_pip(allow_global=allow_global), install_reqs, source['url'], no_deps)
|
||||
|
||||
if verbose:
|
||||
click.echo('$ {0}'.format(pip_command), err=True)
|
||||
|
||||
c = delegator.run(pip_command)
|
||||
|
||||
if c.return_code == 0:
|
||||
@@ -804,6 +845,7 @@ def easter_egg(package_name):
|
||||
|
||||
|
||||
@click.group(invoke_without_command=True)
|
||||
@click.option('--update', is_flag=True, default=False, help="Upate pipenv & pip.")
|
||||
@click.option('--where', is_flag=True, default=False, help="Output project home information.")
|
||||
@click.option('--venv', is_flag=True, default=False, help="Output virtualenv information.")
|
||||
@click.option('--rm', is_flag=True, default=False, help="Remove the virtualenv.")
|
||||
@@ -813,9 +855,18 @@ def easter_egg(package_name):
|
||||
@click.option('--help', '-h', is_flag=True, default=None, help="Show this message then exit.")
|
||||
@click.version_option(prog_name=crayons.yellow('pipenv'), version=__version__)
|
||||
@click.pass_context
|
||||
def cli(ctx, where=False, venv=False, rm=False, bare=False, three=False, python=False, help=False):
|
||||
def cli(ctx, where=False, venv=False, rm=False, bare=False, three=False, python=False, help=False, update=False):
|
||||
|
||||
check_for_updates()
|
||||
if not update:
|
||||
check_for_updates()
|
||||
else:
|
||||
# Update pip to latest version.
|
||||
ensure_latest_pip()
|
||||
|
||||
# Upgrade self to latest version.
|
||||
enhance()
|
||||
|
||||
sys.exit()
|
||||
|
||||
if ctx.invoked_subcommand is None:
|
||||
# --where was passed...
|
||||
@@ -869,9 +920,10 @@ def cli(ctx, where=False, venv=False, rm=False, bare=False, three=False, python=
|
||||
@click.option('--three/--two', is_flag=True, default=None, help="Use Python 3/2 when creating virtualenv.")
|
||||
@click.option('--python', default=False, nargs=1, help="Specify which version of Python virtualenv should use.")
|
||||
@click.option('--system', is_flag=True, default=False, help="System pip management.")
|
||||
@click.option('--verbose', is_flag=True, default=False, help="Verbose mode.")
|
||||
@click.option('--ignore-pipfile', is_flag=True, default=False, help="Ignore Pipfile when installing, using the Pipfile.lock.")
|
||||
@click.option('--skip-lock', is_flag=True, default=False, help=u"Ignore locking mechanisms when installing—use the Pipfile, instead.")
|
||||
def install(package_name=False, more_packages=False, dev=False, three=False, python=False, system=False, lock=True, hashes=True, ignore_pipfile=False, skip_lock=False):
|
||||
def install(package_name=False, more_packages=False, dev=False, three=False, python=False, system=False, lock=True, hashes=True, ignore_pipfile=False, skip_lock=False, verbose=False):
|
||||
|
||||
# Automatically use an activated virtualenv.
|
||||
if PIPENV_USE_SYSTEM:
|
||||
@@ -895,7 +947,7 @@ def install(package_name=False, more_packages=False, dev=False, three=False, pyt
|
||||
if package_name is False:
|
||||
click.echo(crayons.yellow('No package provided, installing all dependencies.'), err=True)
|
||||
|
||||
do_init(dev=dev, allow_global=system, ignore_hashes=not hashes, ignore_pipfile=ignore_pipfile, skip_lock=skip_lock)
|
||||
do_init(dev=dev, allow_global=system, ignore_hashes=not hashes, ignore_pipfile=ignore_pipfile, skip_lock=skip_lock, verbose=verbose)
|
||||
sys.exit(0)
|
||||
|
||||
for package_name in package_names:
|
||||
@@ -903,7 +955,7 @@ def install(package_name=False, more_packages=False, dev=False, three=False, pyt
|
||||
|
||||
# pip install:
|
||||
with spinner():
|
||||
c = pip_install(package_name, ignore_hashes=True, allow_global=system, no_deps=False)
|
||||
c = pip_install(package_name, ignore_hashes=True, allow_global=system, no_deps=False, verbose=verbose)
|
||||
|
||||
click.echo(crayons.blue(format_pip_output(c.out)))
|
||||
|
||||
@@ -1152,6 +1204,7 @@ def run(command, args, three=None, python=False):
|
||||
@click.option('--three/--two', is_flag=True, default=None, help="Use Python 3/2 when creating virtualenv.")
|
||||
@click.option('--python', default=False, nargs=1, help="Specify which version of Python virtualenv should use.")
|
||||
def check(three=None, python=False):
|
||||
|
||||
# Ensure that virtualenv is available.
|
||||
ensure_project(three=three, python=python, validate=False)
|
||||
|
||||
@@ -1181,27 +1234,29 @@ def check(three=None, python=False):
|
||||
click.echo(crayons.green('Passed!'))
|
||||
|
||||
|
||||
@click.command(help="Updates pip to latest version, uninstalls all packages, and re-installs package(s) in [packages] to latest compatible versions.")
|
||||
@click.command(help="Updates Pipenv & pip to latest, uninstalls all packages, and re-installs package(s) in [packages] to latest compatible versions.")
|
||||
@click.option('--verbose', '-v', is_flag=True, default=False, help="Verbose mode.")
|
||||
@click.option('--dev', '-d', is_flag=True, default=False, help="Additionally install package(s) in [dev-packages].")
|
||||
@click.option('--three/--two', is_flag=True, default=None, help="Use Python 3/2 when creating virtualenv.")
|
||||
@click.option('--python', default=False, nargs=1, help="Specify which version of Python virtualenv should use.")
|
||||
@click.option('--dry-run', is_flag=True, default=False, help="Just output outdated packages.")
|
||||
@click.option('--bare', is_flag=True, default=False, help="Minimal output.")
|
||||
def update(dev=False, three=None, python=None, dry_run=False, bare=False):
|
||||
def update(dev=False, three=None, python=None, dry_run=False, bare=False, dont_upgrade=False, user=False, verbose=False):
|
||||
|
||||
# Ensure that virtualenv is available.
|
||||
ensure_project(three=three, python=python, validate=False)
|
||||
|
||||
# --dry-run
|
||||
if dry_run:
|
||||
dont_upgrade = True
|
||||
updates = False
|
||||
|
||||
# Dev packages
|
||||
if not bare:
|
||||
click.echo(crayons.yellow('Checking dependencies...'), err=True)
|
||||
|
||||
packages = project.dev_packages
|
||||
packages.update(project.packages)
|
||||
packages = project.packages
|
||||
if dev:
|
||||
packages.update(project.dev_packages)
|
||||
|
||||
installed_packages = {}
|
||||
deps = convert_deps_to_pip(packages, r=False)
|
||||
@@ -1220,26 +1275,26 @@ def update(dev=False, three=None, python=None, dry_run=False, bare=False):
|
||||
name = result['name']
|
||||
installed = result['version']
|
||||
|
||||
latest = installed_packages[name]
|
||||
if installed != latest:
|
||||
if not bare:
|
||||
click.echo('{0}=={1} is availble ({2} installed)!'.format(name, latest, installed))
|
||||
else:
|
||||
click.echo('{0}=={1}'.format(name, latest))
|
||||
updates = True
|
||||
try:
|
||||
latest = installed_packages[name]
|
||||
if installed != latest:
|
||||
if not bare:
|
||||
click.echo('{0}=={1} is available ({2} installed)!'.format(name, latest, installed))
|
||||
else:
|
||||
click.echo('{0}=={1}'.format(name, latest))
|
||||
updates = True
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
if not updates and not bare:
|
||||
click.echo(crayons.green('All good!'))
|
||||
|
||||
sys.exit(int(updates))
|
||||
|
||||
# Update pip to latest version.
|
||||
ensure_latest_pip()
|
||||
|
||||
click.echo(crayons.yellow('Updating all dependencies from Pipfile...'))
|
||||
|
||||
do_purge()
|
||||
do_init(dev=dev)
|
||||
do_init(dev=dev, verbose=verbose)
|
||||
|
||||
click.echo(crayons.yellow('All dependencies are now up-to-date!'))
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ PIPENV_USE_SYSTEM = os.environ.get('VIRTUAL_ENV') if 'PIPENV_IGNORE_VIRTUALENVS'
|
||||
PIPENV_USE_HASHES = True
|
||||
|
||||
# Tells pipenv to skip case-checking (slow internet connections).
|
||||
PIPENV_SKIP_VALIDATION = os.environ.get('PIPENV_SKIP_VALIDATION')
|
||||
PIPENV_SKIP_VALIDATION = True
|
||||
|
||||
# Use shell compatibility mode when using venv in project mode.
|
||||
if PIPENV_VENV_IN_PROJECT:
|
||||
|
||||
+4
-1
@@ -273,4 +273,7 @@ class Project(object):
|
||||
p[key][package_name] = package[package_name]
|
||||
|
||||
# Write Pipfile.
|
||||
self.write_toml(recase_file(p))
|
||||
self.write_toml(p)
|
||||
|
||||
def recase_pipfile(self):
|
||||
self.write_toml(recase_file(self._pipfile))
|
||||
|
||||
+10
-15
@@ -23,7 +23,7 @@ class PipCommand(pip.basecommand.Command):
|
||||
|
||||
|
||||
def shellquote(s):
|
||||
return "'" + s.replace("'", "'\\''") + "'"
|
||||
return "'" + s.replace("'", "'\\''") + "'"
|
||||
|
||||
|
||||
def clean_pkg_version(version):
|
||||
@@ -55,18 +55,13 @@ def resolve_deps(deps, sources=None, verbose=False, hashes=False):
|
||||
if verbose:
|
||||
logging.log.verbose = True
|
||||
|
||||
r = Resolver(constraints=constraints, repository=pypi)
|
||||
resolver = Resolver(constraints=constraints, repository=pypi)
|
||||
results = []
|
||||
_hashes = r.resolve_hashes(r.resolve())
|
||||
# convert to a dictionary indexed by package names instead of install req objects
|
||||
resolved_hashes = {}
|
||||
for req, _hash in _hashes.items():
|
||||
resolved_hashes[pep423_name(req.name)] = {
|
||||
'version': clean_pkg_version(req.specifier),
|
||||
'hashes': list(_hash)
|
||||
}
|
||||
|
||||
for result in r.resolve():
|
||||
# pre-resolve instead of iterating to avoid asking pypi for hashes of editable packages
|
||||
resolved_tree = resolver.resolve()
|
||||
|
||||
for result in resolved_tree:
|
||||
name = pep423_name(result.name)
|
||||
version = clean_pkg_version(result.specifier)
|
||||
|
||||
@@ -78,9 +73,10 @@ def resolve_deps(deps, sources=None, verbose=False, hashes=False):
|
||||
collected_hashes.append(release['digests']['sha256'])
|
||||
|
||||
collected_hashes = ['sha256:' + s for s in collected_hashes]
|
||||
# Add pypi resolved hashes
|
||||
if name in resolved_hashes and resolved_hashes[name]['version'] == version:
|
||||
collected_hashes.extend(resolved_hashes[name]['hashes'])
|
||||
|
||||
# Collect un-collectable hashes.
|
||||
if not collected_hashes:
|
||||
collected_hashes = list(resolver.resolve_hashes([result]).items()[0][1])
|
||||
|
||||
results.append({'name': name, 'version': version, 'hashes': collected_hashes})
|
||||
except ValueError:
|
||||
@@ -361,4 +357,3 @@ def find_requirements(max_depth=3):
|
||||
if os.path.isfile(r):
|
||||
return r
|
||||
raise RuntimeError('No requirements.txt found!')
|
||||
|
||||
|
||||
@@ -182,8 +182,10 @@ class TestPipenv():
|
||||
|
||||
# Build the environment.
|
||||
os.environ['PIPENV_VENV_IN_PROJECT'] = '1'
|
||||
delegator.run('touch Pipfile')
|
||||
|
||||
# Install packages for test.
|
||||
# print(delegator.run('pipenv install pep8').err)
|
||||
assert delegator.run('pipenv install pep8').return_code == 0
|
||||
assert delegator.run('pipenv install pytest').return_code == 0
|
||||
|
||||
|
||||
@@ -65,12 +65,12 @@ class TestProject():
|
||||
delegator.run('rm -fr test_add_to_pipfile')
|
||||
|
||||
# Confirm Flask added to packages.
|
||||
assert 'Flask' in p['packages']
|
||||
assert p['packages']['Flask'] == '*'
|
||||
assert 'flask' in p['packages']
|
||||
assert p['packages']['flask'] == '*'
|
||||
|
||||
# Confirm Django added to dev-packages.
|
||||
assert 'Django' in p['dev-packages']
|
||||
assert p['dev-packages']['Django'] == '==1.10.1'
|
||||
assert 'django' in p['dev-packages']
|
||||
assert p['dev-packages']['django'] == '==1.10.1'
|
||||
|
||||
# Confirm casing is normalized.
|
||||
assert 'click-completion' in p['packages']
|
||||
|
||||
Reference in New Issue
Block a user