Skip to content

Instantly share code, notes, and snippets.

@ovidner
Created January 4, 2018 11:26
Show Gist options
  • Save ovidner/d01661ded87df226334b14fa8f9e69d1 to your computer and use it in GitHub Desktop.
Save ovidner/d01661ded87df226334b14fa8f9e69d1 to your computer and use it in GitHub Desktop.
Detect Pipfile.lock conflicts (https://github.com/pypa/pipenv/issues/1220)
#!/usr/bin/env python
import json
import sys
from itertools import chain, groupby
from os import path
# This assumes that this script is placed in a subdirectory relative to the
# project root, such as /bin
PROJECT_ROOT = path.dirname(path.dirname(path.abspath(__file__)))
PIPFILE_LOCK_PATH = path.join(PROJECT_ROOT, 'Pipfile.lock')
def yield_package_versions(payload, pipfile_lock_section, pipfile_section):
for (pkg_name, pkg) in payload[pipfile_lock_section].items():
yield (pkg_name, pkg.get('version', None), pipfile_section)
def main():
with open(PIPFILE_LOCK_PATH) as f:
pipfile_lock_payload = json.load(f)
grouped_package_versions = (
(pkg_name, [(x[1], x[2]) for x in pkgs])
for (pkg_name, pkgs) in groupby(
sorted(
chain(
yield_package_versions(pipfile_lock_payload, 'default', 'packages'),
yield_package_versions(pipfile_lock_payload, 'develop', 'dev-packages'),
),
key=lambda x: x[0],
),
key=lambda x: x[0],
)
)
has_conflicts = False
for (pkg_name, versions) in grouped_package_versions:
if len(set(x[0] for x in versions)) > 1:
has_conflicts = True
print(f'{pkg_name} has conflicting versions: {versions}')
if has_conflicts:
sys.exit(1)
else:
print('Pipfile.lock is OK!')
sys.exit(0)
if __name__ == '__main__':
main()
@ovidner
Copy link
Author

ovidner commented Jan 4, 2018

  1. Place in a subdirectory one (1) level below Pipfile.lock, such as bin (or adapt the code accordingly).
  2. python bin/check-pipfile-lock.py

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment