From d21efa08c79427bb05189269ae05e892b9196e7a Mon Sep 17 00:00:00 2001 From: Tzu-ping Chung Date: Thu, 3 May 2018 23:19:47 +0800 Subject: [PATCH] Check lockfile exists on sync, and don't update it Matching the behaviour mentioned in: https://github.com/pypa/pipenv/issues/1463#issuecomment-386297896 --- pipenv/core.py | 23 ++++++++++++++----- tests/integration/test_sync.py | 42 ++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 6 deletions(-) create mode 100644 tests/integration/test_sync.py diff --git a/pipenv/core.py b/pipenv/core.py index 711ec28d..7ca65872 100644 --- a/pipenv/core.py +++ b/pipenv/core.py @@ -2485,19 +2485,30 @@ def do_sync( unused=False, sequential=False, ): + # The lock file needs to exist because sync won't write to it. + if not project.lockfile_exists: + click.echo( + '{0}: Pipfile.lock is missing! You need to run {1} first.'.format( + crayons.red('Error', bold=True), + crayons.red('$ pipenv lock', bold=True), + ), + err=True, + ) + sys.exit(1) + + # Ensure that virtualenv is available. + ensure_project(three=three, python=python, validate=False) + + # Install everything. requirements_dir = TemporaryDirectory( suffix='-requirements', prefix='pipenv-' ) - # Ensure that virtualenv is available. - ensure_project(three=three, python=python, validate=False) - concurrent = (not sequential) - ensure_lockfile() - # Install everything. do_init( dev=dev, verbose=verbose, - concurrent=concurrent, + concurrent=(not sequential), requirements_dir=requirements_dir, + ignore_pipfile=True, # Don't check if Pipfile and lock match. ) requirements_dir.cleanup() click.echo(crayons.green('All dependencies are now up-to-date!')) diff --git a/tests/integration/test_sync.py b/tests/integration/test_sync.py new file mode 100644 index 00000000..1116ed83 --- /dev/null +++ b/tests/integration/test_sync.py @@ -0,0 +1,42 @@ +import pytest + + +@pytest.mark.sync +def test_sync_error_without_lockfile(PipenvInstance, pypi): + with PipenvInstance(pypi=pypi) as p: + with open(p.pipfile_path, 'w') as f: + f.write(""" +[packages] + """.strip()) + + c = p.pipenv('sync') + assert c.return_code != 0 + assert 'Pipfile.lock is missing!' in c.err + + +@pytest.mark.sync +@pytest.mark.lock +def test_sync_should_not_lock(PipenvInstance, pypi): + """Sync should not touch the lock file, even if Pipfile is changed. + """ + with PipenvInstance(pypi=pypi) as p: + with open(p.pipfile_path, 'w') as f: + f.write(""" +[packages] + """.strip()) + + # Perform initial lock. + c = p.pipenv('lock') + assert c.return_code == 0 + lockfile_content = p.lockfile + assert lockfile_content + + # Make sure sync does not trigger lockfile update. + with open(p.pipfile_path, 'w') as f: + f.write(""" +[packages] +six = "*" + """.strip()) + c = p.pipenv('sync') + assert c.return_code == 0 + assert lockfile_content == p.lockfile