diff --git a/pipenv/cli.py b/pipenv/cli.py index 88d706be..a28b9f2f 100644 --- a/pipenv/cli.py +++ b/pipenv/cli.py @@ -1352,7 +1352,22 @@ def pip_install( f.write(package_name) # Install dependencies when a package is a VCS dependency. - if get_requirement(package_name.split('--hash')[0].split('--trusted-host')[0]).vcs: + try: + req = get_requirement(package_name.split('--hash')[0].split('--trusted-host')[0]).vcs + except (pip._vendor.pyparsing.ParseException, ValueError) as e: + click.echo('{0}: {1}'.format(crayons.red('WARNING'), e), err=True) + click.echo( + '{0}... You will have to reinstall any packages that failed to install.'.format( + crayons.red('ABORTING INSTALL') + ), err=True + ) + click.echo( + 'You may have to manually run {0} when you are finished.'.format( + crayons.normal('pipenv lock', bold=True) + ) + ) + sys.exit(1) + if req: no_deps = False # Don't specify a source directory when using --system. diff --git a/tests/test_pipenv.py b/tests/test_pipenv.py index 8a0d6812..280b1df0 100644 --- a/tests/test_pipenv.py +++ b/tests/test_pipenv.py @@ -174,6 +174,16 @@ class TestPipenv: c = p.pipenv('--man') assert c.return_code == 0 or c.err + @pytest.mark.cli + @pytest.mark.install + def test_install_parse_error(self): + with PipenvInstance() as p: + # Make sure unparseable packages don't wind up in the pipfile + # Escape $ for shell input + c = p.pipenv('install tablib u/\\/p@r\$34b13+pkg') + assert c.return_code != 0 + assert 'u/\\/p@r$34b13+pkg' not in p.pipfile['packages'] + @pytest.mark.install @pytest.mark.setup @pytest.mark.skip(reason="this doesn't work on travis")