Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: wellknown qualifiers #158

Merged
merged 2 commits into from
Nov 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions HISTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,18 @@

## unreleased

* Added
* Constant `PackageUrl::QUALIFIER_REPOSITORY_URL` ([#54] via [#158])
* Constant `PackageUrl::QUALIFIER_DOWNLOAD_URL` ([#54] via [#158])
* Constant `PackageUrl::QUALIFIER_VCS_URL` ([#54] via [#158])
* Constant `PackageUrl::QUALIFIER_FILE_NAME` ([#54] via [#158])
* Constant `PackageUrl::QUALIFIER_CHECKSUM` ([#54] via [#158])
* Deprecated
* Constant `PackageUrl::CHECKSUM_QUALIFIER` -> use `PackageUrl::QUALIFIER_CHECKSUM` instead ([#54] via [#158])

[#54]: https://github.com/package-url/packageurl-php/issues/54
[#158]: https://github.com/package-url/packageurl-php/pull/158

## 1.0.6 - 2023-03-18

Maintenance release.
Expand Down
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ composer require package-url/packageurl-php

## Usage

see also [the examples](https://github.com/package-url/packageurl-php/tree/main/examples).

```php
<?php

Expand All @@ -27,7 +29,9 @@ use PackageUrl\PackageUrl;
$purl = (new PackageUrl('composer', 'console'))
->setNamespace('symfony')
->setVersion('6.3.8')
->setQualifiers(['vcs_url'=>'git+https://github.com/symfony/console.git@v6.3.8']);
->setQualifiers([
PackageUrl::QUALIFIER_VCS_URL => 'git+https://github.com/symfony/console.git@v6.3.8',
]);

$purlString = $purl->toString();

Expand Down
4 changes: 3 additions & 1 deletion examples/usage.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@
$purl = (new PackageUrl('composer', 'console'))
->setNamespace('symfony')
->setVersion('6.3.8')
->setQualifiers(['vcs_url' => 'git+https://github.com/symfony/console.git@v6.3.8']);
->setQualifiers([
PackageUrl::QUALIFIER_VCS_URL => 'git+https://github.com/symfony/console.git@v6.3.8',
]);

$purlString = $purl->toString();

Expand Down
53 changes: 50 additions & 3 deletions src/PackageUrl.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,54 @@ class PackageUrl
{
public const SCHEME = 'pkg';

public const CHECKSUM_QUALIFIER = 'checksum';
// region known qualifiers
/*
* see https://github.com/package-url/purl-spec/blob/master/PURL-SPECIFICATION.rst#known-qualifiers-keyvalue-pairs
*
* Note: Do not abuse qualifiers: it can be tempting to use many qualifier keys but their usage should be limited to the bare minimum for proper package identification to ensure that a purl stays compact and readable in most cases.
*
* 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.
*
* With this warning, the known key and value defined here are valid for use in all package types:
*/

/**
* is an extra URL for an alternative, non-default package 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 {@link https://github.com/package-url/purl-spec/blob/master/PURL-TYPES.rst "Known purl types" section}.
*/
public const QUALIFIER_REPOSITORY_URL = 'repository_url';

/**
* is an extra URL for a direct package web download URL to optionally qualify a purl.
*/
public const QUALIFIER_DOWNLOAD_URL = 'download_url';

/**
* is an extra URL for a package version control system URL to optionally qualify a purl.
* The syntax for this URL should be as defined in Python pip or the SPDX specification.
* See {@link https://github.com/spdx/spdx-spec/blob/cfa1b9d08903/chapters/3-package-information.md#37-package-download-location}.
*/
public const QUALIFIER_VCS_URL = 'vcs_url';

/**
* is an extra file name of a package archive.
*/
public const QUALIFIER_FILE_NAME = 'file_name';

/**
* is a qualifier for one or more checksums stored as a comma-separated list.
* Each item in the value is in form of lowercase_algorithm:hex_encoded_lowercase_value.
*/
public const QUALIFIER_CHECKSUM = 'checksum';

/**
* @see QUALIFIER_CHECKSUM
* @deprecated use {@see QUALIFIER_CHECKSUM} instead
*/
public const CHECKSUM_QUALIFIER = self::QUALIFIER_CHECKSUM;

// endregion known qualifiers

/**
* @psalm-var TType
Expand Down Expand Up @@ -189,7 +236,7 @@ public function getQualifiers(): ?array
*/
public function setQualifiers(?array $qualifiers): self
{
if ($qualifiers && \array_key_exists(self::CHECKSUM_QUALIFIER, $qualifiers)) {
if ($qualifiers && \array_key_exists(self::QUALIFIER_CHECKSUM, $qualifiers)) {
throw new \DomainException('Checksums must not be part of the qualifiers. Use setChecksums().');
}
$this->qualifiers = $qualifiers;
Expand Down Expand Up @@ -271,7 +318,7 @@ public function toString(PackageUrlBuilder $builder = null): string

$qualifiers = $this->qualifiers ?? [];
if ($this->checksums) {
$qualifiers[self::CHECKSUM_QUALIFIER] = $this->checksums;
$qualifiers[self::QUALIFIER_CHECKSUM] = $this->checksums;
}

return $builder->build(
Expand Down
6 changes: 3 additions & 3 deletions src/PackageUrlBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -170,8 +170,8 @@ public function normalizeQualifiers(?array $data): ?string

$data = array_change_key_case($data, \CASE_LOWER);

$checksum = $this->normalizeChecksum($data[PackageUrl::CHECKSUM_QUALIFIER] ?? null);
unset($data[PackageUrl::CHECKSUM_QUALIFIER]);
$checksum = $this->normalizeChecksum($data[PackageUrl::QUALIFIER_CHECKSUM] ?? null);
unset($data[PackageUrl::QUALIFIER_CHECKSUM]);

/** @var mixed $value */
foreach ($data as $key => $value) {
Expand All @@ -187,7 +187,7 @@ public function normalizeQualifiers(?array $data): ?string
}

if (null !== $checksum) {
$segments[] = PackageUrl::CHECKSUM_QUALIFIER.'='.$checksum;
$segments[] = PackageUrl::QUALIFIER_CHECKSUM.'='.$checksum;
}

sort($segments, \SORT_STRING);
Expand Down
6 changes: 3 additions & 3 deletions src/PackageUrlParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -237,10 +237,10 @@ public function normalizeQualifiers(?string $data): array
$qualifiers[$key] = $value;
}

$checksums = empty($qualifiers[PackageUrl::CHECKSUM_QUALIFIER])
$checksums = empty($qualifiers[PackageUrl::QUALIFIER_CHECKSUM])
? null
: explode(',', $qualifiers[PackageUrl::CHECKSUM_QUALIFIER]);
unset($qualifiers[PackageUrl::CHECKSUM_QUALIFIER]);
: explode(',', $qualifiers[PackageUrl::QUALIFIER_CHECKSUM]);
unset($qualifiers[PackageUrl::QUALIFIER_CHECKSUM]);

return empty($qualifiers)
? [null, $checksums]
Expand Down