Skip to content

Commit 0da2e84

Browse files
authored
Merge pull request #91 from nexB/source_only
Add --prefer-source option #90
2 parents 9008e9f + e0ce657 commit 0da2e84

27 files changed

+659
-88
lines changed

CHANGELOG.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@ Changelog
22
=========
33

44

5+
v0.9.1
6+
------
7+
8+
- Add --prefer-source option, to prefer source packages over binary ones
9+
if no source distribution is available then binary distributions are used.
10+
11+
512
v0.9.0
613
------
714

docs/source/dependencies-design.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,9 @@ repositories.
223223
PyPI "simple" API. Both the "simple" API and the PyPI JSON
224224
"warehouse-style" API are supported.
225225

226+
- ``--prefer-source``: when set, prefer source distribution instead
227+
of binary distribution. In case there is no source distribution
228+
available, the tool should provide binary distribution.
226229

227230
Strategy and error processing:
228231
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

src/python_inspector/api.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ def resolve_dependencies(
7777
use_pypi_json_api=False,
7878
verbose=False,
7979
analyze_setup_py_insecurely=False,
80+
prefer_source=False,
8081
printer=print,
8182
):
8283
"""
@@ -249,7 +250,9 @@ def resolve_dependencies(
249250
[
250251
pkg.to_dict()
251252
for pkg in list(
252-
get_pypi_data_from_purl(package, repos=repos, environment=environment)
253+
get_pypi_data_from_purl(
254+
package, repos=repos, environment=environment, prefer_source=prefer_source
255+
)
253256
)
254257
],
255258
)

src/python_inspector/package_data.py

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,16 @@
2525

2626

2727
def get_pypi_data_from_purl(
28-
purl: str, environment: Environment, repos: List[PypiSimpleRepository]
28+
purl: str, environment: Environment, repos: List[PypiSimpleRepository], prefer_source: bool
2929
) -> PackageData:
3030
"""
3131
Generate `Package` object from the `purl` string of pypi type
3232
3333
``purl`` is a package-url of pypi type
3434
``environment`` is a `Environment` object defaulting Python version 3.8 and linux OS
3535
``repos`` is a list of `PypiSimpleRepository` objects
36+
``prefer_source`` is a boolean value to prefer source distribution over wheel,
37+
if no source distribution is available then wheel is used
3638
"""
3739
purl = PackageURL.from_string(purl)
3840
name = purl.name
@@ -53,23 +55,29 @@ def get_pypi_data_from_purl(
5355
bug_tracking_url = get_pypi_bugtracker_url(project_urls)
5456
python_version = get_python_version_from_env_tag(python_version=environment.python_version)
5557
valid_distribution_urls = []
56-
valid_distribution_urls.extend(
57-
list(
58-
get_wheel_download_urls(
59-
purl=purl,
60-
repos=repos,
61-
environment=environment,
62-
python_version=python_version,
63-
)
64-
)
65-
)
58+
6659
valid_distribution_urls.append(
6760
get_sdist_download_url(
6861
purl=purl,
6962
repos=repos,
7063
python_version=python_version,
7164
)
7265
)
66+
67+
# if prefer_source is True then only source distribution is used
68+
# in case of no source distribution available then wheel is used
69+
if not valid_distribution_urls or not prefer_source:
70+
valid_distribution_urls.extend(
71+
list(
72+
get_wheel_download_urls(
73+
purl=purl,
74+
repos=repos,
75+
environment=environment,
76+
python_version=python_version,
77+
)
78+
)
79+
)
80+
7381
urls = response.get("urls") or []
7482
for url in urls:
7583
dist_url = url.get("url")

src/python_inspector/resolve_cli.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020

2121
TRACE = False
2222

23-
__version__ = "0.9.0"
23+
__version__ = "0.9.1"
2424

2525
DEFAULT_PYTHON_VERSION = "38"
2626
PYPI_SIMPLE_URL = "https://pypi.org/simple"
@@ -151,6 +151,12 @@ def print_version(ctx, param, value):
151151
help="Enable collection of requirements in setup.py that compute these"
152152
" dynamically. This is an insecure operation as it can run arbitrary code.",
153153
)
154+
@click.option(
155+
"--prefer-source",
156+
is_flag=True,
157+
help="Prefer source distributions over binary distributions"
158+
" if no source distribution is available then binary distributions are used",
159+
)
154160
@click.option(
155161
"--verbose",
156162
is_flag=True,
@@ -182,6 +188,7 @@ def resolve_dependencies(
182188
use_cached_index=False,
183189
use_pypi_json_api=False,
184190
analyze_setup_py_insecurely=False,
191+
prefer_source=False,
185192
verbose=TRACE,
186193
):
187194
"""
@@ -194,7 +201,10 @@ def resolve_dependencies(
194201
linux OS.
195202
196203
Download from the provided PyPI simple --index-url INDEX(s) URLs defaulting
197-
to PyPI.org
204+
to PyPI.org.
205+
206+
Provide source distributions over binary distributions with the --prefer-source
207+
option. If no source distribution is available then binary distributions are used.
198208
199209
Error and progress are printed to stderr.
200210
@@ -250,6 +260,7 @@ def resolve_dependencies(
250260
verbose=verbose,
251261
analyze_setup_py_insecurely=analyze_setup_py_insecurely,
252262
printer=click.secho,
263+
prefer_source=prefer_source,
253264
)
254265
output = dict(
255266
headers=headers,

src/python_inspector/utils_pypi.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,7 @@ def download_sdist(
336336
fetched_sdist_filename = None
337337

338338
for repo in repos:
339-
sdist = get_valid_sdist(repo, name, version, python_version=DEFAULT_PYTHON_VERSION)
339+
sdist = get_valid_sdist(repo, name, version, python_version=python_version)
340340
if not sdist:
341341
if TRACE_DEEP:
342342
print(f" download_sdist: No valid sdist for {name}=={version}")

tests/data/azure-devops.req-310-expected.json

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"headers": {
33
"tool_name": "python-inspector",
44
"tool_homepageurl": "https://github.com/nexB/python-inspector",
5-
"tool_version": "0.9.0",
5+
"tool_version": "0.9.1",
66
"options": [
77
"--requirement /home/tg1999/Desktop/python-inspector-1/tests/data/azure-devops.req.txt",
88
"--index-url https://pypi.org/simple",
@@ -945,12 +945,12 @@
945945
"type": "pypi",
946946
"namespace": null,
947947
"name": "cryptography",
948-
"version": "38.0.2",
948+
"version": "38.0.3",
949949
"qualifiers": {},
950950
"subpath": null,
951951
"primary_language": "Python",
952952
"description": "cryptography is a package which provides cryptographic recipes and primitives to Python developers.\npyca/cryptography\n=================\n\n.. image:: https://img.shields.io/pypi/v/cryptography.svg\n :target: https://pypi.org/project/cryptography/\n :alt: Latest Version\n\n.. image:: https://readthedocs.org/projects/cryptography/badge/?version=latest\n :target: https://cryptography.io\n :alt: Latest Docs\n\n.. image:: https://github.com/pyca/cryptography/workflows/CI/badge.svg?branch=main\n :target: https://github.com/pyca/cryptography/actions?query=workflow%3ACI+branch%3Amain\n\n\n``cryptography`` is a package which provides cryptographic recipes and\nprimitives to Python developers. Our goal is for it to be your \"cryptographic\nstandard library\". It supports Python 3.6+ and PyPy3 7.2+.\n\n``cryptography`` includes both high level recipes and low level interfaces to\ncommon cryptographic algorithms such as symmetric ciphers, message digests, and\nkey derivation functions. For example, to encrypt something with\n``cryptography``'s high level symmetric encryption recipe:\n\n.. code-block:: pycon\n\n >>> from cryptography.fernet import Fernet\n >>> # Put this somewhere safe!\n >>> key = Fernet.generate_key()\n >>> f = Fernet(key)\n >>> token = f.encrypt(b\"A really secret message. Not for prying eyes.\")\n >>> token\n '...'\n >>> f.decrypt(token)\n 'A really secret message. Not for prying eyes.'\n\nYou can find more information in the `documentation`_.\n\nYou can install ``cryptography`` with:\n\n.. code-block:: console\n\n $ pip install cryptography\n\nFor full details see `the installation documentation`_.\n\nDiscussion\n~~~~~~~~~~\n\nIf you run into bugs, you can file them in our `issue tracker`_.\n\nWe maintain a `cryptography-dev`_ mailing list for development discussion.\n\nYou can also join ``#pyca`` on ``irc.libera.chat`` to ask questions or get\ninvolved.\n\nSecurity\n~~~~~~~~\n\nNeed to report a security issue? Please consult our `security reporting`_\ndocumentation.\n\n\n.. _`documentation`: https://cryptography.io/\n.. _`the installation documentation`: https://cryptography.io/en/latest/installation/\n.. _`issue tracker`: https://github.com/pyca/cryptography/issues\n.. _`cryptography-dev`: https://mail.python.org/mailman/listinfo/cryptography-dev\n.. _`security reporting`: https://cryptography.io/en/latest/security/",
953-
"release_date": "2022-10-11T18:57:26",
953+
"release_date": "2022-11-01T21:48:36",
954954
"parties": [
955955
{
956956
"type": "person",
@@ -982,11 +982,11 @@
982982
"Topic :: Security :: Cryptography"
983983
],
984984
"homepage_url": "https://github.com/pyca/cryptography",
985-
"download_url": "https://files.pythonhosted.org/packages/92/3d/6f9b9f562c2cc7ff4985bc18822308edbf546de1475563ad51410874c7e3/cryptography-38.0.2-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
986-
"size": 4151333,
985+
"download_url": "https://files.pythonhosted.org/packages/bd/b4/2f8532124bda7470af31b6d9322b5bbb74e3bde94030f9b3a88450f12c8e/cryptography-38.0.3-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
986+
"size": 4151214,
987987
"sha1": null,
988-
"md5": "78cc9f5b632f9a44b51566366ed5e37c",
989-
"sha256": "9b99713109d76ad35736dcc4e47d54fbaa36cce761adc0333db75e86621fa68c",
988+
"md5": "5f979c7f0729477e2fb830f8fe525799",
989+
"sha256": "b1b52c9e5f8aa2b802d48bd693190341fae201ea51c7a167d69fc48b60e8a959",
990990
"sha512": null,
991991
"bug_tracking_url": null,
992992
"code_view_url": "https://github.com/pyca/cryptography/",
@@ -1007,20 +1007,20 @@
10071007
"dependencies": [],
10081008
"repository_homepage_url": null,
10091009
"repository_download_url": null,
1010-
"api_data_url": "https://pypi.org/pypi/cryptography/38.0.2/json",
1010+
"api_data_url": "https://pypi.org/pypi/cryptography/38.0.3/json",
10111011
"datasource_id": null,
1012-
"purl": "pkg:pypi/[email protected].2"
1012+
"purl": "pkg:pypi/[email protected].3"
10131013
},
10141014
{
10151015
"type": "pypi",
10161016
"namespace": null,
10171017
"name": "cryptography",
1018-
"version": "38.0.2",
1018+
"version": "38.0.3",
10191019
"qualifiers": {},
10201020
"subpath": null,
10211021
"primary_language": "Python",
10221022
"description": "cryptography is a package which provides cryptographic recipes and primitives to Python developers.\npyca/cryptography\n=================\n\n.. image:: https://img.shields.io/pypi/v/cryptography.svg\n :target: https://pypi.org/project/cryptography/\n :alt: Latest Version\n\n.. image:: https://readthedocs.org/projects/cryptography/badge/?version=latest\n :target: https://cryptography.io\n :alt: Latest Docs\n\n.. image:: https://github.com/pyca/cryptography/workflows/CI/badge.svg?branch=main\n :target: https://github.com/pyca/cryptography/actions?query=workflow%3ACI+branch%3Amain\n\n\n``cryptography`` is a package which provides cryptographic recipes and\nprimitives to Python developers. Our goal is for it to be your \"cryptographic\nstandard library\". It supports Python 3.6+ and PyPy3 7.2+.\n\n``cryptography`` includes both high level recipes and low level interfaces to\ncommon cryptographic algorithms such as symmetric ciphers, message digests, and\nkey derivation functions. For example, to encrypt something with\n``cryptography``'s high level symmetric encryption recipe:\n\n.. code-block:: pycon\n\n >>> from cryptography.fernet import Fernet\n >>> # Put this somewhere safe!\n >>> key = Fernet.generate_key()\n >>> f = Fernet(key)\n >>> token = f.encrypt(b\"A really secret message. Not for prying eyes.\")\n >>> token\n '...'\n >>> f.decrypt(token)\n 'A really secret message. Not for prying eyes.'\n\nYou can find more information in the `documentation`_.\n\nYou can install ``cryptography`` with:\n\n.. code-block:: console\n\n $ pip install cryptography\n\nFor full details see `the installation documentation`_.\n\nDiscussion\n~~~~~~~~~~\n\nIf you run into bugs, you can file them in our `issue tracker`_.\n\nWe maintain a `cryptography-dev`_ mailing list for development discussion.\n\nYou can also join ``#pyca`` on ``irc.libera.chat`` to ask questions or get\ninvolved.\n\nSecurity\n~~~~~~~~\n\nNeed to report a security issue? Please consult our `security reporting`_\ndocumentation.\n\n\n.. _`documentation`: https://cryptography.io/\n.. _`the installation documentation`: https://cryptography.io/en/latest/installation/\n.. _`issue tracker`: https://github.com/pyca/cryptography/issues\n.. _`cryptography-dev`: https://mail.python.org/mailman/listinfo/cryptography-dev\n.. _`security reporting`: https://cryptography.io/en/latest/security/",
1023-
"release_date": "2022-10-11T18:59:25",
1023+
"release_date": "2022-11-01T21:53:57",
10241024
"parties": [
10251025
{
10261026
"type": "person",
@@ -1052,11 +1052,11 @@
10521052
"Topic :: Security :: Cryptography"
10531053
],
10541054
"homepage_url": "https://github.com/pyca/cryptography",
1055-
"download_url": "https://files.pythonhosted.org/packages/63/82/a6e21842f2e31b3874f01c112093b8bf8af119f5ed999bbd667a81de720b/cryptography-38.0.2.tar.gz",
1056-
"size": 599757,
1055+
"download_url": "https://files.pythonhosted.org/packages/13/dd/a9608b7aebe5d2dc0c98a4b2090a6b815628efa46cc1c046b89d8cd25f4c/cryptography-38.0.3.tar.gz",
1056+
"size": 599876,
10571057
"sha1": null,
1058-
"md5": "5560580a72fe2d7a1731a84ee191dd1f",
1059-
"sha256": "7a022ec87c7a8bdad99f516a4ee6ffcb3a2bc31487577f9eccbc9b2edb1a8fd4",
1058+
"md5": "2148f1283f22df0677e204e46bccaf06",
1059+
"sha256": "bfbe6ee19615b07a98b1d2287d6a6073f734735b49ee45b11324d85efc4d5cbd",
10601060
"sha512": null,
10611061
"bug_tracking_url": null,
10621062
"code_view_url": "https://github.com/pyca/cryptography/",
@@ -1077,9 +1077,9 @@
10771077
"dependencies": [],
10781078
"repository_homepage_url": null,
10791079
"repository_download_url": null,
1080-
"api_data_url": "https://pypi.org/pypi/cryptography/38.0.2/json",
1080+
"api_data_url": "https://pypi.org/pypi/cryptography/38.0.3/json",
10811081
"datasource_id": null,
1082-
"purl": "pkg:pypi/[email protected].2"
1082+
"purl": "pkg:pypi/[email protected].3"
10831083
},
10841084
{
10851085
"type": "pypi",
@@ -2419,7 +2419,7 @@
24192419
"package": "pkg:pypi/[email protected]",
24202420
"dependencies": [
24212421
"pkg:pypi/[email protected]",
2422-
"pkg:pypi/[email protected].2",
2422+
"pkg:pypi/[email protected].3",
24232423
"pkg:pypi/[email protected]"
24242424
]
24252425
},
@@ -2442,7 +2442,7 @@
24422442
"dependencies": []
24432443
},
24442444
{
2445-
"package": "pkg:pypi/[email protected].2",
2445+
"package": "pkg:pypi/[email protected].3",
24462446
"dependencies": [
24472447
"pkg:pypi/[email protected]"
24482448
]

0 commit comments

Comments
 (0)