200 lines
5.9 KiB
Python
200 lines
5.9 KiB
Python
import json
|
|
import os
|
|
import sys
|
|
from collections import defaultdict
|
|
|
|
from pipenv.routines.lock import do_lock
|
|
from pipenv.routines.outdated import do_outdated
|
|
from pipenv.routines.sync import do_sync
|
|
from pipenv.utils.dependencies import (
|
|
expansive_install_req_from_line,
|
|
get_pipfile_category_using_lockfile_section,
|
|
)
|
|
from pipenv.utils.project import ensure_project
|
|
from pipenv.utils.requirements import add_index_to_pipfile
|
|
from pipenv.utils.resolver import venv_resolve_deps
|
|
from pipenv.vendor import click
|
|
|
|
|
|
def do_update(
|
|
project,
|
|
python=None,
|
|
pre=False,
|
|
system=False,
|
|
packages=None,
|
|
editable_packages=None,
|
|
site_packages=False,
|
|
pypi_mirror=None,
|
|
dev=False,
|
|
categories=None,
|
|
index_url=None,
|
|
extra_pip_args=None,
|
|
quiet=False,
|
|
bare=False,
|
|
dry_run=None,
|
|
outdated=False,
|
|
clear=False,
|
|
lock_only=False,
|
|
):
|
|
ensure_project(
|
|
project,
|
|
python=python,
|
|
pypi_mirror=pypi_mirror,
|
|
warn=(not quiet),
|
|
site_packages=site_packages,
|
|
clear=clear,
|
|
)
|
|
packages = [p for p in (packages or []) if p]
|
|
editable = [p for p in (editable_packages or []) if p]
|
|
if not outdated:
|
|
outdated = bool(dry_run)
|
|
if not packages:
|
|
click.echo(
|
|
"{} {} {} {}{}".format(
|
|
click.style("Running", bold=True),
|
|
click.style("$ pipenv lock", fg="yellow", bold=True),
|
|
click.style("then", bold=True),
|
|
click.style("$ pipenv sync", fg="yellow", bold=True),
|
|
click.style(".", bold=True),
|
|
)
|
|
)
|
|
do_lock(
|
|
project,
|
|
clear=clear,
|
|
pre=pre,
|
|
pypi_mirror=pypi_mirror,
|
|
write=not outdated,
|
|
extra_pip_args=extra_pip_args,
|
|
)
|
|
else:
|
|
upgrade(
|
|
project,
|
|
pre=pre,
|
|
system=system,
|
|
packages=packages,
|
|
editable_packages=editable,
|
|
pypi_mirror=pypi_mirror,
|
|
categories=categories,
|
|
index_url=index_url,
|
|
dev=dev,
|
|
lock_only=lock_only,
|
|
extra_pip_args=extra_pip_args,
|
|
)
|
|
|
|
if outdated:
|
|
do_outdated(
|
|
project,
|
|
clear=clear,
|
|
pre=pre,
|
|
pypi_mirror=pypi_mirror,
|
|
)
|
|
else:
|
|
do_sync(
|
|
project,
|
|
dev=dev,
|
|
categories=categories,
|
|
python=python,
|
|
bare=bare,
|
|
clear=clear,
|
|
pypi_mirror=pypi_mirror,
|
|
extra_pip_args=extra_pip_args,
|
|
)
|
|
|
|
|
|
def upgrade(
|
|
project,
|
|
pre=False,
|
|
system=False,
|
|
packages=None,
|
|
editable_packages=None,
|
|
pypi_mirror=None,
|
|
index_url=None,
|
|
categories=None,
|
|
dev=False,
|
|
lock_only=False,
|
|
extra_pip_args=None,
|
|
):
|
|
lockfile = project.lockfile()
|
|
if not pre:
|
|
pre = project.settings.get("allow_prereleases")
|
|
if dev:
|
|
categories = ["develop"]
|
|
elif not categories:
|
|
categories = ["default"]
|
|
|
|
index_name = None
|
|
if index_url:
|
|
index_name = add_index_to_pipfile(project, index_url)
|
|
|
|
if extra_pip_args:
|
|
os.environ["PIPENV_EXTRA_PIP_ARGS"] = json.dumps(extra_pip_args)
|
|
|
|
package_args = list(packages) + [f"-e {pkg}" for pkg in editable_packages]
|
|
|
|
requested_install_reqs = defaultdict(dict)
|
|
requested_packages = defaultdict(dict)
|
|
for category in categories:
|
|
pipfile_category = get_pipfile_category_using_lockfile_section(category)
|
|
|
|
for package in package_args[:]:
|
|
install_req, _ = expansive_install_req_from_line(package, expand_env=True)
|
|
if index_name:
|
|
install_req.index = index_name
|
|
name, normalized_name, pipfile_entry = project.generate_package_pipfile_entry(
|
|
install_req, package, category=pipfile_category
|
|
)
|
|
project.add_pipfile_entry_to_pipfile(
|
|
name, normalized_name, pipfile_entry, category=pipfile_category
|
|
)
|
|
requested_packages[pipfile_category][normalized_name] = pipfile_entry
|
|
requested_install_reqs[pipfile_category][normalized_name] = install_req
|
|
|
|
if project.pipfile_exists:
|
|
packages = project.parsed_pipfile.get(pipfile_category, {})
|
|
else:
|
|
packages = project.get_pipfile_section(pipfile_category)
|
|
|
|
if not package_args:
|
|
click.echo("Nothing to upgrade!")
|
|
sys.exit(0)
|
|
|
|
# Resolve package to generate constraints of new package data
|
|
upgrade_lock_data = venv_resolve_deps(
|
|
requested_packages[pipfile_category],
|
|
which=project._which,
|
|
project=project,
|
|
lockfile={},
|
|
category="default",
|
|
pre=pre,
|
|
allow_global=system,
|
|
pypi_mirror=pypi_mirror,
|
|
)
|
|
if not upgrade_lock_data:
|
|
click.echo("Nothing to upgrade!")
|
|
sys.exit(0)
|
|
|
|
for package_name, pipfile_entry in requested_packages[pipfile_category].items():
|
|
if package_name not in packages:
|
|
packages.append(package_name, pipfile_entry)
|
|
else:
|
|
packages[package_name] = pipfile_entry
|
|
|
|
full_lock_resolution = venv_resolve_deps(
|
|
packages,
|
|
which=project._which,
|
|
project=project,
|
|
lockfile={},
|
|
category=pipfile_category,
|
|
pre=pre,
|
|
allow_global=system,
|
|
pypi_mirror=pypi_mirror,
|
|
)
|
|
# Mutate the existing lockfile with the upgrade data for the categories
|
|
for package_name in upgrade_lock_data:
|
|
correct_package_lock = full_lock_resolution.get(package_name)
|
|
if correct_package_lock:
|
|
lockfile[category][package_name] = correct_package_lock
|
|
|
|
lockfile.update({"_meta": project.get_lockfile_meta()})
|
|
project.write_lockfile(lockfile)
|