diff --git a/.gitignore b/.gitignore index 2cee5455..4809d065 100644 --- a/.gitignore +++ b/.gitignore @@ -130,6 +130,9 @@ venv.bak/ .spyderproject .spyproject +# PyCharm project settings +.idea + # Rope project settings .ropeproject diff --git a/docs/dev/contributing.rst b/docs/dev/contributing.rst index 4cbb9e3f..db7f14cc 100644 --- a/docs/dev/contributing.rst +++ b/docs/dev/contributing.rst @@ -67,7 +67,7 @@ Steps for Submitting Code When contributing code, you'll want to follow this checklist: 1. Fork the repository on GitHub. -2. Run the tests to confirm they all pass on your system. If they don't, you'll +2. `Run the tests`_ to confirm they all pass on your system. If they don't, you'll need to investigate why they fail. If you're unable to diagnose this yourself, raise it as a bug report by following the guidelines in this document: :ref:`bug-reports`. @@ -120,3 +120,38 @@ hasn't been reported before. Duplicate bug reports are a huge drain on the time of other contributors, and should be avoided as much as possible. .. _GitHub issues: https://github.com/pypa/pipenv/issues + +Run the tests +------------- + +Three ways of running the tests are as follows: + +1. ``make test`` (which uses ``docker``) +2. ``./run-tests.sh`` or ``run-tests.bat`` +3. Using pipenv:: + + pipenv install --dev + pipenv run pytest + +For the last two, it is important that your environment is setup correctly, and +this may take some work, for example, on a specific Mac installation, the following +steps may be needed:: + + # Make sure the tests can access github + if [ "$SSH_AGENT_PID" = "" ] + then + eval `ssh-agent` + ssh-add + fi + + # Use unix like utilities, installed with brew, + # e.g. brew install coreutils + for d in /usr/local/opt/*/libexec/gnubin /usr/local/opt/python/libexec/bin + do + [[ ":$PATH:" != *":$d:"* ]] && PATH="$d:${PATH}" + done + + export PATH + + # PIP_FIND_LINKS currently breaks test_uninstall.py + unset PIP_FIND_LINKS diff --git a/news/2996.trivial b/news/2996.trivial new file mode 100644 index 00000000..dbe1006a --- /dev/null +++ b/news/2996.trivial @@ -0,0 +1 @@ +Set `PIPENV_ACTIVE=1` when running `pipenv run`. This is what `pipenv shell` already does. \ No newline at end of file diff --git a/news/3041.feature b/news/3041.feature new file mode 100644 index 00000000..79a1d5de --- /dev/null +++ b/news/3041.feature @@ -0,0 +1 @@ +--bare now has an effect on clean, and sync's bare option is now used to reduce output. diff --git a/news/3074.doc.rst b/news/3074.doc.rst new file mode 100644 index 00000000..85feefd5 --- /dev/null +++ b/news/3074.doc.rst @@ -0,0 +1 @@ +Expanded development and testing documentation for contributors to get started. diff --git a/pipenv/cli/command.py b/pipenv/cli/command.py index 1ce9fee9..02bd5dc9 100644 --- a/pipenv/cli/command.py +++ b/pipenv/cli/command.py @@ -533,7 +533,13 @@ def graph(bare=False, json=False, json_tree=False, reverse=False): @argument("module", nargs=1) @pass_state def run_open(state, module, *args, **kwargs): - """View a given module in your editor.""" + """View a given module in your editor. + + This uses the EDITOR environment variable. You can temporarily override it, + for example: + + EDITOR=atom pipenv open requests + """ from ..core import which, ensure_project # Ensure that virtualenv is available. @@ -590,6 +596,7 @@ def sync( @cli.command(short_help="Uninstalls all packages not specified in Pipfile.lock.") +@option("--bare", is_flag=True, default=False, help="Minimal output.") @option("--dry-run", is_flag=True, default=False, help="Just output unneeded packages.") @verbose_option @three_option diff --git a/pipenv/core.py b/pipenv/core.py index 59b9a29c..1b9c5ade 100644 --- a/pipenv/core.py +++ b/pipenv/core.py @@ -1775,6 +1775,10 @@ def do_install( # Don't search for requirements.txt files if the user provides one if requirements or package_args or project.pipfile_exists: skip_requirements = True + # Don't attempt to install develop and default packages if Pipfile is missing + if not project.pipfile_exists and not packages and dev: + click.echo("Could not find Pipfile.", err=True) + sys.exit(1) concurrent = not sequential # Ensure that virtualenv is available. ensure_project( @@ -2280,6 +2284,8 @@ def do_run(command, args, three=None, python=False, pypi_mirror=None): # Ensure that virtualenv is available. ensure_project(three=three, python=python, validate=False, pypi_mirror=pypi_mirror) + # Set an environment variable, so we know we're in the environment. + os.environ["PIPENV_ACTIVE"] = vistir.misc.fs_str("1") load_dot_env() # Activate virtualenv under the current interpreter's environment inline_activate_virtual_environment() @@ -2578,7 +2584,8 @@ def do_sync( deploy=deploy, system=system, ) - click.echo(crayons.green("All dependencies are now up-to-date!")) + if not bare: + click.echo(crayons.green("All dependencies are now up-to-date!")) def do_clean(ctx, three=None, python=None, dry_run=False, bare=False, pypi_mirror=None): @@ -2607,14 +2614,15 @@ def do_clean(ctx, three=None, python=None, dry_run=False, bare=False, pypi_mirro )] failure = False for apparent_bad_package in installed_package_names: - if dry_run: + if dry_run and not bare: click.echo(apparent_bad_package) else: - click.echo( - crayons.white( - fix_utf8("Uninstalling {0}…".format(repr(apparent_bad_package))), bold=True + if not bare: + click.echo( + crayons.white( + fix_utf8("Uninstalling {0}…".format(repr(apparent_bad_package))), bold=True + ) ) - ) # Uninstall the package. c = delegator.run( "{0} uninstall {1} -y".format(which_pip(), apparent_bad_package) diff --git a/pipenv/vendor/requirementslib/__init__.py b/pipenv/vendor/requirementslib/__init__.py index 8ceccd79..bcbff09e 100644 --- a/pipenv/vendor/requirementslib/__init__.py +++ b/pipenv/vendor/requirementslib/__init__.py @@ -1,5 +1,5 @@ # -*- coding=utf-8 -*- -__version__ = '1.2.2' +__version__ = '1.2.3' import logging diff --git a/pipenv/vendor/requirementslib/models/requirements.py b/pipenv/vendor/requirementslib/models/requirements.py index 08eb5618..28d90799 100644 --- a/pipenv/vendor/requirementslib/models/requirements.py +++ b/pipenv/vendor/requirementslib/models/requirements.py @@ -649,7 +649,8 @@ class VCSRequirement(FileRequirement): # Remove potential ref in the end of uri after ref is parsed if "@" in self.link.show_url and "@" in self.uri: uri, ref = self.uri.rsplit("@", 1) - if ref in self.ref: + checkout = self.req.revision + if checkout and ref in checkout: self.uri = uri yield vcsrepo diff --git a/pipenv/vendor/vendor.txt b/pipenv/vendor/vendor.txt index 18352c2e..2e00af0c 100644 --- a/pipenv/vendor/vendor.txt +++ b/pipenv/vendor/vendor.txt @@ -27,7 +27,7 @@ requests==2.20.0 idna==2.7 urllib3==1.24 certifi==2018.10.15 -requirementslib==1.2.2 +requirementslib==1.2.3 attrs==18.2.0 distlib==0.2.8 packaging==18.0 diff --git a/tests/integration/test_lock.py b/tests/integration/test_lock.py index 7743804d..2b520808 100644 --- a/tests/integration/test_lock.py +++ b/tests/integration/test_lock.py @@ -369,6 +369,42 @@ requests = {git = "https://github.com/requests/requests.git", ref = "master", ed assert c.return_code == 0 +@pytest.mark.lock +@pytest.mark.vcs +@pytest.mark.needs_internet +def test_lock_editable_vcs_with_ref_in_git(PipenvInstance, pypi): + with PipenvInstance(pypi=pypi, chdir=True) as p: + with open(p.pipfile_path, 'w') as f: + f.write(""" +[packages] +requests = {git = "https://github.com/requests/requests.git@883caaf", editable = true} + """.strip()) + c = p.pipenv('lock') + assert c.return_code == 0 + assert p.lockfile['default']['requests']['git'] == 'https://github.com/requests/requests.git' + assert p.lockfile['default']['requests']['ref'] == '883caaf145fbe93bd0d208a6b864de9146087312' + c = p.pipenv('install') + assert c.return_code == 0 + + +@pytest.mark.lock +@pytest.mark.vcs +@pytest.mark.needs_internet +def test_lock_editable_vcs_with_ref(PipenvInstance, pypi): + with PipenvInstance(pypi=pypi, chdir=True) as p: + with open(p.pipfile_path, 'w') as f: + f.write(""" +[packages] +requests = {git = "https://github.com/requests/requests.git", ref = "883caaf", editable = true} + """.strip()) + c = p.pipenv('lock') + assert c.return_code == 0 + assert p.lockfile['default']['requests']['git'] == 'https://github.com/requests/requests.git' + assert p.lockfile['default']['requests']['ref'] == '883caaf145fbe93bd0d208a6b864de9146087312' + c = p.pipenv('install') + assert c.return_code == 0 + + @pytest.mark.extras @pytest.mark.lock @pytest.mark.vcs