Skip to content

Instantly share code, notes, and snippets.

@kokumura
Created January 29, 2020 07:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kokumura/3663fb8080d52a84a26cda1fa927a1bd to your computer and use it in GitHub Desktop.
Save kokumura/3663fb8080d52a84a26cda1fa927a1bd to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
"""sync_pipfile_versions.py
sync Pipfile dependency versions from Pipfile.lock
requires:
- Python >= 3.8
- tomlkit
"""
import sys
import json
from typing import Dict, Union, Any
from argparse import ArgumentParser
from pathlib import Path
import tomlkit
from tomlkit.items import Table, InlineTable
def main() -> int:
parser = ArgumentParser(description=__doc__)
parser.add_argument("--dry-run", action="store_true")
parser.add_argument("--target", metavar='all|dev|nodev', default="all", help="target section")
parser.add_argument("--lockfile", default="Pipfile.lock", type=Path, help="Pipfile.lock")
parser.add_argument("--pipfile", default="Pipfile", type=Path, help="Pipfile (will be overwritten)")
args = parser.parse_args()
with args.pipfile.open() as f:
pipfile = tomlkit.parse(f.read())
with args.lockfile.open() as f:
pipfile_lock = json.load(f)
do_dev: bool
do_nodev: bool
if args.target == "all":
do_dev = True
do_nodev = True
elif args.target == "dev":
do_dev = True
do_nodev = False
elif args.target == "nodev":
do_dev = False
do_nodev = True
else:
print(f"error: --target must be one of ['all', 'dev', 'nodev']", file=sys.stderr)
return 1
if do_dev:
update_packages(pipfile["dev-packages"], {**pipfile_lock["default"], **pipfile_lock.get("develop", {})})
if do_nodev:
update_packages(pipfile["packages"], pipfile_lock["default"])
if not args.dry_run:
with args.pipfile.open("w") as f:
f.write(tomlkit.dumps(pipfile))
else:
print(tomlkit.dumps(pipfile), file=sys.stdout)
return 0
def update_packages(packages: Table, locked_packages: Dict[str, Dict[str, Union[str, Dict[str, Any]]]]) -> None:
for pname in packages:
pbody = packages[pname]
if pname not in locked_packages:
print(f"""WARNING: "{pname}" entry not exists in Pipfile.lock""", file=sys.stderr)
continue
locked_body = locked_packages[pname]
if "version" not in locked_body:
print(f"""WARNING: "{pname}" version not exists in Pipfile.lock""", file=sys.stderr)
locked_version = locked_body["version"]
if isinstance(pbody, str):
orig_version = pbody
packages[pname] = locked_version
elif isinstance(pbody, InlineTable) and "version" in pbody:
orig_version = pbody["version"]
pbody["version"] = locked_version
packages[pname] = pbody
else:
print(f"""WARNING: {pname} cannot idetify orignial format Pipfile""", file=sys.stderr)
continue
print(f"""{pname}{locked_version} """ + ("(not changd)" if orig_version == locked_version else f"(update from {orig_version})"), file=sys.stderr)
if __name__ == '__main__':
sys.exit(main())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment