Skip to content

Commit abb6dca

Browse files
committed
Add missing standard types
1 parent ee6dda9 commit abb6dca

File tree

2 files changed

+96
-30
lines changed

2 files changed

+96
-30
lines changed

src/main/java/com/github/packageurl/PackageURL.java

Lines changed: 64 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ public PackageURL(final String type, final String namespace, final String name,
9999
this.type = validateType(type);
100100
this.namespace = validateNamespace(namespace);
101101
this.name = validateName(name);
102-
this.version = validateVersion(version);
102+
this.version = validateVersion(type, version);
103103
this.qualifiers = validateQualifiers(qualifiers);
104104
this.subpath = validatePath(subpath, true);
105105
verifyTypeConstraints(this.type, this.namespace, this.name);
@@ -271,13 +271,25 @@ private String validateNamespace(final String[] values) throws MalformedPackageU
271271

272272
String retVal;
273273
switch (type) {
274+
case StandardTypes.APK:
274275
case StandardTypes.BITBUCKET:
275-
case StandardTypes.DEBIAN:
276+
case StandardTypes.COMPOSER:
277+
case StandardTypes.DEB:
276278
case StandardTypes.GITHUB:
277279
case StandardTypes.GOLANG:
280+
case StandardTypes.HEX:
281+
case StandardTypes.LUAROCKS:
282+
case StandardTypes.QPKG:
278283
case StandardTypes.RPM:
279284
retVal = tempNamespace.toLowerCase();
280285
break;
286+
case StandardTypes.MLFLOW:
287+
case StandardTypes.OCI:
288+
if (tempNamespace != null) {
289+
throw new MalformedPackageURLException("The PackageURL specified contains a namespace which is not allowed for type: " + type);
290+
}
291+
retVal = null;
292+
break;
281293
default:
282294
retVal = tempNamespace;
283295
break;
@@ -291,14 +303,22 @@ private String validateName(final String value) throws MalformedPackageURLExcept
291303
}
292304
String temp;
293305
switch (type) {
306+
case StandardTypes.APK:
294307
case StandardTypes.BITBUCKET:
295-
case StandardTypes.DEBIAN:
308+
case StandardTypes.BITNAMI:
309+
case StandardTypes.COMPOSER:
310+
case StandardTypes.DEB:
296311
case StandardTypes.GITHUB:
297-
case StandardTypes.GOLANG:
312+
case StandardTypes.HEX:
313+
case StandardTypes.LUAROCKS:
314+
case StandardTypes.OCI:
298315
temp = value.toLowerCase();
299316
break;
317+
case StandardTypes.PUB:
318+
temp = value.toLowerCase().replaceAll("[^a-z0-9_]", "_");
319+
break;
300320
case StandardTypes.PYPI:
301-
temp = value.replaceAll("_", "-").toLowerCase();
321+
temp = value.toLowerCase().replace('_', '-');
302322
break;
303323
default:
304324
temp = value;
@@ -307,17 +327,26 @@ private String validateName(final String value) throws MalformedPackageURLExcept
307327
return temp;
308328
}
309329

310-
private String validateVersion(final String value) {
330+
private String validateVersion(String type, final String value) {
311331
if (value == null) {
312332
return null;
313333
}
314-
return value;
334+
335+
switch (type) {
336+
case StandardTypes.HUGGINGFACE:
337+
case StandardTypes.LUAROCKS:
338+
case StandardTypes.OCI:
339+
return value.toLowerCase();
340+
default:
341+
return value;
342+
}
315343
}
316344

317345
private Map<String, String> validateQualifiers(final Map<String, String> values) throws MalformedPackageURLException {
318346
if (values == null) {
319347
return null;
320348
}
349+
321350
for (Map.Entry<String, String> entry : values.entrySet()) {
322351
validateKey(entry.getKey());
323352
final String value = entry.getValue();
@@ -575,7 +604,7 @@ private void parse(final String purl) throws MalformedPackageURLException {
575604
// version is optional - check for existence
576605
index = remainder.lastIndexOf("@");
577606
if (index >= start) {
578-
this.version = validateVersion(percentDecode(remainder.substring(index + 1)));
607+
this.version = validateVersion(type, percentDecode(remainder.substring(index + 1)));
579608
remainder.setLength(index);
580609
}
581610

@@ -727,24 +756,47 @@ public int hashCode() {
727756
*
728757
* @since 1.0.0
729758
*/
730-
public static class StandardTypes {
759+
public static final class StandardTypes {
760+
public static final String ALPM = "alpm";
761+
public static final String APK = "apk";
731762
public static final String BITBUCKET = "bitbucket";
763+
public static final String BITNAMI = "bitnami";
764+
public static final String COCOAPODS = "cocoapods";
732765
public static final String CARGO = "cargo";
733766
public static final String COMPOSER = "composer";
734-
public static final String DEBIAN = "deb";
767+
public static final String CONAN = "conan";
768+
public static final String CONDA = "conda";
769+
public static final String CPAN = "cpan";
770+
public static final String CRAN = "cran";
771+
public static final String DEB = "deb";
735772
public static final String DOCKER = "docker";
736773
public static final String GEM = "gem";
737774
public static final String GENERIC = "generic";
738775
public static final String GITHUB = "github";
739776
public static final String GOLANG = "golang";
777+
public static final String HACKAGE = "hackage";
740778
public static final String HEX = "hex";
779+
public static final String HUGGINGFACE = "huggingface";
780+
public static final String LUAROCKS = "luarocks";
741781
public static final String MAVEN = "maven";
782+
public static final String MLFLOW = "mlflow";
742783
public static final String NPM = "npm";
743784
public static final String NUGET = "nuget";
785+
public static final String QPKG = "qpkg";
786+
public static final String OCI = "oci";
787+
public static final String PUB = "pub";
744788
public static final String PYPI = "pypi";
745789
public static final String RPM = "rpm";
746-
public static final String NIXPKGS = "nixpkgs";
747-
public static final String HACKAGE = "hackage";
790+
public static final String SWID = "swid";
791+
public static final String SWIFT = "swift";
792+
// FIXME: Remove this since it should be named DEB
793+
public static final String DEBIAN = "deb";
794+
// FIXME: Remove this since it should be named NIX and it is not a standard type
795+
public static final String NIXPKGS = "nix";
796+
797+
private StandardTypes() {
798+
799+
}
748800
}
749801

750802
}

src/test/java/com/github/packageurl/PackageURLTest.java

Lines changed: 32 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -268,24 +268,38 @@ public void testConstructorWithDuplicateQualifiers() throws MalformedPackageURLE
268268

269269
@Test
270270
public void testStandardTypes() {
271-
exception = ExpectedException.none();
272-
Assert.assertEquals(PackageURL.StandardTypes.BITBUCKET, "bitbucket");
273-
Assert.assertEquals(PackageURL.StandardTypes.CARGO, "cargo");
274-
Assert.assertEquals(PackageURL.StandardTypes.COMPOSER, "composer");
275-
Assert.assertEquals(PackageURL.StandardTypes.DEBIAN, "deb");
276-
Assert.assertEquals(PackageURL.StandardTypes.DOCKER, "docker");
277-
Assert.assertEquals(PackageURL.StandardTypes.GEM, "gem");
278-
Assert.assertEquals(PackageURL.StandardTypes.GENERIC, "generic");
279-
Assert.assertEquals(PackageURL.StandardTypes.GITHUB, "github");
280-
Assert.assertEquals(PackageURL.StandardTypes.GOLANG, "golang");
281-
Assert.assertEquals(PackageURL.StandardTypes.HEX, "hex");
282-
Assert.assertEquals(PackageURL.StandardTypes.MAVEN, "maven");
283-
Assert.assertEquals(PackageURL.StandardTypes.NPM, "npm");
284-
Assert.assertEquals(PackageURL.StandardTypes.NUGET, "nuget");
285-
Assert.assertEquals(PackageURL.StandardTypes.PYPI, "pypi");
286-
Assert.assertEquals(PackageURL.StandardTypes.RPM, "rpm");
287-
Assert.assertEquals(PackageURL.StandardTypes.NIXPKGS, "nixpkgs");
288-
Assert.assertEquals(PackageURL.StandardTypes.HACKAGE, "hackage");
271+
Assert.assertEquals("alpm", PackageURL.StandardTypes.ALPM);
272+
Assert.assertEquals("apk", PackageURL.StandardTypes.APK);
273+
Assert.assertEquals("bitbucket", PackageURL.StandardTypes.BITBUCKET);
274+
Assert.assertEquals("bitnami", PackageURL.StandardTypes.BITNAMI);
275+
Assert.assertEquals("cocoapods", PackageURL.StandardTypes.COCOAPODS);
276+
Assert.assertEquals("cargo", PackageURL.StandardTypes.CARGO);
277+
Assert.assertEquals("composer", PackageURL.StandardTypes.COMPOSER);
278+
Assert.assertEquals("conan", PackageURL.StandardTypes.CONAN);
279+
Assert.assertEquals("conda", PackageURL.StandardTypes.CONDA);
280+
Assert.assertEquals("cpan", PackageURL.StandardTypes.CPAN);
281+
Assert.assertEquals("cran", PackageURL.StandardTypes.CRAN);
282+
Assert.assertEquals("deb", PackageURL.StandardTypes.DEB);
283+
Assert.assertEquals("docker", PackageURL.StandardTypes.DOCKER);
284+
Assert.assertEquals("gem", PackageURL.StandardTypes.GEM);
285+
Assert.assertEquals("generic", PackageURL.StandardTypes.GENERIC);
286+
Assert.assertEquals("github", PackageURL.StandardTypes.GITHUB);
287+
Assert.assertEquals("golang", PackageURL.StandardTypes.GOLANG);
288+
Assert.assertEquals("hackage", PackageURL.StandardTypes.HACKAGE);
289+
Assert.assertEquals("hex", PackageURL.StandardTypes.HEX);
290+
Assert.assertEquals("huggingface", PackageURL.StandardTypes.HUGGINGFACE);
291+
Assert.assertEquals("luarocks", PackageURL.StandardTypes.LUAROCKS);
292+
Assert.assertEquals("maven", PackageURL.StandardTypes.MAVEN);
293+
Assert.assertEquals("mlflow", PackageURL.StandardTypes.MLFLOW);
294+
Assert.assertEquals("npm", PackageURL.StandardTypes.NPM);
295+
Assert.assertEquals("nuget", PackageURL.StandardTypes.NUGET);
296+
Assert.assertEquals("qpkg", PackageURL.StandardTypes.QPKG);
297+
Assert.assertEquals("oci", PackageURL.StandardTypes.OCI);
298+
Assert.assertEquals("pub", PackageURL.StandardTypes.PUB);
299+
Assert.assertEquals("pypi", PackageURL.StandardTypes.PYPI);
300+
Assert.assertEquals("rpm", PackageURL.StandardTypes.RPM);
301+
Assert.assertEquals("swid", PackageURL.StandardTypes.SWID);
302+
Assert.assertEquals("swift", PackageURL.StandardTypes.SWIFT);
289303
}
290304

291305
@Test

0 commit comments

Comments
 (0)