purl 1.7.0 → 1.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +10 -0
- data/README.md +24 -0
- data/lib/purl/ecosystems_url.rb +101 -0
- data/lib/purl/version.rb +1 -1
- data/lib/purl.rb +1 -0
- data/purl-types.json +4 -1
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: fd8e9d9c9a3cafa22edc44525dccb49e48a3d845d3449e34af58503fe073f108
|
|
4
|
+
data.tar.gz: f53708d2eef113aa44d3d5518f6258785b475d7fa92c762110693543efd3dadf
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e2c169dbd6baf5749e733fb689eb7ceac90f0f8e6570e79b1bf6a85968bab6cb95da9be8ac97662ea6b5efb5f1f2841250daa8c84bfeb861aac71af1cc05e02d
|
|
7
|
+
data.tar.gz: 3bf9997d1529682639fe3f9d465688cd109178cd0902c57b08e3236f7c6d9657b9b94b8c80127c22153d3f05d5ea4cbb77219c615284ddc2eb775efdd6ea5632
|
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [1.7.1] - 2026-01-14
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- ecosyste.ms API URL generation for packages and versions
|
|
14
|
+
- `ecosystems_registry` method returns the ecosyste.ms registry name for a PURL type
|
|
15
|
+
- `ecosystems_api_url` method generates the full API URL (version URL if version present, otherwise package URL)
|
|
16
|
+
- `ecosystems_package_api_url` method generates package API URL
|
|
17
|
+
- `ecosystems_version_api_url` method generates version API URL
|
|
18
|
+
- New `ecosystems_registry` field in purl-types.json for types where the registry name differs from the registry URL host
|
|
19
|
+
|
|
10
20
|
## [1.7.0] - 2026-01-02
|
|
11
21
|
|
|
12
22
|
### Added
|
data/README.md
CHANGED
|
@@ -466,6 +466,30 @@ puts Purl.download_supported_types
|
|
|
466
466
|
# "npm", "nuget", "pub", "swift"]
|
|
467
467
|
```
|
|
468
468
|
|
|
469
|
+
### ecosyste.ms API URLs
|
|
470
|
+
|
|
471
|
+
Generate API URLs for the packages.ecosyste.ms service:
|
|
472
|
+
|
|
473
|
+
```ruby
|
|
474
|
+
# Get the ecosyste.ms registry name for a package type
|
|
475
|
+
purl = Purl.parse("pkg:gem/rake@13.3.1")
|
|
476
|
+
purl.ecosystems_registry # => "rubygems.org"
|
|
477
|
+
|
|
478
|
+
# Generate API URLs
|
|
479
|
+
purl.ecosystems_api_url # => "https://packages.ecosyste.ms/api/v1/registries/rubygems.org/packages/rake/versions/13.3.1"
|
|
480
|
+
purl.ecosystems_package_api_url # => "https://packages.ecosyste.ms/api/v1/registries/rubygems.org/packages/rake"
|
|
481
|
+
purl.ecosystems_version_api_url # => "https://packages.ecosyste.ms/api/v1/registries/rubygems.org/packages/rake/versions/13.3.1"
|
|
482
|
+
|
|
483
|
+
# Works with namespaced packages
|
|
484
|
+
purl = Purl.parse("pkg:npm/@babel/core@7.20.0")
|
|
485
|
+
purl.ecosystems_registry # => "npmjs.org"
|
|
486
|
+
purl.ecosystems_api_url # => "https://packages.ecosyste.ms/api/v1/registries/npmjs.org/packages/%40babel%2Fcore/versions/7.20.0"
|
|
487
|
+
|
|
488
|
+
# Without version, returns package URL
|
|
489
|
+
purl = Purl.parse("pkg:cargo/serde")
|
|
490
|
+
purl.ecosystems_api_url # => "https://packages.ecosyste.ms/api/v1/registries/crates.io/packages/serde"
|
|
491
|
+
```
|
|
492
|
+
|
|
469
493
|
### Reverse Parsing: Registry URLs to PURLs
|
|
470
494
|
|
|
471
495
|
```ruby
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Purl
|
|
4
|
+
class EcosystemsURL
|
|
5
|
+
API_BASE = "https://packages.ecosyste.ms/api/v1"
|
|
6
|
+
|
|
7
|
+
def self.registry_name(purl)
|
|
8
|
+
new(purl).registry_name
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def self.api_url(purl)
|
|
12
|
+
new(purl).api_url
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def self.package_api_url(purl)
|
|
16
|
+
new(purl).package_api_url
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def self.version_api_url(purl)
|
|
20
|
+
new(purl).version_api_url
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def initialize(purl)
|
|
24
|
+
@purl = purl.is_a?(PackageURL) ? purl : PackageURL.parse(purl.to_s)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def registry_name
|
|
28
|
+
# Check for explicit ecosystems_registry in config first
|
|
29
|
+
type_config = Purl.type_config(@purl.type)
|
|
30
|
+
return type_config["ecosystems_registry"] if type_config&.dig("ecosystems_registry")
|
|
31
|
+
|
|
32
|
+
# Fall back to extracting host from registry_url
|
|
33
|
+
return nil unless @purl.supports_registry_url?
|
|
34
|
+
|
|
35
|
+
host = URI.parse(@purl.registry_url).host
|
|
36
|
+
host.sub(/^www\./, "")
|
|
37
|
+
rescue URI::InvalidURIError, RegistryError
|
|
38
|
+
nil
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def api_url
|
|
42
|
+
@purl.version ? version_api_url : package_api_url
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def package_api_url
|
|
46
|
+
registry = registry_name
|
|
47
|
+
return nil unless registry
|
|
48
|
+
|
|
49
|
+
name = package_name_for_api
|
|
50
|
+
"#{API_BASE}/registries/#{registry}/packages/#{encode_path_segment(name)}"
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def version_api_url
|
|
54
|
+
registry = registry_name
|
|
55
|
+
return nil unless registry
|
|
56
|
+
return nil unless @purl.version
|
|
57
|
+
|
|
58
|
+
name = package_name_for_api
|
|
59
|
+
"#{API_BASE}/registries/#{registry}/packages/#{encode_path_segment(name)}/versions/#{encode_path_segment(@purl.version)}"
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
private
|
|
63
|
+
|
|
64
|
+
def package_name_for_api
|
|
65
|
+
# Some ecosystems use namespace/name format
|
|
66
|
+
if @purl.namespace && namespaced_package_types.include?(@purl.type.downcase)
|
|
67
|
+
"#{@purl.namespace}/#{@purl.name}"
|
|
68
|
+
else
|
|
69
|
+
@purl.name
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def namespaced_package_types
|
|
74
|
+
%w[npm composer maven golang swift elm clojars]
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def encode_path_segment(str)
|
|
78
|
+
URI.encode_www_form_component(str)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
attr_reader :purl
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
class PackageURL
|
|
85
|
+
def ecosystems_registry
|
|
86
|
+
EcosystemsURL.registry_name(self)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def ecosystems_api_url
|
|
90
|
+
EcosystemsURL.api_url(self)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def ecosystems_package_api_url
|
|
94
|
+
EcosystemsURL.package_api_url(self)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def ecosystems_version_api_url
|
|
98
|
+
EcosystemsURL.version_api_url(self)
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
data/lib/purl/version.rb
CHANGED
data/lib/purl.rb
CHANGED
|
@@ -5,6 +5,7 @@ require_relative "purl/errors"
|
|
|
5
5
|
require_relative "purl/package_url"
|
|
6
6
|
require_relative "purl/registry_url"
|
|
7
7
|
require_relative "purl/download_url"
|
|
8
|
+
require_relative "purl/ecosystems_url"
|
|
8
9
|
require_relative "purl/lookup"
|
|
9
10
|
require_relative "purl/lookup_formatter"
|
|
10
11
|
require_relative "purl/advisory"
|
data/purl-types.json
CHANGED
|
@@ -222,6 +222,7 @@
|
|
|
222
222
|
"golang": {
|
|
223
223
|
"description": "Go packages",
|
|
224
224
|
"default_registry": "https://pkg.go.dev",
|
|
225
|
+
"ecosystems_registry": "proxy.golang.org",
|
|
225
226
|
"examples": [
|
|
226
227
|
"pkg:golang/github.com/gorilla/context@234fd47e07d1004f0aed9c",
|
|
227
228
|
"pkg:golang/google.golang.org/genproto#googleapis/api/annotations",
|
|
@@ -319,7 +320,8 @@
|
|
|
319
320
|
"maven": {
|
|
320
321
|
"description": "PURL type for Maven JARs and related artifacts.",
|
|
321
322
|
"default_registry": "https://repo.maven.apache.org/maven2",
|
|
322
|
-
"
|
|
323
|
+
"ecosystems_registry": "repo1.maven.org",
|
|
324
|
+
"namespace_requirement": "required",
|
|
323
325
|
"examples": [
|
|
324
326
|
"pkg:maven/org.apache.commons/commons-lang3@3.12.0",
|
|
325
327
|
"pkg:maven/junit/junit@4.13.2",
|
|
@@ -349,6 +351,7 @@
|
|
|
349
351
|
"npm": {
|
|
350
352
|
"description": "PURL type for npm packages.",
|
|
351
353
|
"default_registry": "https://registry.npmjs.org",
|
|
354
|
+
"ecosystems_registry": "npmjs.org",
|
|
352
355
|
"namespace_requirement": "optional",
|
|
353
356
|
"examples": [
|
|
354
357
|
"pkg:npm/@babel/core@7.20.0",
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: purl
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.7.
|
|
4
|
+
version: 1.7.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Andrew Nesbitt
|
|
@@ -46,6 +46,7 @@ files:
|
|
|
46
46
|
- lib/purl/advisory.rb
|
|
47
47
|
- lib/purl/advisory_formatter.rb
|
|
48
48
|
- lib/purl/download_url.rb
|
|
49
|
+
- lib/purl/ecosystems_url.rb
|
|
49
50
|
- lib/purl/errors.rb
|
|
50
51
|
- lib/purl/lookup.rb
|
|
51
52
|
- lib/purl/lookup_formatter.rb
|