mirror of
https://github.com/danieldemus/pyp2spec.git
synced 2026-07-27 21:00:37 +02:00
Look for the well-known project URL keys
According to the official specification: https://packaging.python.org/en/latest/specifications/well-known-project-urls/ project URLs' labels can be normalized and then searched for the matches. Attempt to find "homepage" and "source" first, and only return other project URL values if these are not found.
This commit is contained in:
@@ -7,7 +7,7 @@ import tomli_w
|
||||
from pyp2spec.license_processor import check_compliance, resolve_license_expression
|
||||
from pyp2spec.utils import Pyp2specError, normalize_name, get_extras, get_summary_or_placeholder
|
||||
from pyp2spec.utils import prepend_name_with_python, archive_name
|
||||
from pyp2spec.utils import is_archful, get_first_url_or_placeholder
|
||||
from pyp2spec.utils import is_archful, resolve_url
|
||||
from pyp2spec.utils import warn, caution, inform, yay
|
||||
from pyp2spec.pypi_loaders import load_from_pypi, load_core_metadata_from_pypi, CoreMetadataNotFoundError
|
||||
|
||||
@@ -28,7 +28,7 @@ def prepare_package_info(data):
|
||||
"pypi_name": normalize_name(data.get("name")),
|
||||
"pypi_version": data.get("version"),
|
||||
"summary": get_summary_or_placeholder(data.get("summary")),
|
||||
"url": get_first_url_or_placeholder(project_urls),
|
||||
"url": resolve_url(project_urls),
|
||||
"extras": get_extras(data.get("requires_dist", [])),
|
||||
"license_files_present": bool(data.get("license_files")),
|
||||
"license": resolve_license_expression(data),
|
||||
|
||||
+24
-5
@@ -3,6 +3,7 @@ This module contains common functions and classes imported in multiple other mod
|
||||
"""
|
||||
|
||||
import re
|
||||
import string
|
||||
from functools import partial
|
||||
|
||||
import click
|
||||
@@ -152,13 +153,31 @@ def is_archful(archive_urls):
|
||||
return False
|
||||
|
||||
|
||||
def get_first_url_or_placeholder(urls):
|
||||
def _normalize_url_label(label: str) -> str:
|
||||
"""
|
||||
Copied verbatim from
|
||||
https://packaging.python.org/en/latest/specifications/well-known-project-urls/#label-normalization
|
||||
"""
|
||||
chars_to_remove = string.punctuation + string.whitespace
|
||||
removal_map = str.maketrans("", "", chars_to_remove)
|
||||
return label.translate(removal_map).lower()
|
||||
|
||||
|
||||
def resolve_url(urls):
|
||||
"""
|
||||
Project urls are an optional field and come in a form of a dict, e.g.:
|
||||
{"homepage": "https://mypackagehomepage.com"}.
|
||||
There may be multiple urls defined and keys are arbitrary.
|
||||
As there's no way to programmatically determine "the best" url for the
|
||||
spec file, return the first existing url from the dict.
|
||||
Try to return url for normalized "homepage", then "source" keys.
|
||||
Otherwise return the first value from the dictionary or "..." if the dict is empty.
|
||||
"""
|
||||
|
||||
return list(urls.values())[0] if urls else "..."
|
||||
normalized_urls = {_normalize_url_label(k): v for k, v in urls.items()}
|
||||
print(normalized_urls)
|
||||
return (
|
||||
normalized_urls.get("homepage")
|
||||
or normalized_urls.get("source")
|
||||
or normalized_urls.get("sourcecode")
|
||||
or normalized_urls.get("github")
|
||||
or normalized_urls.get("repository")
|
||||
or next(iter(normalized_urls.values()), "...")
|
||||
)
|
||||
|
||||
@@ -7,7 +7,7 @@ Summary: Composable command line interface toolkit
|
||||
# Check if the automatically generated License and its spelling is correct for Fedora
|
||||
# https://docs.fedoraproject.org/en-US/packaging-guidelines/LicensingGuidelines/
|
||||
License: BSD-3-Clause
|
||||
URL: https://palletsprojects.com/donate
|
||||
URL: https://github.com/pallets/click/
|
||||
Source: %{pypi_source click}
|
||||
|
||||
BuildArch: noarch
|
||||
|
||||
@@ -7,7 +7,7 @@ Summary: Fundamental package for array computing in Python
|
||||
# Check if the automatically generated License and its spelling is correct for Fedora
|
||||
# https://docs.fedoraproject.org/en-US/packaging-guidelines/LicensingGuidelines/
|
||||
License: BSD-3-Clause
|
||||
URL: https://github.com/numpy/numpy/issues
|
||||
URL: https://github.com/numpy/numpy
|
||||
Source: %{pypi_source numpy}
|
||||
|
||||
BuildRequires: python3-devel
|
||||
|
||||
@@ -6,7 +6,7 @@ Summary: Python documentation generator
|
||||
|
||||
# No license information obtained, it's up to the packager to fill it in
|
||||
License: ...
|
||||
URL: https://www.sphinx-doc.org/en/master/changes.html
|
||||
URL: https://www.sphinx-doc.org/
|
||||
Source: %{pypi_source sphinx}
|
||||
|
||||
BuildArch: noarch
|
||||
|
||||
@@ -2,7 +2,7 @@ summary = "Python documentation generator"
|
||||
pypi_version = "8.1.3"
|
||||
pypi_name = "sphinx"
|
||||
python_name = "python-sphinx"
|
||||
url = "https://www.sphinx-doc.org/en/master/changes.html"
|
||||
url = "https://www.sphinx-doc.org/"
|
||||
source = "PyPI"
|
||||
extras = [
|
||||
"docs",
|
||||
|
||||
@@ -3,7 +3,7 @@ license = "BSD-3-Clause"
|
||||
pypi_name = "click"
|
||||
pypi_version = "8.1.7"
|
||||
python_name = "python-click"
|
||||
url = "https://palletsprojects.com/donate"
|
||||
url = "https://github.com/pallets/click/"
|
||||
source = "PyPI"
|
||||
extras = []
|
||||
archful = false
|
||||
|
||||
@@ -4,7 +4,7 @@ pypi_version = "1.25.2"
|
||||
license = "BSD-3-Clause"
|
||||
pypi_name = "numpy"
|
||||
python_name = "python-numpy"
|
||||
url = "https://github.com/numpy/numpy/issues"
|
||||
url = "https://github.com/numpy/numpy"
|
||||
source = "PyPI"
|
||||
automode = true
|
||||
extras = []
|
||||
|
||||
+4
-4
@@ -3,7 +3,7 @@ import pytest
|
||||
from pyp2spec.utils import filter_license_classifiers, prepend_name_with_python
|
||||
from pyp2spec.utils import normalize_name, get_extras, is_archful
|
||||
from pyp2spec.utils import normalize_as_wheel_name, archive_name
|
||||
from pyp2spec.utils import get_first_url_or_placeholder, SdistNotFoundError
|
||||
from pyp2spec.utils import resolve_url, SdistNotFoundError
|
||||
|
||||
|
||||
def test_license_classifier_read_correctly():
|
||||
@@ -161,7 +161,7 @@ def test_archive_name_empty_list():
|
||||
|
||||
def test_project_urls_valid_single():
|
||||
urls = {"homepage": "https://example.com"}
|
||||
assert get_first_url_or_placeholder(urls) == "https://example.com"
|
||||
assert resolve_url(urls) == "https://example.com"
|
||||
|
||||
|
||||
def test_project_urls_valid_multiple():
|
||||
@@ -169,8 +169,8 @@ def test_project_urls_valid_multiple():
|
||||
"homepage": "https://example.com",
|
||||
"documentation": "https://docs.example.com",
|
||||
}
|
||||
assert get_first_url_or_placeholder(urls) == "https://example.com"
|
||||
assert resolve_url(urls) == "https://example.com"
|
||||
|
||||
|
||||
def test_project_urls_empty():
|
||||
assert get_first_url_or_placeholder({}) == "..."
|
||||
assert resolve_url({}) == "..."
|
||||
|
||||
Reference in New Issue
Block a user