Skip to content

Commit 921bf09

Browse files
authored
Merge pull request #599 from aboutcode-org/merge_skeleton
Merge skeleton
2 parents fe7895b + 847d55f commit 921bf09

File tree

9 files changed

+97
-62
lines changed

9 files changed

+97
-62
lines changed

.github/workflows/docs-ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ jobs:
99
strategy:
1010
max-parallel: 4
1111
matrix:
12-
python-version: [3.12]
12+
python-version: [3.13]
1313

1414
steps:
1515
- name: Checkout code

.github/workflows/pypi-release.yml

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,10 @@ jobs:
3232
python-version: 3.12
3333

3434
- name: Install pypa/build and twine
35-
run: python -m pip install --user build twine
35+
run: python -m pip install --user --upgrade build twine pkginfo
3636

3737
- name: Build a binary wheel and a source tarball
38-
run: python -m build --sdist --wheel --outdir dist/
38+
run: python -m build --wheel --sdist --outdir dist/
3939

4040
- name: Validate wheel and sdis for Pypi
4141
run: python -m twine check dist/*
@@ -72,6 +72,9 @@ jobs:
7272
needs:
7373
- create-gh-release
7474
runs-on: ubuntu-24.04
75+
environment: pypi-publish
76+
permissions:
77+
id-token: write
7578

7679
steps:
7780
- name: Download built archives
@@ -82,6 +85,4 @@ jobs:
8285

8386
- name: Publish to PyPI
8487
if: startsWith(github.ref, 'refs/tags')
85-
uses: pypa/gh-action-pypi-publish@release/v1
86-
with:
87-
password: ${{ secrets.PYPI_API_TOKEN }}
88+
uses: pypa/gh-action-pypi-publish@release/v1

.readthedocs.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ version: 2
99
build:
1010
os: ubuntu-22.04
1111
tools:
12-
python: "3.11"
12+
python: "3.13"
1313

1414
# Build PDF & ePub
1515
formats:

azure-pipelines.yml

Lines changed: 53 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -13,26 +13,58 @@ jobs:
1313
test_suites:
1414
all: venv/bin/pytest -n 2 -vvs
1515

16-
- template: etc/ci/azure-posix.yml
17-
parameters:
18-
job_name: macos13_cpython
19-
image_name: macOS-13
20-
python_versions: ["3.9", "3.10", "3.11"]
21-
test_suites:
22-
all: venv/bin/pytest -n 2 -vvs
16+
- template: etc/ci/azure-posix.yml
17+
parameters:
18+
job_name: run_code_checks
19+
image_name: ubuntu-24.04
20+
python_versions: ['3.13']
21+
test_suites:
22+
all: make check
2323

24-
- template: etc/ci/azure-win.yml
25-
parameters:
26-
job_name: win2019_cpython
27-
image_name: windows-2019
28-
python_versions: ["3.9", "3.10", "3.11"]
29-
test_suites:
30-
all: venv\Scripts\pytest -n 2 -vvs
24+
- template: etc/ci/azure-posix.yml
25+
parameters:
26+
job_name: ubuntu22_cpython
27+
image_name: ubuntu-22.04
28+
python_versions: ['3.9', '3.10', '3.11', '3.12', '3.13', '3.14']
29+
test_suites:
30+
all: venv/bin/pytest -n 2 -vvs
3131

32-
- template: etc/ci/azure-win.yml
33-
parameters:
34-
job_name: win2022_cpython
35-
image_name: windows-2022
36-
python_versions: ["3.9", "3.10", "3.11"]
37-
test_suites:
38-
all: venv\Scripts\pytest -n 2 -vvs
32+
- template: etc/ci/azure-posix.yml
33+
parameters:
34+
job_name: ubuntu24_cpython
35+
image_name: ubuntu-24.04
36+
python_versions: ['3.9', '3.10', '3.11', '3.12', '3.13', '3.14']
37+
test_suites:
38+
all: venv/bin/pytest -n 2 -vvs
39+
40+
- template: etc/ci/azure-posix.yml
41+
parameters:
42+
job_name: macos14_cpython
43+
image_name: macOS-14
44+
python_versions: ['3.9', '3.10', '3.11', '3.12', '3.13', '3.14']
45+
test_suites:
46+
all: venv/bin/pytest -n 2 -vvs
47+
48+
- template: etc/ci/azure-posix.yml
49+
parameters:
50+
job_name: macos15_cpython
51+
image_name: macOS-15
52+
python_versions: ['3.9', '3.10', '3.11', '3.12', '3.13', '3.14']
53+
test_suites:
54+
all: venv/bin/pytest -n 2 -vvs
55+
56+
- template: etc/ci/azure-win.yml
57+
parameters:
58+
job_name: win2022_cpython
59+
image_name: windows-2022
60+
python_versions: ['3.9', '3.10', '3.11', '3.12', '3.13', '3.14']
61+
test_suites:
62+
all: venv\Scripts\pytest -n 2 -vvs
63+
64+
- template: etc/ci/azure-win.yml
65+
parameters:
66+
job_name: win2025_cpython
67+
image_name: windows-2025
68+
python_versions: ['3.9', '3.10', '3.11', '3.12', '3.13', '3.14']
69+
test_suites:
70+
all: venv\Scripts\pytest -n 2 -vvs

configure

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ create_virtualenv() {
110110
fi
111111

112112
$PYTHON_EXECUTABLE "$VIRTUALENV_PYZ" \
113-
--wheel embed --pip embed --setuptools embed \
113+
--pip embed --setuptools embed \
114114
--seeder pip \
115115
--never-download \
116116
--no-periodic-update \

configure.bat

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ if not exist "%CFG_BIN_DIR%\python.exe" (
110110

111111
if exist "%CFG_ROOT_DIR%\etc\thirdparty\virtualenv.pyz" (
112112
%PYTHON_EXECUTABLE% "%CFG_ROOT_DIR%\etc\thirdparty\virtualenv.pyz" ^
113-
--wheel embed --pip embed --setuptools embed ^
113+
--pip embed --setuptools embed ^
114114
--seeder pip ^
115115
--never-download ^
116116
--no-periodic-update ^
@@ -126,7 +126,7 @@ if not exist "%CFG_BIN_DIR%\python.exe" (
126126
)
127127
)
128128
%PYTHON_EXECUTABLE% "%CFG_ROOT_DIR%\%VIRTUALENV_DIR%\virtualenv.pyz" ^
129-
--wheel embed --pip embed --setuptools embed ^
129+
--pip embed --setuptools embed ^
130130
--seeder pip ^
131131
--never-download ^
132132
--no-periodic-update ^

etc/ci/azure-container-deb.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ jobs:
2121
- job: ${{ parameters.job_name }}
2222

2323
pool:
24-
vmImage: 'ubuntu-16.04'
24+
vmImage: 'ubuntu-22.04'
2525

2626
container:
2727
image: ${{ parameters.container }}

etc/ci/azure-container-rpm.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
parameters:
22
job_name: ''
3-
image_name: 'ubuntu-16.04'
3+
image_name: 'ubuntu-22.04'
44
container: ''
55
python_path: ''
66
python_version: ''

etc/scripts/utils_thirdparty.py

Lines changed: 31 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#!/usr/bin/env python
2+
# -*- coding: utf-8 -*-
23
#
34
# Copyright (c) nexB Inc. and others. All rights reserved.
45
# ScanCode is a trademark of nexB Inc.
@@ -24,13 +25,14 @@
2425
import packageurl
2526
import requests
2627
import saneyaml
27-
import utils_pip_compatibility_tags
2828
from commoncode import fileutils
2929
from commoncode.hash import multi_checksums
3030
from commoncode.text import python_safe_name
3131
from packvers import tags as packaging_tags
3232
from packvers import version as packaging_version
3333

34+
import utils_pip_compatibility_tags
35+
3436
"""
3537
Utilities to manage Python thirparty libraries source, binaries and metadata in
3638
local directories and remote repositories.
@@ -91,8 +93,7 @@
9193
9294
- parse requirement file
9395
- create a TODO queue of requirements to process
94-
- done: create an empty map of processed binary requirements as
95-
{package name: (list of versions/tags}
96+
- done: create an empty map of processed binary requirements as {package name: (list of versions/tags}
9697
9798
9899
- while we have package reqs in TODO queue, process one requirement:
@@ -114,12 +115,15 @@
114115
TRACE_ULTRA_DEEP = False
115116

116117
# Supported environments
117-
PYTHON_VERSIONS = "39", "310", "311"
118+
PYTHON_VERSIONS = "39", "310", "311", "312", "313", "314"
118119

119120
PYTHON_DOT_VERSIONS_BY_VER = {
120121
"39": "3.9",
121122
"310": "3.10",
122123
"311": "3.11",
124+
"312": "3.12",
125+
"313": "3.13",
126+
"314": "3.14",
123127
}
124128

125129

@@ -131,10 +135,12 @@ def get_python_dot_version(version):
131135

132136

133137
ABIS_BY_PYTHON_VERSION = {
134-
"37": ["cp37", "cp37m", "abi3"],
135-
"38": ["cp38", "cp38m", "abi3"],
136138
"39": ["cp39", "cp39m", "abi3"],
137139
"310": ["cp310", "cp310m", "abi3"],
140+
"311": ["cp311", "cp311m", "abi3"],
141+
"312": ["cp312", "cp312m", "abi3"],
142+
"313": ["cp313", "cp313m", "abi3"],
143+
"314": ["cp314", "cp314m", "abi3"],
138144
}
139145

140146
PLATFORMS_BY_OS = {
@@ -552,8 +558,7 @@ def download(self, dest_dir=THIRDPARTY_DIR):
552558
Download this distribution into `dest_dir` directory.
553559
Return the fetched filename.
554560
"""
555-
if not self.filename:
556-
raise ValueError(f"self.filename has no value but is required: {self.filename!r}")
561+
assert self.filename
557562
if TRACE_DEEP:
558563
print(
559564
f"Fetching distribution of {self.name}=={self.version}:",
@@ -821,9 +826,9 @@ def fetch_license_files(self, dest_dir=THIRDPARTY_DIR, use_cached_index=False):
821826
"""
822827
urls = LinksRepository.from_url(use_cached_index=use_cached_index).links
823828
errors = []
824-
extra_lic_names = [lic.get("file") for lic in self.extra_data.get("licenses", {})]
829+
extra_lic_names = [l.get("file") for l in self.extra_data.get("licenses", {})]
825830
extra_lic_names += [self.extra_data.get("license_file")]
826-
extra_lic_names = [eln for eln in extra_lic_names if eln]
831+
extra_lic_names = [ln for ln in extra_lic_names if ln]
827832
lic_names = [f"{key}.LICENSE" for key in self.get_license_keys()]
828833
for filename in lic_names + extra_lic_names:
829834
floc = os.path.join(dest_dir, filename)
@@ -843,7 +848,7 @@ def fetch_license_files(self, dest_dir=THIRDPARTY_DIR, use_cached_index=False):
843848
if TRACE:
844849
print(f"Fetched license from remote: {lic_url}")
845850

846-
except Exception:
851+
except:
847852
try:
848853
# try licensedb second
849854
lic_url = f"{LICENSEDB_API_URL}/{filename}"
@@ -856,9 +861,8 @@ def fetch_license_files(self, dest_dir=THIRDPARTY_DIR, use_cached_index=False):
856861
if TRACE:
857862
print(f"Fetched license from licensedb: {lic_url}")
858863

859-
except Exception:
860-
msg = f"No text for license {filename} in expression "
861-
f"{self.license_expression!r} from {self}"
864+
except:
865+
msg = f'No text for license {filename} in expression "{self.license_expression}" from {self}'
862866
print(msg)
863867
errors.append(msg)
864868

@@ -998,7 +1002,7 @@ def get_license_link_for_filename(filename, urls):
9981002
exception if no link is found or if there are more than one link for that
9991003
file name.
10001004
"""
1001-
path_or_url = [url for url in urls if url.endswith(f"/{filename}")]
1005+
path_or_url = [l for l in urls if l.endswith(f"/{filename}")]
10021006
if not path_or_url:
10031007
raise Exception(f"Missing link to file: {filename}")
10041008
if not len(path_or_url) == 1:
@@ -1287,7 +1291,7 @@ def is_pure(self):
12871291
def is_pure_wheel(filename):
12881292
try:
12891293
return Wheel.from_filename(filename).is_pure()
1290-
except Exception:
1294+
except:
12911295
return False
12921296

12931297

@@ -1483,7 +1487,8 @@ def get_distributions(self):
14831487
"""
14841488
if self.sdist:
14851489
yield self.sdist
1486-
yield from self.wheels
1490+
for wheel in self.wheels:
1491+
yield wheel
14871492

14881493
def get_url_for_filename(self, filename):
14891494
"""
@@ -1612,8 +1617,7 @@ class PypiSimpleRepository:
16121617
type=dict,
16131618
default=attr.Factory(lambda: defaultdict(dict)),
16141619
metadata=dict(
1615-
help="Mapping of {name: {version: PypiPackage, version: PypiPackage, etc} "
1616-
"available in this repo"
1620+
help="Mapping of {name: {version: PypiPackage, version: PypiPackage, etc} available in this repo"
16171621
),
16181622
)
16191623

@@ -1627,8 +1631,7 @@ class PypiSimpleRepository:
16271631
type=bool,
16281632
default=False,
16291633
metadata=dict(
1630-
help="If True, use any existing on-disk cached PyPI index files. "
1631-
"Otherwise, fetch and cache."
1634+
help="If True, use any existing on-disk cached PyPI index files. Otherwise, fetch and cache."
16321635
),
16331636
)
16341637

@@ -1637,8 +1640,7 @@ def _get_package_versions_map(self, name):
16371640
Return a mapping of all available PypiPackage version for this package name.
16381641
The mapping may be empty. It is ordered by version from oldest to newest
16391642
"""
1640-
if not name:
1641-
raise ValueError(f"name is required: {name!r}")
1643+
assert name
16421644
normalized_name = NameVer.normalize_name(name)
16431645
versions = self.packages[normalized_name]
16441646
if not versions and normalized_name not in self.fetched_package_normalized_names:
@@ -1693,7 +1695,7 @@ def fetch_links(self, normalized_name):
16931695
)
16941696
links = collect_urls(text)
16951697
# TODO: keep sha256
1696-
links = [link.partition("#sha256=") for link in links]
1698+
links = [l.partition("#sha256=") for l in links]
16971699
links = [url for url, _, _sha256 in links]
16981700
return links
16991701

@@ -1914,7 +1916,7 @@ def get_remote_file_content(
19141916
# several redirects and that we can ignore content there. A HEAD request may
19151917
# not get us this last header
19161918
print(f" DOWNLOADING: {url}")
1917-
with requests.get(url, allow_redirects=True, stream=True, headers=headers) as response: # noqa: S113
1919+
with requests.get(url, allow_redirects=True, stream=True, headers=headers) as response:
19181920
status = response.status_code
19191921
if status != requests.codes.ok: # NOQA
19201922
if status == 429 and _delay < 20:
@@ -2133,7 +2135,7 @@ def call(args, verbose=TRACE):
21332135
"""
21342136
if TRACE_DEEP:
21352137
print("Calling:", " ".join(args))
2136-
with subprocess.Popen( # noqa: S603
2138+
with subprocess.Popen(
21372139
args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, encoding="utf-8"
21382140
) as process:
21392141
stdouts = []
@@ -2198,7 +2200,7 @@ def download_wheels_with_pip(
21982200
cli_args.extend(["--requirement", req_file])
21992201

22002202
if TRACE:
2201-
print("Downloading wheels using command:", " ".join(cli_args))
2203+
print(f"Downloading wheels using command:", " ".join(cli_args))
22022204

22032205
existing = set(os.listdir(dest_dir))
22042206
error = False
@@ -2231,7 +2233,7 @@ def download_wheels_with_pip(
22312233

22322234
def check_about(dest_dir=THIRDPARTY_DIR):
22332235
try:
2234-
subprocess.check_output(f"venv/bin/about check {dest_dir}".split()) # noqa: S603
2236+
subprocess.check_output(f"venv/bin/about check {dest_dir}".split())
22352237
except subprocess.CalledProcessError as cpe:
22362238
print()
22372239
print("Invalid ABOUT files:")
@@ -2282,5 +2284,5 @@ def get_license_expression(declared_licenses):
22822284
return get_only_expression_from_extracted_license(declared_licenses)
22832285
except ImportError:
22842286
# Scancode is not installed, clean and join all the licenses
2285-
lics = [python_safe_name(lic).lower() for lic in declared_licenses]
2287+
lics = [python_safe_name(l).lower() for l in declared_licenses]
22862288
return " AND ".join(lics).lower()

0 commit comments

Comments
 (0)