Skip to content

Commit

Permalink
Merge pull request #4896 from den4uk/verify-hash-command
Browse files Browse the repository at this point in the history
New command: verify Pipfile.lock hash is up to date
  • Loading branch information
oz123 committed Feb 10, 2022
2 parents ef82533 + 41e1748 commit 880f91c
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 1 deletion.
6 changes: 6 additions & 0 deletions docs/advanced.rst
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,12 @@ Or you can install packages exactly as specified in ``Pipfile.lock`` using the `

``pipenv install --ignore-pipfile`` is nearly equivalent to ``pipenv sync``, but ``pipenv sync`` will *never* attempt to re-lock your dependencies as it is considered an atomic operation. ``pipenv install`` by default does attempt to re-lock unless using the ``--deploy`` flag.

You may only wish to verify your ``Pipfile.lock`` is up-to-date with dependencies specified in the ``Pipfile``, without installing::

$ pipenv verify

The command will perform a verification, and return an exit code ``1`` when dependency locking is needed. This may be useful for cases when the ``Pipfile.lock`` file is subject to version control, so this command can be used within your CI/CD pipelines.

Deploying System Dependencies
/////////////////////////////

Expand Down
1 change: 1 addition & 0 deletions news/4893.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
New CLI command ``verify``, checks the Pipfile.lock is up-to-date
22 changes: 22 additions & 0 deletions pipenv/cli/command.py
Original file line number Diff line number Diff line change
Expand Up @@ -700,5 +700,27 @@ def scripts(state):
echo("\n".join(fix_utf8(line) for line in lines))


@cli.command(
short_help="Verify the hash in Pipfile.lock is up-to-date.",
context_settings=CONTEXT_SETTINGS,
)
@pass_state
def verify(state):
"""Verify the hash in Pipfile.lock is up-to-date."""
if not state.project.pipfile_exists:
echo("No Pipfile present at project home.", err=True)
sys.exit(1)
if state.project.get_lockfile_hash() != state.project.calculate_pipfile_hash():
echo(
'Pipfile.lock is out-of-date. Run {} to update.'.format(
crayons.yellow("$ pipenv lock", bold=True)
),
err=True
)
sys.exit(1)
echo(crayons.green('Pipfile.lock is up-to-date.'))
sys.exit(0)


if __name__ == "__main__":
cli()
43 changes: 42 additions & 1 deletion tests/integration/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import os
import re

from pathlib import Path
import pytest

from flaky import flaky
Expand Down Expand Up @@ -291,3 +291,44 @@ def test_pipenv_outdated_prerelease(PipenvInstance):
f.write(contents)
c = p.pipenv('update --pre --outdated')
assert c.returncode == 0


@pytest.mark.cli
def test_pipenv_verify_without_pipfile(PipenvInstance):
with PipenvInstance(pipfile=False) as p:
c = p.pipenv('verify')
assert c.returncode == 1
assert 'No Pipfile present at project home.' in c.stderr


@pytest.mark.cli
def test_pipenv_verify_without_pipfile_lock(PipenvInstance):
with PipenvInstance() as p:
c = p.pipenv('verify')
assert c.returncode == 1
assert 'Pipfile.lock is out-of-date.' in c.stderr


@pytest.mark.cli
def test_pipenv_verify_locked_passing(PipenvInstance):
with PipenvInstance() as p:
p.pipenv('lock')
c = p.pipenv('verify')
assert c.returncode == 0
assert 'Pipfile.lock is up-to-date.' in c.stdout


@pytest.mark.cli
def test_pipenv_verify_locked_outdated_failing(PipenvInstance):
with PipenvInstance() as p:
p.pipenv('lock')

# modify the Pipfile
pf = Path(p.path).joinpath('Pipfile')
pf_data = pf.read_text()
pf_new = re.sub(r'\[packages\]', '[packages]\nrequests = "*"', pf_data)
pf.write_text(pf_new)

c = p.pipenv('verify')
assert c.returncode == 1
assert 'Pipfile.lock is out-of-date.' in c.stderr

0 comments on commit 880f91c

Please sign in to comment.