Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

requirements command improvements, fixes issue 5755. #5757

Merged
merged 6 commits into from
Jun 30, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 6 additions & 31 deletions pipenv/cli/command.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import os
import re
import sys

from pipenv import environments
Expand All @@ -23,7 +22,6 @@
upgrade_options,
verbose_option,
)
from pipenv.utils.dependencies import get_lockfile_section_using_pipfile_category
from pipenv.utils.environment import load_dot_env
from pipenv.utils.processes import subprocess_run
from pipenv.vendor import click
Expand Down Expand Up @@ -780,40 +778,17 @@ def verify(state):
def requirements(
state, dev=False, dev_only=False, hash=False, exclude_markers=False, categories=""
):
from pipenv.utils.dependencies import convert_deps_to_pip
from pipenv.routines.requirements import generate_requirements

lockfile = state.project.load_lockfile(expand_env_vars=False)

for i, package_index in enumerate(lockfile["_meta"]["sources"]):
prefix = "-i" if i == 0 else "--extra-index-url"
echo(" ".join([prefix, package_index["url"]]))

deps = {}
categories_list = re.split(r", *| ", categories) if categories else []

if categories_list:
for category in categories_list:
category = get_lockfile_section_using_pipfile_category(category.strip())
deps.update(lockfile.get(category, {}))
else:
if dev or dev_only:
deps.update(lockfile["develop"])
if not dev_only:
deps.update(lockfile["default"])

pip_deps = convert_deps_to_pip(
deps,
project=None,
include_index=False,
generate_requirements(
project=state.project,
dev=dev,
dev_only=dev_only,
include_hashes=hash,
include_markers=not exclude_markers,
categories=categories,
)

for d in pip_deps:
echo(d)

sys.exit(0)


if __name__ == "__main__":
cli()
Expand Down
78 changes: 78 additions & 0 deletions pipenv/routines/requirements.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import re
import sys

from pipenv.utils.dependencies import get_lockfile_section_using_pipfile_category
from pipenv.vendor import click


def requirements_from_deps(deps, include_hashes=True, include_markers=True):
pip_packages = []

for package_name, package_info in deps.items():
# Handling git repositories
if "git" in package_info:
git = package_info["git"]
ref = package_info.get("ref", "")
extras = (
"[{}]".format(",".join(package_info.get("extras", [])))
if "extras" in package_info
else ""
)
pip_package = f"{package_name}{extras} @ git+{git}@{ref}"
else:
# Handling packages with hashes and markers
version = package_info.get("version", "").replace("==", "")
hashes = (
" --hash={}".format(" --hash=".join(package_info["hashes"]))
if include_hashes and "hashes" in package_info
else ""
)
markers = (
"; {}".format(package_info["markers"])
matteius marked this conversation as resolved.
Show resolved Hide resolved
if include_markers and "markers" in package_info
else ""
)
pip_package = f"{package_name}=={version}{hashes}{markers}"

# Append to the list
pip_packages.append(pip_package)

# pip_packages contains the pip-installable lines
return pip_packages


def generate_requirements(
project,
dev=False,
dev_only=False,
include_hashes=False,
include_markers=True,
categories="",
):
lockfile = project.load_lockfile(expand_env_vars=False)

for i, package_index in enumerate(lockfile["_meta"]["sources"]):
prefix = "-i" if i == 0 else "--extra-index-url"
click.echo(" ".join([prefix, package_index["url"]]))

deps = {}
categories_list = re.split(r", *| ", categories) if categories else []

if categories_list:
for category in categories_list:
category = get_lockfile_section_using_pipfile_category(category.strip())
deps.update(lockfile.get(category, {}))
else:
if dev or dev_only:
deps.update(lockfile["develop"])
if not dev_only:
deps.update(lockfile["default"])

pip_installable_lines = requirements_from_deps(
deps, include_hashes=include_hashes, include_markers=include_markers
)

for line in pip_installable_lines:
click.echo(line)

sys.exit(0)