Skip to content

Commit 70a90ab

Browse files
authored
Merge branch 'main' into main
2 parents 5052b42 + 4bf64fe commit 70a90ab

129 files changed

Lines changed: 11613 additions & 1314 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
name: Check and generate PURL Type Docs and Index
2+
3+
on:
4+
push:
5+
paths:
6+
- "types/*.json"
7+
- "schemas/*.json"
8+
- "etc/"
9+
branches:
10+
- main
11+
workflow_dispatch:
12+
# All permissions should be specified at the job level
13+
permissions: { }
14+
15+
jobs:
16+
generate-index-and-docs:
17+
runs-on: ubuntu-latest
18+
permissions:
19+
content: write
20+
21+
steps:
22+
- name: Checkout repository
23+
uses: actions/checkout@v4
24+
25+
- name: Set up Python
26+
uses: actions/setup-python@v4
27+
with:
28+
python-version: '3.x'
29+
30+
- name: Install dependencies
31+
run: make conf
32+
33+
- name: Validate code and data formats
34+
run: make check
35+
36+
- name: Generate index and docs
37+
run: make gendocs
38+
39+
- name: Commit and push changes
40+
run: |
41+
git config --global user.name "github-actions[bot]"
42+
git config --global user.email "github-actions[bot]@users.noreply.github.com"
43+
git add types/ types-doc/
44+
git commit -s -m "Generate updated PURL type documentation" || echo "No changes to commit"
45+
git push

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,4 @@
11
/tmp/
2+
/venv/
3+
/.python-version
4+
.ruff_cache/

Makefile

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
# SPDX-License-Identifier: MIT
2+
# Copyright (c) the purl authors
3+
# Visit https://github.com/package-url/purl-spec and https://packageurl.org for support
4+
5+
PYTHON_EXE?=python3
6+
VENV_LOCATION=venv
7+
ACTIVATE?=. ${VENV_LOCATION}/bin/activate;
8+
9+
CODEGEN?=datamodel-codegen \
10+
--target-python-version 3.10 \
11+
--use-double-quotes \
12+
--use-exact-imports \
13+
--use-standard-collections \
14+
--wrap-string-literal \
15+
--enum-field-as-literal all \
16+
--formatters ruff-format \
17+
--field-constraints \
18+
--disable-timestamp \
19+
--keep-model-order \
20+
--custom-file-header-path LICENSE \
21+
--input-file-type jsonschema \
22+
--output-model-type pydantic_v2.BaseModel
23+
24+
virtualenv:
25+
@echo "-> Bootstrap the virtualenv with PYTHON_EXE=${PYTHON_EXE}"
26+
${PYTHON_EXE} -m venv ${VENV_LOCATION}
27+
28+
conf: virtualenv
29+
@echo "-> Install dependencies"
30+
@${ACTIVATE} pip install -r etc/scripts/requirements.txt
31+
32+
formatcode:
33+
@echo "-> Run Ruff format"
34+
@${ACTIVATE} ruff check --select I --fix
35+
@${ACTIVATE} ruff format
36+
@echo "-> Run Ruff linter"
37+
@${ACTIVATE} ruff check --fix
38+
39+
formatjson:
40+
@echo "-> Format JSON files"
41+
@${ACTIVATE} python etc/scripts/format_json.py schemas/
42+
@${ACTIVATE} python etc/scripts/format_json.py types/
43+
@${ACTIVATE} python etc/scripts/format_json.py tests/
44+
45+
format: formatcode formatjson
46+
@echo "-> Format all files"
47+
48+
checkjson:
49+
@echo "-> Validate JSON schemas"
50+
@${ACTIVATE} check-jsonschema --check-metaschema --verbose schemas/*.json
51+
@echo "-> Validate JSON data files against the schemas"
52+
@${ACTIVATE} check-jsonschema --schemafile schemas/purl-types-index.schema.json --verbose purl-types-index.json
53+
@${ACTIVATE} check-jsonschema --schemafile schemas/purl-type-definition.schema.json --verbose types/*-definition.json
54+
@${ACTIVATE} check-jsonschema --schemafile schemas/purl-test.schema.json --verbose tests/*/*-test.json
55+
56+
checkcode:
57+
@echo "-> Run Ruff linter validation (pycodestyle, bandit, isort, and more)"
58+
@${ACTIVATE} ruff --config etc/scripts/pyproject.toml check
59+
@echo "-> Run Ruff format validation"
60+
@${ACTIVATE} ruff --config etc/scripts/pyproject.toml format --check
61+
62+
check: checkjson checkcode
63+
@echo "-> Run all checks"
64+
65+
clean:
66+
@echo "-> Clean the Python env"
67+
rm -rf .venv/
68+
find . -type f -name '*.py[co]' -delete
69+
70+
gencode:
71+
@echo "-> Generate Python code from schemas"
72+
@${ACTIVATE} ${CODEGEN} \
73+
--input schemas/purl-types-index.schema.json \
74+
--output etc/scripts/purl_types_index.py
75+
@${ACTIVATE} ${CODEGEN} \
76+
--input schemas/purl-type-definition.schema.json \
77+
--output etc/scripts/purl_type_definition.py
78+
@${ACTIVATE} ${CODEGEN} \
79+
--input schemas/purl-test.schema.json \
80+
--output etc/scripts/purl_test.py
81+
@echo "-> Run Black format for generated code"
82+
@${ACTIVATE} black -l 100 --preview --enable-unstable-feature string_processing etc/scripts/*.py
83+
84+
gendocs:
85+
@${ACTIVATE} python etc/scripts/generate_index_and_docs.py
86+
87+
88+
.PHONY: virtualenv conf formatcode formatjson format checkcode checkjson check clean gencode gendocs

PURL-SPECIFICATION.rst

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -116,9 +116,10 @@ A ``purl`` string is an ASCII URL string composed of seven components.
116116

117117
Except as expressly stated otherwise in this section, each component:
118118

119-
- MAY be composed of any of the characters defined in the "Permitted
120-
characters" section
121-
- MUST be encoded as defined in the "Character encoding" section
119+
- MAY be composed of any of the characters defined in the "`Permitted characters`_" section
120+
- MUST be encoded as defined in the "`Character encoding`_" section
121+
122+
The "lowercase" rules are defined in the "`Case folding`_" section.
122123

123124
The rules for each component are:
124125

@@ -134,7 +135,7 @@ The rules for each component are:
134135
- **type**:
135136

136137
- The package ``type`` MUST be composed only of ASCII letters and numbers,
137-
period '.', plus '+', and dash '-'.
138+
period '.', and dash '-'.
138139
- The ``type`` MUST start with an ASCII letter.
139140
- The ``type`` MUST NOT be percent-encoded.
140141
- The ``type`` is case insensitive. The canonical form is lowercase.
@@ -168,7 +169,7 @@ The rules for each component are:
168169
stripped in the canonical form. They are not part of the ``name``.
169170
- A ``name`` MUST be a percent-encoded string.
170171
- When percent-decoded, a ``name`` MAY contain any Unicode character unless
171-
prohibited by the package's ``type`` definition in `<PURL-TYPES.rst>`_.
172+
the package's ``type`` definition provides otherwise.
172173

173174

174175
- **version**:
@@ -205,7 +206,7 @@ The rules for each component are:
205206
- A ``key`` MUST NOT be percent-encoded.
206207
- Each ``key`` MUST be unique among all the keys of the ``qualifiers``
207208
component.
208-
- A ``value`` MAY be composed of any character and all characters MUST be
209+
- A ``value`` MAY contain any Unicode character and all characters MUST be
209210
encoded as described in the "Character encoding" section.
210211

211212

@@ -219,9 +220,11 @@ The rules for each component are:
219220
- Each ``subpath`` segment MUST be a percent-encoded string
220221
- When percent-decoded, a segment:
221222

222-
- MUST NOT contain a '/'
223-
- MUST NOT be any of '..' or '.'
223+
- MUST NOT contain any slash '/' characters
224224
- MUST NOT be empty
225+
- MUST NOT be any of '..' or '.'
226+
- MAY contain any Unicode character other than '/' unless the package's
227+
``type`` definition provides otherwise.
225228

226229
- The ``subpath`` MUST be interpreted as relative to the root of the package
227230

@@ -234,7 +237,6 @@ A canonical ``purl`` is composed of these permitted ASCII characters:
234237
- the Alphanumeric Characters: ``A to Z``, ``a to z``, ``0 to 9``,
235238
- the Punctuation Characters: ``.-_~`` (period '.',
236239
dash '-', underscore '_' and tilde '~'),
237-
- the Plus Character: ``+`` (plus '+'),
238240
- the Percent Character: ``%`` (percent sign '%'), and
239241
- the Separator Characters ``:/@?=&#`` (colon ':', slash '/', at sign '@',
240242
question mark '?', equal sign '=', ampersand '&' and pound sign '#').
@@ -286,6 +288,16 @@ Character encoding
286288
- With the exception of the percent-encoding mechanism, the rules regarding
287289
percent-encoding are defined by this specification alone.
288290

291+
Case folding
292+
~~~~~~~~~~~~
293+
294+
References to "lowercase" in this specification refer to the **culture-invariant**
295+
full case mapping defined in
296+
`Section 3.13.2 of the Unicode Standard <https://www.unicode.org/versions/Unicode16.0.0/core-spec/chapter-3/#G34078>`_.
297+
298+
When applied to the ASCII character set, this operation converts uppercase
299+
Latin letters (``A to Z``) to their corresponding lowercase forms (``a to z``).
300+
All other ASCII characters remain unchanged.
289301

290302
How to build ``purl`` string from its components
291303
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -340,7 +352,7 @@ To build a ``purl`` string from its components:
340352

341353
- Discard any pair where the ``value`` is empty.
342354
- UTF-8-encode each ``value`` if needed in your programming language
343-
- If the ``key`` is ``checksums`` and this is a list of ``checksums`` join this
355+
- If the ``key`` is ``checksum`` and this is a list of checksums join this
344356
list with a ',' to create this qualifier ``value``
345357
- Create a string by joining the lowercased ``key``, the equal '=' sign and
346358
the percent-encoded ``value`` to create a qualifier
@@ -396,8 +408,8 @@ To parse a ``purl`` string in its components:
396408
- The ``value`` is the percent-decoded right side
397409
- UTF-8-decode the ``value`` if needed in your programming language
398410
- Discard any key/value pairs where the value is empty
399-
- If the ``key`` is ``checksums``, split the ``value`` on ',' to create
400-
a list of ``checksums``
411+
- If the ``key`` is ``checksum``, split the ``value`` on ',' to create
412+
a list of checksums
401413

402414
- This list of key/value is the ``qualifiers`` object
403415

@@ -463,6 +475,13 @@ download URL, VCS URL or checksums in an API, database or web form.
463475
With this warning, the known ``key`` and ``value`` defined here are valid for use in
464476
all package types:
465477

478+
- ``vers`` allows the specification of a version range.
479+
The value MUST adhere to the `Version Range Specification <VERSION-RANGE-SPEC.rst>`_.
480+
This qualifier is mutually exclusive with the ``version`` component.
481+
For example::
482+
483+
pkg:pypi/django?vers=vers:pypi%2F%3E%3D1.11.0%7C%21%3D1.11.1%7C%3C2.0.0
484+
466485
- ``repository_url`` is an extra URL for an alternative, non-default package
467486
repository or registry. When a package does not come from the default public
468487
package repository for its ``type`` a ``purl`` may be qualified with this extra

0 commit comments

Comments
 (0)