From 4777c3bb267a3a325b7cc999adbb06f948cde4f6 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Thu, 7 Sep 2017 14:28:34 -0400 Subject: [PATCH 01/45] comment Signed-off-by: Kenneth Reitz --- pipenv/cli.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pipenv/cli.py b/pipenv/cli.py index 772d1082..28299089 100644 --- a/pipenv/cli.py +++ b/pipenv/cli.py @@ -259,6 +259,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. From f8f7dfa131f43f8ac81275a6efa73fb4d43b8ec5 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Thu, 7 Sep 2017 15:09:38 -0400 Subject: [PATCH 02/45] auto-updating! Signed-off-by: Kenneth Reitz --- pipenv/cli.py | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/pipenv/cli.py b/pipenv/cli.py index 28299089..8ca713d9 100644 --- a/pipenv/cli.py +++ b/pipenv/cli.py @@ -73,13 +73,35 @@ 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 [--user]') ), 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__) + + 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) + + if not user: + sys.argv = ['pip', 'install', '--upgrade', 'pipenv'] + else: + sys.argv = ['pip', 'install', '--user', '--upgrade', 'pipenv'] + + sys.modules['pip'].main() + + click.echo('{0} to {1}!'.format( + crayons.green('Pipenv updated'), + crayons.yellow('{v.major}.{v.minor}.{v.patch}'.format(v=latest)) + )) def cleanup_virtualenv(bare=True): """Removes the virtualenv directory from the system.""" @@ -1183,18 +1205,20 @@ def check(three=None, python=False): @click.command(help="Updates pip to latest version, uninstalls all packages, and re-installs package(s) in [packages] to latest compatible versions.") +@click.option('--dont-upgrade-self', '-d', is_flag=True, default=False, help="Upgrade Pipenv to latest version.") +@click.option('--user', '-U', is_flag=True, default=False, help="When upgrading Pipenv, use pip --user") @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_self=False, user=False): # Ensure that virtualenv is available. ensure_project(three=three, python=python, validate=False) - # --dry-run if dry_run: + dont_upgrade_self = True updates = False # Dev packages @@ -1237,6 +1261,9 @@ def update(dev=False, three=None, python=None, dry_run=False, bare=False): # Update pip to latest version. ensure_latest_pip() + if not dont_upgrade_self: + enhance(user=user) + click.echo(crayons.yellow('Updating all dependencies from Pipfile...')) do_purge() From 82399931aff60793f917b93afdfda9ae8ec79c48 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Thu, 7 Sep 2017 15:11:23 -0400 Subject: [PATCH 03/45] further notes Signed-off-by: Kenneth Reitz --- pipenv/cli.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pipenv/cli.py b/pipenv/cli.py index 8ca713d9..d465b442 100644 --- a/pipenv/cli.py +++ b/pipenv/cli.py @@ -1204,7 +1204,7 @@ 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('--dont-upgrade-self', '-d', is_flag=True, default=False, help="Upgrade Pipenv to latest version.") @click.option('--user', '-U', is_flag=True, default=False, help="When upgrading Pipenv, use pip --user") @click.option('--dev', '-d', is_flag=True, default=False, help="Additionally install package(s) in [dev-packages].") From c4b22df30bf71c028e2b2d206a5f8a5300937aa4 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Thu, 7 Sep 2017 15:12:35 -0400 Subject: [PATCH 04/45] improvements Signed-off-by: Kenneth Reitz --- pipenv/cli.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/pipenv/cli.py b/pipenv/cli.py index d465b442..ac47321a 100644 --- a/pipenv/cli.py +++ b/pipenv/cli.py @@ -1205,20 +1205,20 @@ def check(three=None, python=False): @click.command(help="Updates Pipenv & pip to latest, uninstalls all packages, and re-installs package(s) in [packages] to latest compatible versions.") -@click.option('--dont-upgrade-self', '-d', is_flag=True, default=False, help="Upgrade Pipenv to latest version.") +@click.option('--dont-upgrade', '-d', is_flag=True, default=False, help="Don't upgrade Pipenv & pip.") @click.option('--user', '-U', is_flag=True, default=False, help="When upgrading Pipenv, use pip --user") @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, dont_upgrade_self=False, user=False): +def update(dev=False, three=None, python=None, dry_run=False, bare=False, dont_upgrade=False, user=False): # Ensure that virtualenv is available. ensure_project(three=three, python=python, validate=False) # --dry-run if dry_run: - dont_upgrade_self = True + dont_upgrade = True updates = False # Dev packages @@ -1259,9 +1259,11 @@ def update(dev=False, three=None, python=None, dry_run=False, bare=False, dont_u sys.exit(int(updates)) # Update pip to latest version. - ensure_latest_pip() + if not dont_upgrade: + ensure_latest_pip() - if not dont_upgrade_self: + # Upgrade self to latest version. + if not dont_upgrade: enhance(user=user) click.echo(crayons.yellow('Updating all dependencies from Pipfile...')) From cc33d98613dc0217a6ddccba4d5aa5d52acff7ed Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Thu, 7 Sep 2017 15:24:41 -0400 Subject: [PATCH 05/45] verbose mode Signed-off-by: Kenneth Reitz --- pipenv/cli.py | 48 +++++++++++++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/pipenv/cli.py b/pipenv/cli.py index ac47321a..1cf7601c 100644 --- a/pipenv/cli.py +++ b/pipenv/cli.py @@ -264,7 +264,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: @@ -312,7 +312,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!')) @@ -643,7 +643,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() @@ -686,14 +686,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): @@ -725,6 +725,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: @@ -892,9 +896,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: @@ -918,7 +923,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: @@ -926,7 +931,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))) @@ -1207,12 +1212,13 @@ def check(three=None, python=False): @click.command(help="Updates Pipenv & pip to latest, uninstalls all packages, and re-installs package(s) in [packages] to latest compatible versions.") @click.option('--dont-upgrade', '-d', is_flag=True, default=False, help="Don't upgrade Pipenv & pip.") @click.option('--user', '-U', is_flag=True, default=False, help="When upgrading Pipenv, use pip --user") +@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, dont_upgrade=False, user=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) @@ -1225,8 +1231,9 @@ def update(dev=False, three=None, python=None, dry_run=False, bare=False, dont_u 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) @@ -1245,13 +1252,16 @@ def update(dev=False, three=None, python=None, dry_run=False, bare=False, dont_u 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 availble ({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!')) @@ -1269,7 +1279,7 @@ def update(dev=False, three=None, python=None, dry_run=False, bare=False, dont_u 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!')) From f7c704963def21036031638d21e3c86a66a8b922 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Thu, 7 Sep 2017 15:52:20 -0400 Subject: [PATCH 06/45] enhance Signed-off-by: Kenneth Reitz --- pipenv/cli.py | 43 ++++++++++++++++++++++++++++++------------- 1 file changed, 30 insertions(+), 13 deletions(-) diff --git a/pipenv/cli.py b/pipenv/cli.py index 1cf7601c..088d9c6c 100644 --- a/pipenv/cli.py +++ b/pipenv/cli.py @@ -81,27 +81,44 @@ def check_for_updates(): 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__) - 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) + if current < latest: - if not user: - sys.argv = ['pip', 'install', '--upgrade', 'pipenv'] - else: - sys.argv = ['pip', 'install', '--user', '--upgrade', 'pipenv'] + # Resolve user site, enable user mode automatically. + c = delegator.run('{0} -m site'.format(sys.executable)) - sys.modules['pip'].main() + for line in c.out.split('\n'): + if line.strip().startswith('ENABLE_USER_SITE'): + can_user = eval(line[len('ENABLE_USER_SITE: '):]) + if line.strip().startswith('USER_SITE'): + user_site = eval(''.join(line[len('USER_SITE: '):].split()[:-1])) + + if can_user: + if user_site in sys.modules['pipenv'].__file__: + user = True + + 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) + + if not user: + sys.argv = ['pip', 'install', '--upgrade', 'pipenv'] + else: + sys.argv = ['pip', 'install', '--user', '--upgrade', 'pipenv'] + + sys.modules['pip'].main() + + click.echo('{0} to {1}!'.format( + crayons.green('Pipenv updated'), + crayons.yellow('{v.major}.{v.minor}.{v.patch}'.format(v=latest)) + )) - click.echo('{0} to {1}!'.format( - crayons.green('Pipenv updated'), - crayons.yellow('{v.major}.{v.minor}.{v.patch}'.format(v=latest)) - )) def cleanup_virtualenv(bare=True): """Removes the virtualenv directory from the system.""" From 8e58890c00acb0dd403ec180470d3b4b694e8404 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Thu, 7 Sep 2017 15:52:29 -0400 Subject: [PATCH 07/45] history Signed-off-by: Kenneth Reitz --- HISTORY.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/HISTORY.txt b/HISTORY.txt index 07603beb..f13df2e4 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -1,3 +1,6 @@ +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. From f71095e655e14756ae44b7d4890e4cbe6e730c8f Mon Sep 17 00:00:00 2001 From: Dan Ryan Date: Thu, 7 Sep 2017 16:25:00 -0400 Subject: [PATCH 08/45] Fix variable naming issues --- pipenv/utils.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/pipenv/utils.py b/pipenv/utils.py index ba859a8f..8366448f 100644 --- a/pipenv/utils.py +++ b/pipenv/utils.py @@ -57,13 +57,13 @@ def resolve_deps(deps, sources=None, verbose=False, hashes=False): r = Resolver(constraints=constraints, repository=pypi) results = [] - _hashes = r.resolve_hashes(r.resolve()) + 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(): + for req, pypi_hash in hashes.items(): resolved_hashes[pep423_name(req.name)] = { 'version': clean_pkg_version(req.specifier), - 'hashes': _hash + 'hashes': pypi_hash } for result in r.resolve(): @@ -81,9 +81,9 @@ def resolve_deps(deps, sources=None, verbose=False, hashes=False): # Add pypi resolved hashes if name in resolved_hashes and resolved_hashes[name]['version'] == version: # Eliminate potential duplicate hashes - _resolved = resolved_hashes[name]['hashes'] - _resolved |= set(collected_hashes) - collected_hashes = list(_resolved) + resolved = resolved_hashes[name]['hashes'] + resolved |= set(collected_hashes) + collected_hashes = list(resolved) results.append({'name': name, 'version': version, 'hashes': collected_hashes}) except ValueError: @@ -364,4 +364,3 @@ def find_requirements(max_depth=3): if os.path.isfile(r): return r raise RuntimeError('No requirements.txt found!') - From 9e0fe3d3b8e30b636b9131bf2c1636814245503d Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Thu, 7 Sep 2017 16:25:25 -0400 Subject: [PATCH 09/45] shell escaping more often Signed-off-by: Kenneth Reitz --- pipenv/cli.py | 6 +++--- pipenv/project.py | 4 ++-- pipenv/utils.py | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/pipenv/cli.py b/pipenv/cli.py index 088d9c6c..65a4bad6 100644 --- a/pipenv/cli.py +++ b/pipenv/cli.py @@ -768,15 +768,15 @@ def which(command): if command.endswith('.py'): return os.sep.join([project.virtualenv_location] + ['Scripts\{0}'.format(command)]) return os.sep.join([project.virtualenv_location] + ['Scripts\{0}.exe'.format(command)]) - return os.sep.join([project.virtualenv_location] + ['bin/{0}'.format(command)]) + return shellquote(os.sep.join([project.virtualenv_location] + ['bin/{0}'.format(command)])) def which_pip(allow_global=False): """Returns the location of virtualenv-installed pip.""" if allow_global: - return distutils.spawn.find_executable('pip') + return shellquote(distutils.spawn.find_executable('pip')) - return which('pip') + return shellquote(which('pip')) def format_help(help): diff --git a/pipenv/project.py b/pipenv/project.py index 9654a217..985ee138 100644 --- a/pipenv/project.py +++ b/pipenv/project.py @@ -12,7 +12,7 @@ import delegator from requests.compat import OrderedDict from .utils import (format_toml, mkdir_p, convert_deps_from_pip, - pep423_name, recase_file, find_requirements) + pep423_name, recase_file, find_requirements, shellquote) from .environments import PIPENV_MAX_DEPTH, PIPENV_VENV_IN_PROJECT from .environments import PIPENV_USE_SYSTEM @@ -90,7 +90,7 @@ class Project(object): loc = c.out.strip() # Default mode. else: - loc = os.sep.join(self.pipfile_location.split(os.sep)[:-1] + ['.venv']) + loc = shellquote(os.sep.join(self.pipfile_location.split(os.sep)[:-1] + ['.venv'])) self._virtualenv_location = loc return loc diff --git a/pipenv/utils.py b/pipenv/utils.py index 1d77adad..6de8c034 100644 --- a/pipenv/utils.py +++ b/pipenv/utils.py @@ -23,7 +23,7 @@ class PipCommand(pip.basecommand.Command): def shellquote(s): - return "'" + s.replace("'", "'\\''") + "'" + return "'" + s.replace("'", "'\\''").replace(' ', '\\ ') + "'" def resolve_deps(deps, sources=None, verbose=False, hashes=False): From 9175ed068501a804be7f5eed6eafb39ac2cc99d1 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Thu, 7 Sep 2017 16:26:27 -0400 Subject: [PATCH 10/45] 6.1.0 Signed-off-by: Kenneth Reitz --- pipenv/__version__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pipenv/__version__.py b/pipenv/__version__.py index e7b7493f..166faf77 100644 --- a/pipenv/__version__.py +++ b/pipenv/__version__.py @@ -3,4 +3,4 @@ # //___/ / / / //___/ / // // / / || / / # // / / // ((____ // / / ||/ / -__version__ = '6.0.3' +__version__ = '6.1.0' From 75049408a2b4130df962ce79b1a9d3e6cca8d863 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Thu, 7 Sep 2017 16:31:16 -0400 Subject: [PATCH 11/45] oops Signed-off-by: Kenneth Reitz --- pipenv/cli.py | 6 +++--- pipenv/project.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pipenv/cli.py b/pipenv/cli.py index 65a4bad6..088d9c6c 100644 --- a/pipenv/cli.py +++ b/pipenv/cli.py @@ -768,15 +768,15 @@ def which(command): if command.endswith('.py'): return os.sep.join([project.virtualenv_location] + ['Scripts\{0}'.format(command)]) return os.sep.join([project.virtualenv_location] + ['Scripts\{0}.exe'.format(command)]) - return shellquote(os.sep.join([project.virtualenv_location] + ['bin/{0}'.format(command)])) + return os.sep.join([project.virtualenv_location] + ['bin/{0}'.format(command)]) def which_pip(allow_global=False): """Returns the location of virtualenv-installed pip.""" if allow_global: - return shellquote(distutils.spawn.find_executable('pip')) + return distutils.spawn.find_executable('pip') - return shellquote(which('pip')) + return which('pip') def format_help(help): diff --git a/pipenv/project.py b/pipenv/project.py index 985ee138..3fdefffa 100644 --- a/pipenv/project.py +++ b/pipenv/project.py @@ -90,7 +90,7 @@ class Project(object): loc = c.out.strip() # Default mode. else: - loc = shellquote(os.sep.join(self.pipfile_location.split(os.sep)[:-1] + ['.venv'])) + loc = os.sep.join(self.pipfile_location.split(os.sep)[:-1] + ['.venv']) self._virtualenv_location = loc return loc From f9f79fa937e266b2f8b0952b9b627884d4456782 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Thu, 7 Sep 2017 16:31:27 -0400 Subject: [PATCH 12/45] fix Signed-off-by: Kenneth Reitz --- pipenv/__version__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pipenv/__version__.py b/pipenv/__version__.py index 166faf77..4297c1c6 100644 --- a/pipenv/__version__.py +++ b/pipenv/__version__.py @@ -3,4 +3,4 @@ # //___/ / / / //___/ / // // / / || / / # // / / // ((____ // / / ||/ / -__version__ = '6.1.0' +__version__ = '6.1.1' From 34b5a5736b5fe23bf380890f73bfcf906d997b5b Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Thu, 7 Sep 2017 16:32:07 -0400 Subject: [PATCH 13/45] fix bug Signed-off-by: Kenneth Reitz --- HISTORY.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/HISTORY.txt b/HISTORY.txt index f13df2e4..a1096edf 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -1,3 +1,5 @@ +6.1.1: + - Bug fix. 6.1.0: - Self–updating! Very fancy. $ pipenv update. - Verbose mode for update, install. From 437d4e37364fb790a52eb77c3204cdd136e478b0 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Thu, 7 Sep 2017 16:38:06 -0400 Subject: [PATCH 14/45] remove more shell escaping Signed-off-by: Kenneth Reitz --- pipenv/project.py | 2 +- pipenv/utils.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pipenv/project.py b/pipenv/project.py index 3fdefffa..9654a217 100644 --- a/pipenv/project.py +++ b/pipenv/project.py @@ -12,7 +12,7 @@ import delegator from requests.compat import OrderedDict from .utils import (format_toml, mkdir_p, convert_deps_from_pip, - pep423_name, recase_file, find_requirements, shellquote) + pep423_name, recase_file, find_requirements) from .environments import PIPENV_MAX_DEPTH, PIPENV_VENV_IN_PROJECT from .environments import PIPENV_USE_SYSTEM diff --git a/pipenv/utils.py b/pipenv/utils.py index 6de8c034..62a2984a 100644 --- a/pipenv/utils.py +++ b/pipenv/utils.py @@ -23,7 +23,7 @@ class PipCommand(pip.basecommand.Command): def shellquote(s): - return "'" + s.replace("'", "'\\''").replace(' ', '\\ ') + "'" + return "'" + s.replace("'", "'\\''") + "'" def resolve_deps(deps, sources=None, verbose=False, hashes=False): From 92af904ad060aebc1f4800df1983d987088dcfef Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Thu, 7 Sep 2017 16:38:16 -0400 Subject: [PATCH 15/45] see if that fixes it Signed-off-by: Kenneth Reitz --- pipenv/__version__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pipenv/__version__.py b/pipenv/__version__.py index 4297c1c6..e8d08e9c 100644 --- a/pipenv/__version__.py +++ b/pipenv/__version__.py @@ -3,4 +3,4 @@ # //___/ / / / //___/ / // // / / || / / # // / / // ((____ // / / ||/ / -__version__ = '6.1.1' +__version__ = '6.1.2' From 09fbd15e71462b2af3f82e2366563a8ea8b56b81 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Thu, 7 Sep 2017 16:51:06 -0400 Subject: [PATCH 16/45] skip validation Signed-off-by: Kenneth Reitz --- docs/advanced.rst | 1 - pipenv/cli.py | 1 + pipenv/environments.py | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/advanced.rst b/docs/advanced.rst index 3c180b0b..b9b57778 100644 --- a/docs/advanced.rst +++ b/docs/advanced.rst @@ -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). diff --git a/pipenv/cli.py b/pipenv/cli.py index 088d9c6c..60d9a8c7 100644 --- a/pipenv/cli.py +++ b/pipenv/cli.py @@ -1197,6 +1197,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) diff --git a/pipenv/environments.py b/pipenv/environments.py index e86f48ac..bf0baddc 100644 --- a/pipenv/environments.py +++ b/pipenv/environments.py @@ -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: From 0433fd23641245681c8b2b762eb77b15f7b9a11e Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Thu, 7 Sep 2017 16:51:32 -0400 Subject: [PATCH 17/45] history Signed-off-by: Kenneth Reitz --- HISTORY.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/HISTORY.txt b/HISTORY.txt index a1096edf..24ee32a2 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -1,3 +1,5 @@ +6.1.2: + - Skip validation of Pipfiles, massive speedup for far-away users. 6.1.1: - Bug fix. 6.1.0: From ee926fc347c11b98d6f5391e14522ef60558a6ed Mon Sep 17 00:00:00 2001 From: Dan Ryan Date: Thu, 7 Sep 2017 16:56:26 -0400 Subject: [PATCH 18/45] Fix new bug querying pypi for editable local package hashes --- pipenv/utils.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pipenv/utils.py b/pipenv/utils.py index 8366448f..feb7751c 100644 --- a/pipenv/utils.py +++ b/pipenv/utils.py @@ -57,7 +57,9 @@ def resolve_deps(deps, sources=None, verbose=False, hashes=False): r = Resolver(constraints=constraints, repository=pypi) results = [] - hashes = r.resolve_hashes(r.resolve()) + # pre-resolve instead of iterating to avoid asking pypi for hashes of editable packages + resolved_tree = r.resolve() + hashes = r.resolve_hashes((req for req in resolved_tree if not req.editable)) # convert to a dictionary indexed by package names instead of install req objects resolved_hashes = {} for req, pypi_hash in hashes.items(): @@ -66,7 +68,7 @@ def resolve_deps(deps, sources=None, verbose=False, hashes=False): 'hashes': pypi_hash } - for result in r.resolve(): + for result in resolved_tree: name = pep423_name(result.name) version = clean_pkg_version(result.specifier) From bb0719f8ae8ec98e6004a85f9324abc4a729f34b Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Thu, 7 Sep 2017 17:01:15 -0400 Subject: [PATCH 19/45] only call recase_file once Signed-off-by: Kenneth Reitz --- pipenv/cli.py | 2 ++ pipenv/project.py | 5 ++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/pipenv/cli.py b/pipenv/cli.py index 60d9a8c7..eeb1f007 100644 --- a/pipenv/cli.py +++ b/pipenv/cli.py @@ -174,6 +174,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. diff --git a/pipenv/project.py b/pipenv/project.py index 9654a217..09cec0d8 100644 --- a/pipenv/project.py +++ b/pipenv/project.py @@ -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)) From 14d301ee852be1ef47ec23130746fb804b9c34a7 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Thu, 7 Sep 2017 17:01:55 -0400 Subject: [PATCH 20/45] history Signed-off-by: Kenneth Reitz --- HISTORY.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/HISTORY.txt b/HISTORY.txt index 24ee32a2..417bced0 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -1,5 +1,6 @@ 6.1.2: - Skip validation of Pipfiles, massive speedup for far-away users. + - Other speed-ups. 6.1.1: - Bug fix. 6.1.0: From 43ea43ccd87326a22c39909e0c0d185541580f2a Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Thu, 7 Sep 2017 17:02:47 -0400 Subject: [PATCH 21/45] version bump Signed-off-by: Kenneth Reitz --- HISTORY.txt | 2 +- pipenv/__version__.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index 417bced0..63d67bc7 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -1,4 +1,4 @@ -6.1.2: +6.1.3: - Skip validation of Pipfiles, massive speedup for far-away users. - Other speed-ups. 6.1.1: diff --git a/pipenv/__version__.py b/pipenv/__version__.py index e8d08e9c..da448424 100644 --- a/pipenv/__version__.py +++ b/pipenv/__version__.py @@ -3,4 +3,4 @@ # //___/ / / / //___/ / // // / / || / / # // / / // ((____ // / / ||/ / -__version__ = '6.1.2' +__version__ = '6.1.3' From 3a4722070d264dfb6b2c8c6ba315096ab449a5cf Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Thu, 7 Sep 2017 17:06:09 -0400 Subject: [PATCH 22/45] new update formula Signed-off-by: Kenneth Reitz --- pipenv/cli.py | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/pipenv/cli.py b/pipenv/cli.py index eeb1f007..492b3343 100644 --- a/pipenv/cli.py +++ b/pipenv/cli.py @@ -76,7 +76,7 @@ def check_for_updates(): click.echo('{0}: {1} is now available. You get bonus points for upgrading ($ {})!'.format( crayons.green('Courtesy Notice'), crayons.yellow('Pipenv {v.major}.{v.minor}.{v.patch}'.format(v=latest)), - crayons.red('pipenv update [--user]') + crayons.red('pipenv --update') ), err=True) except Exception: pass @@ -850,6 +850,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.") @@ -859,9 +860,16 @@ 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() if ctx.invoked_subcommand is None: # --where was passed... @@ -1230,8 +1238,6 @@ def check(three=None, python=False): @click.command(help="Updates Pipenv & pip to latest, uninstalls all packages, and re-installs package(s) in [packages] to latest compatible versions.") -@click.option('--dont-upgrade', '-d', is_flag=True, default=False, help="Don't upgrade Pipenv & pip.") -@click.option('--user', '-U', is_flag=True, default=False, help="When upgrading Pipenv, use pip --user") @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.") @@ -1288,14 +1294,6 @@ def update(dev=False, three=None, python=None, dry_run=False, bare=False, dont_u sys.exit(int(updates)) - # Update pip to latest version. - if not dont_upgrade: - ensure_latest_pip() - - # Upgrade self to latest version. - if not dont_upgrade: - enhance(user=user) - click.echo(crayons.yellow('Updating all dependencies from Pipfile...')) do_purge() From 7ba8574b8359ef01face838ef4528f6dbf3cbbdd Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Thu, 7 Sep 2017 17:08:04 -0400 Subject: [PATCH 23/45] all good! Signed-off-by: Kenneth Reitz --- pipenv/cli.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pipenv/cli.py b/pipenv/cli.py index 492b3343..b113deeb 100644 --- a/pipenv/cli.py +++ b/pipenv/cli.py @@ -118,6 +118,8 @@ def enhance(user=False): 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): @@ -871,6 +873,8 @@ def cli(ctx, where=False, venv=False, rm=False, bare=False, three=False, python= # Upgrade self to latest version. enhance() + sys.exit() + if ctx.invoked_subcommand is None: # --where was passed... if where: From 334993a581a0af5085a2130ed705783847013d93 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Thu, 7 Sep 2017 17:11:32 -0400 Subject: [PATCH 24/45] simplify upgrade logic Signed-off-by: Kenneth Reitz --- pipenv/cli.py | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/pipenv/cli.py b/pipenv/cli.py index b113deeb..ffc3ea90 100644 --- a/pipenv/cli.py +++ b/pipenv/cli.py @@ -89,17 +89,11 @@ def enhance(user=False): if current < latest: + import site + # Resolve user site, enable user mode automatically. - c = delegator.run('{0} -m site'.format(sys.executable)) - - for line in c.out.split('\n'): - if line.strip().startswith('ENABLE_USER_SITE'): - can_user = eval(line[len('ENABLE_USER_SITE: '):]) - if line.strip().startswith('USER_SITE'): - user_site = eval(''.join(line[len('USER_SITE: '):].split()[:-1])) - - if can_user: - if user_site in sys.modules['pipenv'].__file__: + if site.ENABLE_USER_SITE: + if site.USER_SITE in sys.modules['pipenv'].__file__: user = True click.echo('{0}: {1} is now available. Automatically upgrading!'.format( @@ -108,11 +102,11 @@ def enhance(user=False): ), err=True) if not user: - sys.argv = ['pip', 'install', '--upgrade', 'pipenv'] + args = ['install', '--upgrade', 'pipenv'] else: - sys.argv = ['pip', 'install', '--user', '--upgrade', 'pipenv'] + args = ['install', '--user', '--upgrade', 'pipenv'] - sys.modules['pip'].main() + sys.modules['pip'].main(args) click.echo('{0} to {1}!'.format( crayons.green('Pipenv updated'), From ba7c134edb38a1ea4a762533de001780841c38f9 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Thu, 7 Sep 2017 17:13:00 -0400 Subject: [PATCH 25/45] futher simplify upgrade logic Signed-off-by: Kenneth Reitz --- pipenv/cli.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/pipenv/cli.py b/pipenv/cli.py index ffc3ea90..d33d02da 100644 --- a/pipenv/cli.py +++ b/pipenv/cli.py @@ -91,17 +91,13 @@ def enhance(user=False): import site - # Resolve user site, enable user mode automatically. - if site.ENABLE_USER_SITE: - if site.USER_SITE in sys.modules['pipenv'].__file__: - user = True - 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) - if not user: + # 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'] From 270658482337f4db95701d669a89937f8c94d979 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Thu, 7 Sep 2017 17:14:52 -0400 Subject: [PATCH 26/45] new version Signed-off-by: Kenneth Reitz --- HISTORY.txt | 2 ++ pipenv/__version__.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/HISTORY.txt b/HISTORY.txt index 63d67bc7..a568b15e 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -1,3 +1,5 @@ +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. diff --git a/pipenv/__version__.py b/pipenv/__version__.py index da448424..caae30a7 100644 --- a/pipenv/__version__.py +++ b/pipenv/__version__.py @@ -3,4 +3,4 @@ # //___/ / / / //___/ / // // / / || / / # // / / // ((____ // / / ||/ / -__version__ = '6.1.3' +__version__ = '6.1.4' From 6ac3d0accf211b6552a35b25746dc74eda909f75 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Thu, 7 Sep 2017 17:17:22 -0400 Subject: [PATCH 27/45] let's see what's going on here Signed-off-by: Kenneth Reitz --- tests/test_pipenv.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_pipenv.py b/tests/test_pipenv.py index 459acc48..1252bc5e 100644 --- a/tests/test_pipenv.py +++ b/tests/test_pipenv.py @@ -184,6 +184,7 @@ class TestPipenv(): os.environ['PIPENV_VENV_IN_PROJECT'] = '1' # 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 From 8b7903ff2217e129a9d904c84ba9704517efd3ba Mon Sep 17 00:00:00 2001 From: Jeffrey Gelens Date: Fri, 8 Sep 2017 00:35:38 +0200 Subject: [PATCH 28/45] typo --- pipenv/cli.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pipenv/cli.py b/pipenv/cli.py index d33d02da..eb15f1f9 100644 --- a/pipenv/cli.py +++ b/pipenv/cli.py @@ -1276,7 +1276,7 @@ def update(dev=False, three=None, python=None, dry_run=False, bare=False, dont_u latest = installed_packages[name] if installed != latest: if not bare: - click.echo('{0}=={1} is availble ({2} installed)!'.format(name, latest, installed)) + click.echo('{0}=={1} is available ({2} installed)!'.format(name, latest, installed)) else: click.echo('{0}=={1}'.format(name, latest)) updates = True From acf6be75102a25ddad9c7962264a6930d84e1cbb Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Thu, 7 Sep 2017 20:55:12 -0400 Subject: [PATCH 29/45] fix updating pip on windows Signed-off-by: Kenneth Reitz --- pipenv/cli.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pipenv/cli.py b/pipenv/cli.py index eb15f1f9..39ead9c2 100644 --- a/pipenv/cli.py +++ b/pipenv/cli.py @@ -135,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)) From 8e0c834e909bf3386186bfd7d310b25bf81ce2cc Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Thu, 7 Sep 2017 21:04:02 -0400 Subject: [PATCH 30/45] Revert "Merge pull request #492 from techalchemy/pypi-hash-retrieval" This reverts commit 49980021d69efbea6e00e778636be2c6d76e5536, reversing changes made to b42b5274bb4ebf1276762b9ba62d6d2f644dbce0. --- pipenv/utils.py | 24 ++---------------------- 1 file changed, 2 insertions(+), 22 deletions(-) diff --git a/pipenv/utils.py b/pipenv/utils.py index 2cd58ae5..62a2984a 100644 --- a/pipenv/utils.py +++ b/pipenv/utils.py @@ -26,10 +26,6 @@ def shellquote(s): return "'" + s.replace("'", "'\\''") + "'" -def clean_pkg_version(version): - return six.u(pep440_version(str(version))).replace('==', '') - - def resolve_deps(deps, sources=None, verbose=False, hashes=False): constraints = [] @@ -57,20 +53,10 @@ def resolve_deps(deps, sources=None, verbose=False, hashes=False): r = Resolver(constraints=constraints, repository=pypi) results = [] - # pre-resolve instead of iterating to avoid asking pypi for hashes of editable packages - resolved_tree = r.resolve() - hashes = r.resolve_hashes((req for req in resolved_tree if not req.editable)) - # convert to a dictionary indexed by package names instead of install req objects - resolved_hashes = {} - for req, pypi_hash in hashes.items(): - resolved_hashes[pep423_name(req.name)] = { - 'version': clean_pkg_version(req.specifier), - 'hashes': pypi_hash - } - for result in resolved_tree: + for result in r.resolve(): name = pep423_name(result.name) - version = clean_pkg_version(result.specifier) + version = six.u(pep440_version(str(result.specifier))).replace('==', '') if hashes: try: @@ -80,12 +66,6 @@ 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: - # Eliminate potential duplicate hashes - resolved = resolved_hashes[name]['hashes'] - resolved |= set(collected_hashes) - collected_hashes = list(resolved) results.append({'name': name, 'version': version, 'hashes': collected_hashes}) except ValueError: From 7a89f15f1b5bd7f9198aceb2ca1ccc9a3b029377 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Thu, 7 Sep 2017 21:16:51 -0400 Subject: [PATCH 31/45] fix broken test Signed-off-by: Kenneth Reitz --- tests/test_project.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/test_project.py b/tests/test_project.py index 04391496..f50e7613 100644 --- a/tests/test_project.py +++ b/tests/test_project.py @@ -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'] From 0e6d683da75b92808f4c502f3efd76b8538c3a12 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Thu, 7 Sep 2017 21:19:43 -0400 Subject: [PATCH 32/45] attempted fix of second test Signed-off-by: Kenneth Reitz --- tests/test_pipenv.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/test_pipenv.py b/tests/test_pipenv.py index 1252bc5e..260ba557 100644 --- a/tests/test_pipenv.py +++ b/tests/test_pipenv.py @@ -176,9 +176,9 @@ class TestPipenv(): delegator.run('rm -fr test_pipenv_uninstall') def test_pipenv_run(self): - working_dir = 'test_pipenv_run' - delegator.run('mkdir {0}'.format(working_dir)) - os.chdir(working_dir) + # working_dir = 'test_pipenv_run' + # delegator.run('mkdir {0}'.format(working_dir)) + # os.chdir(working_dir) # Build the environment. os.environ['PIPENV_VENV_IN_PROJECT'] = '1' @@ -193,8 +193,8 @@ class TestPipenv(): assert delegator.run('pipenv run pep8 --version').return_code == 0 assert delegator.run('pipenv run pytest --version').return_code == 0 - os.chdir('..') - delegator.run('rm -fr {0}'.format(working_dir)) + # os.chdir('..') + # delegator.run('rm -fr {0}'.format(working_dir)) def test_ensure_proper_casing_names(self): """Ensure proper casing for package names.""" From f95216cb693784fcb933583363d74f0eff74e495 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Thu, 7 Sep 2017 21:23:10 -0400 Subject: [PATCH 33/45] better fix for test Signed-off-by: Kenneth Reitz --- tests/test_pipenv.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/tests/test_pipenv.py b/tests/test_pipenv.py index 260ba557..4842f27c 100644 --- a/tests/test_pipenv.py +++ b/tests/test_pipenv.py @@ -176,15 +176,16 @@ class TestPipenv(): delegator.run('rm -fr test_pipenv_uninstall') def test_pipenv_run(self): - # working_dir = 'test_pipenv_run' - # delegator.run('mkdir {0}'.format(working_dir)) - # os.chdir(working_dir) + working_dir = 'test_pipenv_run' + delegator.run('mkdir {0}'.format(working_dir)) + os.chdir(working_dir) # 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) + # 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 @@ -193,8 +194,8 @@ class TestPipenv(): assert delegator.run('pipenv run pep8 --version').return_code == 0 assert delegator.run('pipenv run pytest --version').return_code == 0 - # os.chdir('..') - # delegator.run('rm -fr {0}'.format(working_dir)) + os.chdir('..') + delegator.run('rm -fr {0}'.format(working_dir)) def test_ensure_proper_casing_names(self): """Ensure proper casing for package names.""" From 2c13f7fc0d920b9f65f8ef0f6dfd5d92e2aefefe Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Thu, 7 Sep 2017 21:28:56 -0400 Subject: [PATCH 34/45] Revert "Revert "Merge pull request #492 from techalchemy/pypi-hash-retrieval"" This reverts commit 8e0c834e909bf3386186bfd7d310b25bf81ce2cc. --- pipenv/utils.py | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/pipenv/utils.py b/pipenv/utils.py index 62a2984a..2cd58ae5 100644 --- a/pipenv/utils.py +++ b/pipenv/utils.py @@ -26,6 +26,10 @@ def shellquote(s): return "'" + s.replace("'", "'\\''") + "'" +def clean_pkg_version(version): + return six.u(pep440_version(str(version))).replace('==', '') + + def resolve_deps(deps, sources=None, verbose=False, hashes=False): constraints = [] @@ -53,10 +57,20 @@ def resolve_deps(deps, sources=None, verbose=False, hashes=False): r = Resolver(constraints=constraints, repository=pypi) results = [] + # pre-resolve instead of iterating to avoid asking pypi for hashes of editable packages + resolved_tree = r.resolve() + hashes = r.resolve_hashes((req for req in resolved_tree if not req.editable)) + # convert to a dictionary indexed by package names instead of install req objects + resolved_hashes = {} + for req, pypi_hash in hashes.items(): + resolved_hashes[pep423_name(req.name)] = { + 'version': clean_pkg_version(req.specifier), + 'hashes': pypi_hash + } - for result in r.resolve(): + for result in resolved_tree: name = pep423_name(result.name) - version = six.u(pep440_version(str(result.specifier))).replace('==', '') + version = clean_pkg_version(result.specifier) if hashes: try: @@ -66,6 +80,12 @@ 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: + # Eliminate potential duplicate hashes + resolved = resolved_hashes[name]['hashes'] + resolved |= set(collected_hashes) + collected_hashes = list(resolved) results.append({'name': name, 'version': version, 'hashes': collected_hashes}) except ValueError: From 17588204816bb65e62fa0324b59adffb85b0e4f8 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Thu, 7 Sep 2017 21:37:14 -0400 Subject: [PATCH 35/45] collect uncollectable hashes #492 Signed-off-by: Kenneth Reitz --- pipenv/utils.py | 23 +++++++---------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/pipenv/utils.py b/pipenv/utils.py index 2cd58ae5..51cefd20 100644 --- a/pipenv/utils.py +++ b/pipenv/utils.py @@ -55,18 +55,11 @@ 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 = [] + # pre-resolve instead of iterating to avoid asking pypi for hashes of editable packages - resolved_tree = r.resolve() - hashes = r.resolve_hashes((req for req in resolved_tree if not req.editable)) - # convert to a dictionary indexed by package names instead of install req objects - resolved_hashes = {} - for req, pypi_hash in hashes.items(): - resolved_hashes[pep423_name(req.name)] = { - 'version': clean_pkg_version(req.specifier), - 'hashes': pypi_hash - } + resolved_tree = resolver.resolve() for result in resolved_tree: name = pep423_name(result.name) @@ -80,12 +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: - # Eliminate potential duplicate hashes - resolved = resolved_hashes[name]['hashes'] - resolved |= set(collected_hashes) - collected_hashes = list(resolved) + + # 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: From b28f752be1c25443e272e4c9355d2545d2989466 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Thu, 7 Sep 2017 21:39:53 -0400 Subject: [PATCH 36/45] next version --- HISTORY.txt | 2 ++ pipenv/__version__.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/HISTORY.txt b/HISTORY.txt index a568b15e..356b1151 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -1,3 +1,5 @@ +6.1.5: + - Grab hashes for un-grabbable hashes. 6.1.4: - New update via $ pipenv --update, instead. 6.1.3: diff --git a/pipenv/__version__.py b/pipenv/__version__.py index caae30a7..2251d726 100644 --- a/pipenv/__version__.py +++ b/pipenv/__version__.py @@ -3,4 +3,4 @@ # //___/ / / / //___/ / // // / / || / / # // / / // ((____ // / / ||/ / -__version__ = '6.1.4' +__version__ = '6.1.5' From bbe7e1d1f018b7349490a54b2ac494a79d9fe382 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Thu, 7 Sep 2017 21:53:06 -0400 Subject: [PATCH 37/45] attempted fix of windows tests Signed-off-by: Kenneth Reitz --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 7b79fe82..77a41ad4 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -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" From 70cf70902f5c0affe805e8c6ffe5d384f0916e86 Mon Sep 17 00:00:00 2001 From: Jeremy Satterfield Date: Thu, 7 Sep 2017 22:59:15 -0500 Subject: [PATCH 38/45] force reclone of editable git if url changes Fixes #484 --- pipenv/cli.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pipenv/cli.py b/pipenv/cli.py index 39ead9c2..936b7a6d 100644 --- a/pipenv/cli.py +++ b/pipenv/cli.py @@ -738,7 +738,7 @@ 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) + pip_command = '"{0}" install {3} {1} -i {2} --exists-action w'.format(which_pip(allow_global=allow_global), install_reqs, source['url'], no_deps) if verbose: click.echo('$ {0}'.format(pip_command), err=True) From 625d642f63a1169938f9d0563b95e29bf2b1805e Mon Sep 17 00:00:00 2001 From: Erin O'Connell Date: Thu, 7 Sep 2017 22:12:49 -0600 Subject: [PATCH 39/45] fixed shellquote on windows --- pipenv/__version__.py | 2 +- pipenv/cli.py | 8 ++++++-- pipenv/utils.py | 2 +- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/pipenv/__version__.py b/pipenv/__version__.py index 2251d726..ccc03aa0 100644 --- a/pipenv/__version__.py +++ b/pipenv/__version__.py @@ -3,4 +3,4 @@ # //___/ / / / //___/ / // // / / || / / # // / / // ((____ // / / ||/ / -__version__ = '6.1.5' +__version__ = '6.1.6' diff --git a/pipenv/cli.py b/pipenv/cli.py index 39ead9c2..5bc706b0 100644 --- a/pipenv/cli.py +++ b/pipenv/cli.py @@ -501,7 +501,7 @@ def get_downloads_info(names_map, section): def do_lock(no_hashes=True, verbose=False, legacy=False): """Executes the freeze functionality.""" - + print(no_hashes, verbose, legacy) if not legacy: # Alert the user of progress. click.echo(crayons.yellow('Locking {0} dependencies...'.format(crayons.red('[dev-packages]'))), err=True) @@ -580,7 +580,11 @@ def do_lock(no_hashes=True, verbose=False, legacy=False): lockfile['default'][dep['name']]['hashes'] = dep['hashes'] # Run the PEP 508 checker in the virtualenv, add it to the lockfile. - c = delegator.run('"{0}" {1}'.format(which('python'), shellquote(pep508checker.__file__.rstrip('cdo')))) + cmd = '"{0}" {1}'.format(which('python'), shellquote(pep508checker.__file__.rstrip('cdo'))) + c = delegator.run(cmd) + # print("Cmd: {0}".format(cmd)) + # print("Return Code: {0}".format(c.return_code)) + # print("Out: {0}".format(c.out)) lockfile['_meta']['host-environment-markers'] = json.loads(c.out) # Write out the lockfile. diff --git a/pipenv/utils.py b/pipenv/utils.py index 51cefd20..139a5531 100644 --- a/pipenv/utils.py +++ b/pipenv/utils.py @@ -23,7 +23,7 @@ class PipCommand(pip.basecommand.Command): def shellquote(s): - return "'" + s.replace("'", "'\\''") + "'" + return '"' + s.replace("'", "'\\''") + '"' def clean_pkg_version(version): From 3116882fe67d7cdd7725194aac73ec7e9b5cb240 Mon Sep 17 00:00:00 2001 From: Erin O'Connell Date: Thu, 7 Sep 2017 22:57:27 -0600 Subject: [PATCH 40/45] all tests pass on my local windows 10 machine, come on app veyor --- test_windows/test_pipenv.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test_windows/test_pipenv.py b/test_windows/test_pipenv.py index b1877ed5..1c350948 100644 --- a/test_windows/test_pipenv.py +++ b/test_windows/test_pipenv.py @@ -151,7 +151,7 @@ class TestPipenvWindows(): pipfile_output = delegator.run('type Pipfile').out pipfile_list = pipfile_output.split('\n') - assert 'Werkzeug = "*"' in pipfile_list + assert 'werkzeug = "*"' in pipfile_list assert 'pytest = "*"' in pipfile_list assert '[packages]' in pipfile_list assert '[dev-packages]' in pipfile_list @@ -182,6 +182,8 @@ class TestPipenvWindows(): # Build the environment. os.environ['PIPENV_VENV_IN_PROJECT'] = '1' + assert delegator.run('copy /y nul Pipfile').return_code == 0 + assert delegator.run('pipenv --python python').return_code == 0 # Install packages for test. assert delegator.run('pipenv install pep8').return_code == 0 From 9f5d22ac11fe838798d8a30513a1f8ad198fc86a Mon Sep 17 00:00:00 2001 From: Erin O'Connell Date: Thu, 7 Sep 2017 23:05:02 -0600 Subject: [PATCH 41/45] fixed flake8 variable assignment complaint --- pipenv/cli.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pipenv/cli.py b/pipenv/cli.py index 5bc706b0..d5308e91 100644 --- a/pipenv/cli.py +++ b/pipenv/cli.py @@ -1251,7 +1251,7 @@ def update(dev=False, three=None, python=None, dry_run=False, bare=False, dont_u ensure_project(three=three, python=python, validate=False) # --dry-run if dry_run: - dont_upgrade = True + # dont_upgrade = True updates = False # Dev packages From 6f5df44a4e7f17d0b5503a48ff9d4ea0a89422d0 Mon Sep 17 00:00:00 2001 From: Erin O'Connell Date: Thu, 7 Sep 2017 23:11:36 -0600 Subject: [PATCH 42/45] removed debug message --- pipenv/cli.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pipenv/cli.py b/pipenv/cli.py index d5308e91..f070b9ce 100644 --- a/pipenv/cli.py +++ b/pipenv/cli.py @@ -501,7 +501,6 @@ def get_downloads_info(names_map, section): def do_lock(no_hashes=True, verbose=False, legacy=False): """Executes the freeze functionality.""" - print(no_hashes, verbose, legacy) if not legacy: # Alert the user of progress. click.echo(crayons.yellow('Locking {0} dependencies...'.format(crayons.red('[dev-packages]'))), err=True) From abe1218fc7f1d06e55c84337970d1d7b09be5a4c Mon Sep 17 00:00:00 2001 From: Erin O'Connell Date: Thu, 7 Sep 2017 23:22:25 -0600 Subject: [PATCH 43/45] Added a shied for app veyor! --- README.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.rst b/README.rst index 6098c595..85e58f28 100644 --- a/README.rst +++ b/README.rst @@ -19,6 +19,9 @@ Pipenv: Sacred Marriage of Pipfile, Pip, & Virtualenv .. image:: https://img.shields.io/badge/Say%20Thanks-!-1EAEDB.svg :target: https://saythanks.io/to/kennethreitz +.. image:: https://img.shields.io/appveyor/ci/kennethreitz/pipenv.svg + :target: https://ci.appveyor.com/project/kennethreitz/pipenv/branch/master + --------------- **Pipenv** — the officially recommended Python packaging tool from `Python.org `_, free (as in freedom). From 9d864d88b2c3c1a03cb84ed6dcc1c289c8463bba Mon Sep 17 00:00:00 2001 From: Erin O'Connell Date: Thu, 7 Sep 2017 23:37:50 -0600 Subject: [PATCH 44/45] switched badge places --- README.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.rst b/README.rst index 85e58f28..4f2af082 100644 --- a/README.rst +++ b/README.rst @@ -15,13 +15,13 @@ Pipenv: Sacred Marriage of Pipfile, Pip, & Virtualenv .. image:: https://travis-ci.org/kennethreitz/pipenv.svg?branch=master :target: https://travis-ci.org/kennethreitz/pipenv + +.. image:: https://img.shields.io/appveyor/ci/kennethreitz/pipenv.svg + :target: https://ci.appveyor.com/project/kennethreitz/pipenv/branch/master .. image:: https://img.shields.io/badge/Say%20Thanks-!-1EAEDB.svg :target: https://saythanks.io/to/kennethreitz -.. image:: https://img.shields.io/appveyor/ci/kennethreitz/pipenv.svg - :target: https://ci.appveyor.com/project/kennethreitz/pipenv/branch/master - --------------- **Pipenv** — the officially recommended Python packaging tool from `Python.org `_, free (as in freedom). From 3d74d317696053cbc43631294a95ad3408a00ea0 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Fri, 8 Sep 2017 11:10:32 -0400 Subject: [PATCH 45/45] 6.1.6 Signed-off-by: Kenneth Reitz --- HISTORY.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/HISTORY.txt b/HISTORY.txt index 356b1151..ee2518d2 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -1,3 +1,5 @@ +6.1.6: + - Fix for Windows. 6.1.5: - Grab hashes for un-grabbable hashes. 6.1.4: