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

Implements requirements command as per #4959 #5013

Merged
merged 15 commits into from
Apr 5, 2022
15 changes: 10 additions & 5 deletions pipenv/cli/command.py
Original file line number Diff line number Diff line change
Expand Up @@ -714,17 +714,22 @@ def verify(state):
context_settings=CONTEXT_SETTINGS,
)
@option("--dev", is_flag=True, default=False, help="Also add development requirements.")
ImreC marked this conversation as resolved.
Show resolved Hide resolved
@option("--dev-only", is_flag=True, default=False, help="Only add development requirements.")
@option("--hash", is_flag=True, default=False, help="Add package hashes.")
@pass_state
def requirements(state, dev=False):
def requirements(state, dev=False, dev_only=False, hash=False):
lockfile = state.project.lockfile_content
for i, package_index in enumerate(lockfile['_meta']['sources']):
prefix = '-i' if i == 0 else '--extra-index-url'
echo(crayons.normal(' '.join([prefix, package_index['url']])))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should output the index verbatim as specified in the Pipfile, without expanding variables. It is fairly common to specify credentials for a private PyPI this way, and writing those into the resulting requirements.txt file is counter-productive.

I'm not sure whether your existing code is already doing this or not, just wanted to mention this need.

for req_name, value in lockfile['default'].items():
echo(crayons.normal(f"{req_name}{value['version']}"))
if dev:
if not dev_only:
for req_name, value in lockfile['default'].items():
hashes = [f' \\\n --hash={h}' for h in value['hashes'] if hash]
echo(crayons.normal(''.join([req_name, value['version'], *hashes])))
if dev or dev_only:
for req_name, value in lockfile['develop'].items():
echo(crayons.normal(f"{req_name}{value['version']}"))
hashes = [f' \\\n --hash={h}' for h in value['hashes'] if hash]
ImreC marked this conversation as resolved.
Show resolved Hide resolved
echo(crayons.normal(''.join([req_name, value['version'], *hashes])))
sys.exit(0)


Expand Down
24 changes: 18 additions & 6 deletions tests/integration/test_requirements.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,27 @@ def test_requirements_generates_requirements_from_lockfile(PipenvInstance):
f.write(contents)
p.pipenv('lock')
c = p.pipenv('requirements')
d = p.pipenv('requirements --dev')
assert c.returncode == 0
assert d.returncode == 0

assert f'{packages[0]}=={packages[1]}' in c.stdout
assert f'{dev_packages[0]}=={dev_packages[1]}' not in c.stdout

d = p.pipenv('requirements --dev')
assert d.returncode == 0
assert f'{packages[0]}=={packages[1]}' in d.stdout
assert f'{dev_packages[0]}=={dev_packages[1]}' in d.stdout

e = p.pipenv('requirements --dev-only')
assert e.returncode == 0
assert f'{packages[0]}=={packages[1]}' not in e.stdout
assert f'{dev_packages[0]}=={dev_packages[1]}' in e.stdout

e = p.pipenv('requirements --hash')
assert e.returncode == 0
assert f'{packages[0]}=={packages[1]}' in e.stdout
for value in p.lockfile['default'].values():
for hash in value['hashes']:
assert f' --hash={hash}' in e.stdout


@pytest.mark.requirements
def test_requirements_generates_requirements_from_lockfile_multiple_sources(PipenvInstance):
Expand All @@ -40,17 +51,18 @@ def test_requirements_generates_requirements_from_lockfile_multiple_sources(Pipe
verify_ssl = true
[[source]]
name = "other_source"
url = "https://some_other_source.org"
url = "https://https://$USERNAME:${{PASSWORD}}@some_other_source.org"
verify_ssl = true
[packages]
{packages[0]}= "=={packages[1]}"
[dev-packages]
{dev_packages[0]}= "=={dev_packages[1]}"
""".strip()
f.write(contents)
p.pipenv('lock')
l = p.pipenv('lock')
assert l.returncode == 0
c = p.pipenv('requirements')
assert c.returncode == 0

assert '-i https://pypi.org/simple' in c.stdout
assert '--extra-index-url https://some_other_source.org' in c.stdout
assert '--extra-index-url https://$USERNAME:${PASSWORD}@some_other_source.org' in c.stdout