Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master' into colindean/brew-pu…
Browse files Browse the repository at this point in the history
…rl__merge
  • Loading branch information
colindean committed Dec 17, 2024
2 parents 584a4e4 + 1951d21 commit eb26960
Show file tree
Hide file tree
Showing 5 changed files with 143 additions and 62 deletions.
30 changes: 14 additions & 16 deletions PURL-SPECIFICATION.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@ packaging conventions, tools, APIs and databases.
Such a package URL is useful to reliably reference the same software package
using a simple and expressive syntax and conventions based on familiar URLs.

See https://github.com/package-url/purl-spec for the Package URL specification
and `<PURL-SPECIFICATION.rst>`_ for known type definitions.
See <PURL-TYPES.rst>_ for known type definitions.

Check also this short ``purl`` presentation (with video) at FOSDEM 2018
https://fosdem.org/2018/schedule/event/purl/ for an overview.
Expand Down Expand Up @@ -105,7 +104,7 @@ A ``purl`` is a URL
- Version control system (VCS) URLs such ``git://``, ``svn://``, ``hg://`` or as
defined in Python pip or SPDX download locations are NOT valid ``purl`` types.
They are valid URL or URI schemes but they are not ``purl``.
They are a closely related, compact and uniform way to reference vcs URLs.
They are a closely related, compact and uniform way to reference VCS URLs.
They may be used as references in separate attributes outside of a ``purl`` or
in a ``purl`` qualifier.

Expand Down Expand Up @@ -151,7 +150,7 @@ The rules for each component are:
- The package ``type`` is composed only of ASCII letters and numbers, '.', '+'
and '-' (period, plus, and dash)
- The ``type`` cannot start with a number
- The ``type`` cannot contains spaces
- The ``type`` cannot contain spaces
- The ``type`` must NOT be percent-encoded
- The ``type`` is case insensitive. The canonical form is lowercase

Expand Down Expand Up @@ -187,7 +186,7 @@ The rules for each component are:
- A ``version`` must be a percent-encoded string

- A ``version`` is a plain and opaque string. Some package ``types`` use versioning
conventions such as semver for NPMs or nevra conventions for RPMS. A ``type``
conventions such as SemVer for NPMs or NEVRA conventions for RPMS. A ``type``
may define a procedure to compare and sort versions, but there is no
reliable and uniform way to do such comparison consistently.

Expand All @@ -210,7 +209,7 @@ The rules for each component are:
- A ``key`` cannot start with a number
- A ``key`` must NOT be percent-encoded
- A ``key`` is case insensitive. The canonical form is lowercase
- A ``key`` cannot contains spaces
- A ``key`` cannot contain spaces
- A ``value`` must be a percent-encoded string
- The '=' separator is neither part of the ``key`` nor of the ``value``

Expand Down Expand Up @@ -282,7 +281,7 @@ To build a ``purl`` string from its components:

- Start a ``purl`` string with the "pkg:" ``scheme`` as a lowercase ASCII string

- Append the ``type`` string to the ``purl`` as a lowercase ASCII string
- Append the ``type`` string to the ``purl`` as a lowercase ASCII string

- Append '/' to the ``purl``

Expand Down Expand Up @@ -319,15 +318,15 @@ To build a ``purl`` string from its components:
- Append '?' to the ``purl``
- Build a list from all key/value pair:

- discard any pair where the ``value`` is empty.
- Discard any pair where the ``value`` is empty.
- UTF-8-encode each ``value`` if needed in your programming language
- If the ``key`` is ``checksums`` and this is a list of ``checksums`` join this
list with a ',' to create this qualifier ``value``
- create a string by joining the lowercased ``key``, the equal '=' sign and
- Create a string by joining the lowercased ``key``, the equal '=' sign and
the percent-encoded ``value`` to create a qualifier

- sort this list of qualifier strings lexicographically
- join this list of qualifier strings with a '&' ampersand
- Sort this list of qualifier strings lexicographically
- Join this list of qualifier strings with a '&' ampersand
- Append this string to the ``purl``

- If the ``subpath`` is not empty and not composed only of empty, '.' and '..'
Expand Down Expand Up @@ -360,7 +359,7 @@ To parse a ``purl`` string in its components:
- Strip the right side from leading and trailing '/'
- Split this on '/'
- Discard any empty string segment from that split
- Discard any '.' or '..' segment from that split
- Discard any '.' or '..' segment from that split
- Percent-decode each segment
- UTF-8-decode each segment if needed in your programming language
- Join segments back with a '/'
Expand Down Expand Up @@ -412,8 +411,7 @@ To parse a ``purl`` string in its components:

- Discard any empty segment from that split
- Percent-decode each segment
- UTF-8-decode the each segment if needed in your programming
language
- UTF-8-decode each segment if needed in your programming language
- Apply type-specific normalization to each segment if needed
- Join segments back with a '/'
- This is the ``namespace``
Expand All @@ -434,14 +432,14 @@ identification to ensure that a ``purl`` stays compact and readable in most case

Additional, separate external attributes stored outside of a ``purl`` are the
preferred mechanism to convey extra long and optional information such as a
download URL, vcs URL or checksums in an API, database or web form.
download URL, VCS URL or checksums in an API, database or web form.


With this warning, the known ``key`` and ``value`` defined here are valid for use in
all package types:

- ``repository_url`` is an extra URL for an alternative, non-default package
repository or registry. When a package does not come from the default public
repository or registry. When a package does not come from the default public
package repository for its ``type`` a ``purl`` may be qualified with this extra
URL. The default repository or registry of a ``type`` is documented in the
"Known ``purl`` types" section.
Expand Down
17 changes: 12 additions & 5 deletions PURL-TYPES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -198,17 +198,17 @@ cpan
----
``cpan`` for CPAN Perl packages:

- The default respository is ``https://www.cpan.org/``.
- The default repository is ``https://www.cpan.org/``.
- The ``namespace``:
- To refer to a CPAN distribution name, the ``namespace`` MUST be present. In this case, the namespace is the CPAN id of the author/publisher. It MUST be written uppercase, followed by the distribution name in the ``name`` component. A distribution name may NEVER contain the string ``::``.
- To refer to a CPAN distribution name, the ``namespace`` MUST be present. In this case, the namespace is the CPAN id of the author/publisher. It MUST be written uppercase, followed by the distribution name in the ``name`` component. A distribution name MUST NOT contain the string ``::``.
- To refer to a CPAN module, the ``namespace`` MUST be absent. The module name MAY contain zero or more ``::`` strings, and the module name MUST NOT contain a ``-``

- The ``name`` is the module or distribution name and is case sensitive.
- The ``version`` is the module or distribution version.
- Optional qualifiers may include:

- ``repository_url``: CPAN/MetaCPAN/BackPAN/DarkPAN repository base URL (default is ``https://www.cpan.org``)
- ``download_url``: URL of package or distibution
- ``download_url``: URL of package or distribution
- ``vcs_url``: extra URL for a package version control system
- ``ext``: file extension (default is ``tar.gz``)

Expand Down Expand Up @@ -278,7 +278,7 @@ docker

gem
---
``gem`` for Rubygems:
``gem`` for RubyGems:

- The default repository is ``https://rubygems.org``.
- The ``platform`` qualifiers key is used to specify an alternative platform.
Expand Down Expand Up @@ -400,7 +400,7 @@ luarocks
The full version number is required to uniquely identify a version.
- Qualifier ``repository_url``: The LuaRocks rocks server to be used;
useful in case a private server is used (optional).
If ommitted, ``https://luarocks.org`` as default server is assumed.
If omitted, ``https://luarocks.org`` as default server is assumed.

Examples::

Expand Down Expand Up @@ -545,9 +545,16 @@ pypi
- PyPI treats ``-`` and ``_`` as the same character and is not case sensitive.
Therefore a PyPI package ``name`` must be lowercased and underscore ``_``
replaced with a dash ``-``.
- The ``file_name`` qualifier selects a particular distribution file
(case-sensitive). For naming convention, see the Python Packaging User Guide on
`source distributions <https://packaging.python.org/en/latest/specifications/source-distribution-format/#source-distribution-file-name>`_,
`binary distributions <https://packaging.python.org/en/latest/specifications/binary-distribution-format/#file-name-convention>`_,
and `platform compatibility tags <https://packaging.python.org/en/latest/specifications/platform-compatibility-tags/>`_.
- Examples::

pkg:pypi/[email protected]
pkg:pypi/[email protected]?filename=Django-1.11.1.tar.gz
pkg:pypi/[email protected]?filename=Django-1.11.1-py2.py3-none-any.whl
pkg:pypi/[email protected]

rpm
Expand Down
46 changes: 25 additions & 21 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ A `purl` or package URL is an attempt to standardize existing approaches to
reliably identify and locate software packages.

A `purl` is a URL string used to identify and locate a software package in a
mostly universal and uniform way across programing languages, package managers,
mostly universal and uniform way across programming languages, package managers,
packaging conventions, tools, APIs and databases.

Such a package URL is useful to reliably reference the same software package
Expand Down Expand Up @@ -124,7 +124,7 @@ Some `purl` examples
pkg:golang/google.golang.org/genproto#googleapis/api/annotations

pkg:maven/org.apache.xmlgraphics/[email protected]?packaging=sources
pkg:maven/org.apache.xmlgraphics/[email protected]?repository_url=repo.spring.io%2Frelease
pkg:maven/org.apache.xmlgraphics/[email protected]?repository_url=repo.spring.io/release

pkg:npm/%40angular/[email protected]
pkg:npm/[email protected]
Expand Down Expand Up @@ -156,35 +156,39 @@ type definitions:
Known implementations
~~~~~~~~~~~~~~~~~~~~~

- in Golang: https://github.com/package-url/packageurl-go
- for .NET: https://github.com/package-url/packageurl-dotnet
- for the JVM: https://github.com/package-url/packageurl-java,
- .NET: https://github.com/package-url/packageurl-dotnet
- Elixir: https://github.com/maennchen/purl
- Go: https://github.com/package-url/packageurl-go
- Java: https://github.com/package-url/packageurl-java,
https://github.com/sonatype/package-url-java
- in Python: https://github.com/package-url/packageurl-python
- in Rust: https://github.com/package-url/packageurl.rs
- in JS: https://github.com/package-url/packageurl-js
- in Elixir: https://github.com/jshmrtn/purl
- in Perl: https://github.com/giterlizzi/perl-URI-PackageURL
- JavaScript: https://github.com/package-url/packageurl-js
- Perl: https://github.com/giterlizzi/perl-URI-PackageURL
- PHP: https://github.com/package-url/packageurl-php
- Python: https://github.com/package-url/packageurl-python
- Ruby: https://github.com/package-url/packageurl-ruby
- Rust: https://github.com/package-url/packageurl.rs
- Swift: https://github.com/package-url/packageurl-swift


Users, adopters and links
~~~~~~~~~~~~~~~~~~~~~~~~~
Users, adopters and links (alphabetical order)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

- `CycloneDX <https://github.com/CycloneDX>`_: A lightweight software
bill-of-material (SBOM) specification
- `GitHub Dependency Submission API <https://docs.github.com/en/rest/dependency-graph/dependency-submission>`_: allows third-party tools
to submit dependency data to GitHub for inclusion in a repository's dependency graph.
- `Scancode Toolkit <https://github.com/nexB/scancode-toolkit>`_: Reports
`purl` from parsed package manifests using https://github.com/package-url/packageurl-python
- `OWASP Dependency-Track <https://www.owasp.org/index.php/OWASP_Dependency_Track_Project>`_:
- `OWASP Dependency-Track <https://www.owasp.org/index.php/OWASP_Dependency_Track_Project>`_:
Open source component analysis platform
- `CycloneDX <https://github.com/CycloneDX>`_: A lightweight software
bill-of-material (SBOM) specification
- `SPDX <https://spdx.dev>`_: A data exchange standard for human-readable and
machine-processable software bill-of-materials (SBOM)
- `OSS Index <https://ossindex.sonatype.org>`_: A free catalog of Open Source
Components and scanning tools to help developers identify vulnerable components
- `Sonatype Nexus Lifecycle <https://www.sonatype.com/product-nexus-lifecycle>`_:
Enterprise grade Open Source component management
- `OSV Schema <https://ossf.github.io/osv-schema/>`_ and `OSV.dev <https://osv.dev>`_:
Open Source Vulnerability Schema and distributed vulnerability database
- `Scancode Toolkit <https://github.com/nexB/scancode-toolkit>`_: Reports
`purl` from parsed package manifests using https://github.com/package-url/packageurl-python
- `Sonatype Nexus Lifecycle <https://www.sonatype.com/product-nexus-lifecycle>`_:
Enterprise grade Open Source component management
- `SPDX <https://spdx.dev>`_: A data exchange standard for human-readable and
machine-processable software bill-of-materials (SBOM)

License
~~~~~~~
Expand Down
40 changes: 20 additions & 20 deletions VERSION-RANGE-SPEC.rst
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,9 @@ conventions in use:
- ``semver`` https://semver.org/ is a popular specification to structure version
strings, but does not provide a way to express version ranges.

- Rubygems strongly suggest using ``semver`` for version but does not enforce it.
- RubyGems strongly suggest using ``semver`` for version but does not enforce it.
As a result some gem use semver while several popular package do not use
strict semver. Rubygems use their own notation for version ranges which
strict semver. RubyGems use their own notation for version ranges which
looks like the ``node-semver`` notation with some subtle differences.
See https://guides.rubygems.org/patterns/#semantic-versioning

Expand Down Expand Up @@ -115,7 +115,7 @@ conventions in use:
version. And also provides a concrete enumeration of the available ranges as
a daily feed.

- The version 5 of the NVD CVE JSON data format at
- The version 5 of the CVE JSON data format at
https://github.com/CVEProject/cve-schema/blob/master/schema/v5.0/CVE_JSON_5.0.schema#L303
defines version ranges with a starting version, a versionType, and an upper
limit for the version range as lessThan or lessThanOrEqual; or an enumeration
Expand All @@ -142,7 +142,7 @@ related topic:
- For instance, ``semver`` is a prominent specification in this domain but this
is just one of the many ways to structure a version string.

- Debian, RPM, PyPI, Rubygems, and Composer have their own subtly different
- Debian, RPM, PyPI, RubyGems, and Composer have their own subtly different
approach on how to determine how two versions are compared as equal, greater
or lesser.

Expand Down Expand Up @@ -260,7 +260,7 @@ Note how the constraints are sorted:
- ``vers:tomee/>=7.1.0|<=7.1.2``
- ``vers:tomee/>=8.0.0-M1|<=8.0.1``

Conversing Rubygems custom syntax for dependency on gem. Note how the
Conversing RubyGems custom syntax for dependency on gem. Note how the
pessimistic version constraint is expanded:

- ``'library', '~> 2.2.0', '!= 2.2.1'``
Expand Down Expand Up @@ -603,9 +603,9 @@ These are a few known versioning schemes for some common Package URL
Debian uses these comparators: <<, <=, =, >= and >>.

- **rpm**: RPM distros https://rpm-software-management.github.io/rpm/manual/dependencies.html
The a simplified rmpvercmp version comparison routine is used by archlinux Pacman.
The a simplified rmpvercmp version comparison routine is used by Arch Linux Pacman.

- **gem**: Rubygems https://guides.rubygems.org/patterns/#semantic-versioning
- **gem**: RubyGems https://guides.rubygems.org/patterns/#semantic-versioning
which is similar to ``node-semver`` for its syntax, but does not use semver
versions.

Expand Down Expand Up @@ -692,7 +692,7 @@ Why not reuse existing version range notations?

Most existing version range notations are tied to a specific version string
syntax and are therefore not readily applicable to other contexts. For example,
the use of elements such as tilde and caret ranges in Rubygems, npm or Dart
the use of elements such as tilde and caret ranges in RubyGems, npm or Dart
notations implies that a certain structure exists in the version string (semver
or semver- like). The inclusion of these additional comparators is a result of
the history and evolution in a given package ecosystem to address specific needs.
Expand Down Expand Up @@ -752,7 +752,7 @@ most vulnerable ranges yet:
and vulnerable ranges when a version must be excluded and the set of existing
versions is not yet known,

- this make some ranges more verbose such as with the NVD CVE v5 API ranges
- this make some ranges more verbose such as with the CVE v5 API ranges
notation that can include their upper limit and would need two constraints.

Another high level difference between the two specifications are the
Expand All @@ -761,15 +761,15 @@ the Package URL package "type" used in ``vers``. This spec will provide a strict
mapping between the OSV ecosystem and the ``vers`` versioning schemes values.


Why not use the NVD CVE v5 API Ranges?
Why not use the CVE v5 API Ranges?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

See:

- https://github.com/CVEProject/cve-schema/blob/master/schema/v5.0/CVE_JSON_5.0_schema.json#L303
- https://github.com/CVEProject/cve-schema/blob/master/schema/v5.0/CVE_JSON_5.0_schema.json#L123

The version 5 of the NVD CVE JSON data format defines version ranges with a
The version 5 of the CVE JSON data format defines version ranges with a
starting version, a versionType, and an upper limit for the version range as
lessThan or lessThanOrEqual or as an enumeration of versions. The versionType
and the package collectionURL possible values are only indicative and left out
Expand All @@ -778,16 +778,16 @@ of this specification and both seem strictly equivalent to the Package URL

The semantics and expressiveness of each range are similar and ``vers`` provides
a compact notation rather than a more verbose JSON notation. ``vers`` supports
strictly the conversion of any NVD v5 range to its notation and further
strictly the conversion of any CVE v5 range to its notation and further
provides a concrete list of well known versioning schemes. ``vers`` design was
informed by the NVD CVE v5 API schema spec and its authors.
informed by the CVE v5 API schema spec and its authors.

When NVD v5 becomes active, this spec will provide a strict mapping between the
NVD versionType and the ``vers`` versioning schemes values. Furthermore, this
When CVE v5 becomes active, this spec will provide a strict mapping between the
CVE ``versionType`` and the ``vers`` versioning schemes values. Furthermore, this
spec and the Package URL "types" should be updated accordingly to provide
a mapping with the upcoming NVD collectionURL that will be effectively used.
a mapping with the upcoming CVE ``collectionURL`` that will be effectively used.

There is one issue with NVD v5: it introduces a new trailing "*" notation that
There is one issue with CVE v5: it introduces a new trailing "*" notation that
does not exists in most version ranges notations and may not be computable
easily in many cases. The description of the "lessThan" property is:

Expand All @@ -806,7 +806,7 @@ The conversion to ``vers`` range should be:
computed for ``semver`` versions as ``>=1.0|<2`` but is not accurate unless
as versioning schemes have different rules. For instance, pre-release may be
treated in some case as part of the v1. branch and in some other cases as part
of the v2. branch. It is not clear if with "2.*" the NVD spec means:
of the v2. branch. It is not clear if with "2.*" the CVE v5 spec means:

- ``<2``
- or something that excludes any version string that starts with ``2.``
Expand Down Expand Up @@ -900,14 +900,14 @@ aspects specific to the versions used only in the Python ecosystem.
difficult to express without an "OR" logic.


Why not use Rubygems requirements notation?
Why not use RubyGems requirements notation?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

See:

- https://guides.rubygems.org/patterns/#declaring-dependencies

The Rubygems specification suggests but does not enforce using semver. It uses
The RubyGems specification suggests but does not enforce using semver. It uses
operators similar to the ``node-semver`` spec with the different of the "~>"
aka. pessimistic operator vs. a plain "~" tilde used in node-semver. This
operator implies some semver-like versioning, yet gem version are not strictly
Expand Down
Loading

0 comments on commit eb26960

Please sign in to comment.