From eb9d32a90e62792a5ea4b042d18a9c7bb39a6951 Mon Sep 17 00:00:00 2001 From: Tushar Goel Date: Tue, 25 Jul 2023 17:15:38 +0530 Subject: [PATCH] Add download purl2url support for bitbucket and gitlab Signed-off-by: Tushar Goel --- src/packageurl/contrib/purl2url.py | 33 ++++++++++++++++++++++++++---- tests/contrib/test_purl2url.py | 10 +++++++-- 2 files changed, 37 insertions(+), 6 deletions(-) diff --git a/src/packageurl/contrib/purl2url.py b/src/packageurl/contrib/purl2url.py index 6e91bab..be8715d 100644 --- a/src/packageurl/contrib/purl2url.py +++ b/src/packageurl/contrib/purl2url.py @@ -28,6 +28,19 @@ from packageurl.contrib.route import NoRouteAvailable from packageurl.contrib.route import Router + +def get_repo_download_url_by_package_type(type, namespace, name, version): + """ + Return a download URL for package repo by package type. + """ + download_url_by_type = { + "github": f"https://github.com/{namespace}/{name}/archive/refs/tags/{version}.zip", + "bitbucket": f"https://bitbucket.org/{namespace}/{name}/get/{version}.zip", + "gitlab": f"https://gitlab.com/{namespace}/{name}/-/archive/{version}/{name}-{version}.zip", + } + return download_url_by_type.get(type) + + repo_router = Router() download_router = Router() @@ -328,14 +341,24 @@ def build_nuget_download_url(purl): return f"https://www.nuget.org/api/v2/package/{name}/{version}" -@download_router.route("pkg:github/.*") -def build_github_download_url(purl): +@download_router.route("pkg:gitlab/.*", "pkg:bitbucket/.*", "pkg:github/.*") +def build_repo_download_url(purl): """ - Return a github download URL from the `purl` string. + Return a gitlab download URL from the `purl` string. + """ + return get_repo_download_url(purl) + + +def get_repo_download_url(purl): + """ + Return a dict with download_url if present in ``purl`` qualifiers, + if namespace, name and version is present in ``purl`` return a dict with + namespace, name and version else return None. """ purl_data = PackageURL.from_string(purl) namespace = purl_data.namespace + type = purl_data.type name = purl_data.name version = purl_data.version qualifiers = purl_data.qualifiers @@ -350,4 +373,6 @@ def build_github_download_url(purl): version_prefix = qualifiers.get("version_prefix", "") version = f"{version_prefix}{version}" - return f"https://github.com/{namespace}/{name}/archive/refs/tags/{version}.zip" + return get_repo_download_url_by_package_type( + type=type, namespace=namespace, name=name, version=version + ) diff --git a/tests/contrib/test_purl2url.py b/tests/contrib/test_purl2url.py index ed0c686..eef1ba6 100644 --- a/tests/contrib/test_purl2url.py +++ b/tests/contrib/test_purl2url.py @@ -75,6 +75,10 @@ def test_purl2url_get_download_url(): "pkg:hackage/cli-extras@0.2.0.0": "https://hackage.haskell.org/package/cli-extras-0.2.0.0/cli-extras-0.2.0.0.tar.gz", "pkg:nuget/System.Text.Json@6.0.6": "https://www.nuget.org/api/v2/package/System.Text.Json/6.0.6", "pkg:github/nexb/scancode-toolkit@3.1.1?version_prefix=v": "https://github.com/nexb/scancode-toolkit/archive/refs/tags/v3.1.1.zip", + "pkg:bitbucket/robeden/trove@3.0.3": "https://bitbucket.org/robeden/trove/get/3.0.3.zip", + "pkg:bitbucket/robeden/trove@3.0.3?version_prefix=v": "https://bitbucket.org/robeden/trove/get/v3.0.3.zip", + "pkg:gitlab/tg1999/firebase@1a122122": "https://gitlab.com/tg1999/firebase/-/archive/1a122122/firebase-1a122122.zip", + "pkg:gitlab/tg1999/firebase@1a122122?version_prefix=v": "https://gitlab.com/tg1999/firebase/-/archive/v1a122122/firebase-v1a122122.zip", # 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", @@ -87,7 +91,6 @@ def test_purl2url_get_download_url(): "pkg:cargo/abc": None, "pkg:gem/package-name": None, "pkg:bitbucket/birkenfeld": None, - "pkg:gitlab/tg1999/firebase@1a122122": None, "pkg:pypi/sortedcontainers@2.4.0": None, "pkg:golang/xorm.io/xorm@v0.8.2": None, "pkg:golang/gopkg.in/ldap.v3@v3.1.0": None, @@ -121,7 +124,10 @@ def test_purl2url_get_inferred_urls(): ], "pkg:cargo/abc": ["https://crates.io/crates/abc"], "pkg:github/tg1999/fetchcode": ["https://github.com/tg1999/fetchcode"], - "pkg:gitlab/tg1999/firebase@1a122122": ["https://gitlab.com/tg1999/firebase"], + "pkg:gitlab/tg1999/firebase@1a122122": [ + "https://gitlab.com/tg1999/firebase", + "https://gitlab.com/tg1999/firebase/-/archive/1a122122/firebase-1a122122.zip", + ], "pkg:pypi/sortedcontainers@2.4.0": ["https://pypi.org/project/sortedcontainers/2.4.0/"], "pkg:gem/package-name": [], "pkg:bitbucket/birkenfeld": [],