Skip to content
42 changes: 42 additions & 0 deletions src/packageurl/contrib/purl2url.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
from packageurl.contrib.route import NoRouteAvailable
from packageurl.contrib.route import Router

DEFAULT_MAVEN_REPOSITORY = "https://repo.maven.apache.org/maven2"


def get_repo_download_url_by_package_type(
type, namespace, name, version, archive_extension="tar.gz"
Expand Down Expand Up @@ -314,6 +316,24 @@ def build_cocoapods_repo_url(purl):
return name and f"https://cocoapods.org/pods/{name}"


@repo_router.route("pkg:maven/.*")
def build_maven_repo_url(purl):
"""
Return a Maven repo URL from the `purl` string.
"""
purl_data = PackageURL.from_string(purl)
namespace = purl_data.namespace
name = purl_data.name
version = purl_data.version
qualifiers = purl_data.qualifiers

base_url = qualifiers.get("repository_url", DEFAULT_MAVEN_REPOSITORY)

if namespace and name and version:
namespace = namespace.replace(".", "/")
return f"{base_url}/{namespace}/{name}/{version}"


# Download URLs:


Expand Down Expand Up @@ -365,6 +385,28 @@ def build_npm_download_url(purl):
return f"{base_url}/{name}/-/{name}-{version}.tgz"


@download_router.route("pkg:maven/.*")
def build_maven_download_url(purl):
"""
Return a maven download URL from the `purl` string.
"""
purl_data = PackageURL.from_string(purl)

namespace = purl_data.namespace
name = purl_data.name
version = purl_data.version
qualifiers = purl_data.qualifiers

base_url = qualifiers.get("repository_url", DEFAULT_MAVEN_REPOSITORY)
maven_type = qualifiers.get("type", "jar") # default to "jar"
classifier = qualifiers.get("classifier")

if namespace and name and version:
namespace = namespace.replace(".", "/")
classifier = f"-{classifier}" if classifier else ""
return f"{base_url}/{namespace}/{name}/{version}/{name}-{version}{classifier}.{maven_type}"


@download_router.route("pkg:hackage/.*")
def build_hackage_download_url(purl):
"""
Expand Down
10 changes: 10 additions & 0 deletions tests/contrib/test_purl2url.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ def test_purl2url_get_repo_url():
"pkg:golang/gopkg.in/ldap.v3@v3.1.0": "https://pkg.go.dev/gopkg.in/ldap.v3@v3.1.0",
"pkg:cocoapods/AFNetworking@4.0.1": "https://cocoapods.org/pods/AFNetworking",
"pkg:cocoapods/MapsIndoors@3.24.0": "https://cocoapods.org/pods/MapsIndoors",
"pkg:maven/org.apache.commons/commons-io@1.3.2": "https://repo.maven.apache.org/maven2/org/apache/commons/commons-io/1.3.2",
"pkg:maven/org.apache.commons/commons-io@1.3.2?repository_url=https://repo1.maven.org/maven2": "https://repo1.maven.org/maven2/org/apache/commons/commons-io/1.3.2",
}

for purl, url in purls_url.items():
Expand All @@ -92,6 +94,10 @@ def test_purl2url_get_download_url():
"pkg:gitlab/tg1999/firebase@1a122122": "https://gitlab.com/tg1999/firebase/-/archive/1a122122/firebase-1a122122.tar.gz",
"pkg:gitlab/tg1999/firebase@1a122122?version_prefix=v": "https://gitlab.com/tg1999/firebase/-/archive/v1a122122/firebase-v1a122122.tar.gz",
"pkg:gitlab/hoppr/hoppr@v1.11.1-dev.2": "https://gitlab.com/hoppr/hoppr/-/archive/v1.11.1-dev.2/hoppr-v1.11.1-dev.2.tar.gz",
"pkg:maven/org.apache.commons/commons-io@1.3.2": "https://repo.maven.apache.org/maven2/org/apache/commons/commons-io/1.3.2/commons-io-1.3.2.jar",
"pkg:maven/org.apache.commons/commons-io@1.3.2?repository_url=https://repo1.maven.org/maven2": "https://repo1.maven.org/maven2/org/apache/commons/commons-io/1.3.2/commons-io-1.3.2.jar",
"pkg:maven/org.apache.commons/commons-io@1.3.2?type=pom": "https://repo.maven.apache.org/maven2/org/apache/commons/commons-io/1.3.2/commons-io-1.3.2.pom",
"pkg:maven/org.apache.commons/commons-math3@3.6.1?classifier=sources": "https://repo.maven.apache.org/maven2/org/apache/commons/commons-math3/3.6.1/commons-math3-3.6.1-sources.jar",
# From `download_url` qualifier
"pkg:github/yarnpkg/yarn@1.3.2?download_url=https://github.com/yarnpkg/yarn/releases/download/v1.3.2/yarn-v1.3.2.tar.gz&version_prefix=v": "https://github.com/yarnpkg/yarn/releases/download/v1.3.2/yarn-v1.3.2.tar.gz",
"pkg:generic/lxc-master.tar.gz?download_url=https://salsa.debian.org/lxc-team/lxc/-/archive/master/lxc-master.tar.gz": "https://salsa.debian.org/lxc-team/lxc/-/archive/master/lxc-master.tar.gz",
Expand Down Expand Up @@ -150,6 +156,10 @@ def test_purl2url_get_inferred_urls():
"pkg:cocoapods/AFNetworking@4.0.1": ["https://cocoapods.org/pods/AFNetworking"],
"pkg:composer/psr/log@1.1.3": ["https://packagist.org/packages/psr/log#1.1.3"],
"pkg:rubygems/package-name": ["https://rubygems.org/gems/package-name"],
"pkg:maven/org.apache.commons/commons-io@1.3.2": [
"https://repo.maven.apache.org/maven2/org/apache/commons/commons-io/1.3.2",
"https://repo.maven.apache.org/maven2/org/apache/commons/commons-io/1.3.2/commons-io-1.3.2.jar",
],
"pkg:bitbucket/birkenfeld": [],
}

Expand Down
Loading