-
-
Notifications
You must be signed in to change notification settings - Fork 25
[WIP] Add support for converting PURLS to URLS #27
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,173 @@ | ||
| # fetchcode is a free software tool from nexB Inc. and others. | ||
| # Visit https://github.com/nexB/fetchcode for support and download. | ||
| # | ||
| # Copyright (c) nexB Inc. and others. All rights reserved. | ||
| # http://nexb.com and http://aboutcode.org | ||
| # | ||
| # This software is licensed under the Apache License version 2.0. | ||
| # | ||
| # You may not use this software except in compliance with the License. | ||
| # You may obtain a copy of the License at: | ||
| # http://apache.org/licenses/LICENSE-2.0 | ||
| # Unless required by applicable law or agreed to in writing, software distributed | ||
| # under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR | ||
| # CONDITIONS OF ANY KIND, either express or implied. See the License for the | ||
| # specific language governing permissions and limitations under the License. | ||
|
|
||
| from urllib.parse import urlparse | ||
|
|
||
|
|
||
| def index_in_list(index, list): | ||
| return index < len(list) | ||
|
|
||
|
|
||
| def build_bitbucket(**data): | ||
| """ | ||
| Take dictionary `data` as input and returns a valid bitbucket URL string `url` | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use imperative style for docstrings. But there is a larger problem... why use a dict here rather than the packageurl library and object that has nice named attributes? |
||
| """ | ||
|
|
||
| name = data["name"] | ||
| namespace = data["namespace"] | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please use single quotes throughout unless this is a docstring
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I ran black, due to which all these single quotes converted into double quotes, apologies for that 😅
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's great then. Stick to black and make it part of the CI and tests too. |
||
| if not (name and namespace): | ||
| return | ||
|
|
||
| url = "https://bitbucket.org/{namespace}/{name}".format( | ||
| namespace=namespace, name=name | ||
| ) | ||
| version = data["version"] | ||
| if version: | ||
| url = "{url}/src/{version}".format(url=url, version=version) | ||
|
|
||
| subpath = data["subpath"] | ||
| if subpath: | ||
| url = "{url}/{subpath}".format(url=url, subpath=subpath) | ||
|
|
||
| return url | ||
|
|
||
|
|
||
| def build_cargo(**data): | ||
| """ | ||
| Take dictionary `data` as input and returns a valid cargo URL string `url` | ||
| """ | ||
| name = data["name"] | ||
| version = data["version"] | ||
| if not (name and version): | ||
| return | ||
|
|
||
| return "https://crates.io/api/v1/crates/{name}/{version}/download".format( | ||
| name=name, version=version | ||
| ) | ||
|
|
||
|
|
||
| def build_github(**data): | ||
| """ | ||
| Take dictionary `data` as input and returns a valid github URL string `url` | ||
| """ | ||
| name = data["name"] | ||
| namespace = data["namespace"] | ||
| if not (name and namespace): | ||
| return | ||
|
|
||
| url = "https://github.com/{namespace}/{name}".format(namespace=namespace, name=name) | ||
|
|
||
| version = data["version"] | ||
| if version: | ||
| url = "{url}/tree/{version}".format(url=url, version=version) | ||
|
|
||
| subpath = data["subpath"] | ||
| if subpath: | ||
| url = "{url}/{subpath}".format(url=url, subpath=subpath) | ||
|
|
||
| return url | ||
|
|
||
|
|
||
| def build_gitlab(**data): | ||
| """ | ||
| Take dictionary `data` as input and returns a valid gitlab URL string `url` | ||
| """ | ||
| name = data["name"] | ||
| namespace = data["namespace"] | ||
|
|
||
| if not (name and namespace): | ||
| return | ||
|
|
||
| url = "https://gitlab.com/{namespace}/{name}".format(namespace=namespace, name=name) | ||
|
|
||
| version = data["version"] | ||
| if version: | ||
| url = "{url}/-/tree/{version}".format(url=url, version=version) | ||
|
|
||
| subpath = data["subpath"] | ||
| if subpath: | ||
| url = "{url}/{subpath}".format(url=url, subpath=subpath) | ||
|
|
||
| return url | ||
|
|
||
|
|
||
| def build_gem(**data): | ||
| """ | ||
| Take dictionary `data` as input and returns a valid rubygem URL string `url` | ||
| """ | ||
| name = data["name"] | ||
| version = data["version"] | ||
|
|
||
| if not (name and version): | ||
| return | ||
|
|
||
| return "https://rubygems.org/downloads/{name}-{version}.gem".format( | ||
| name=name, version=version | ||
| ) | ||
|
|
||
|
|
||
| def purl2url(purl): | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we add some descriptive docstring for this function |
||
| """ | ||
| Take PackageURL `purl` as input and return a valid URL string `url` depending on the type of purl | ||
| """ | ||
| url_parts = urlparse(purl) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why parsing a purl yourself? please use the packageurl library instead |
||
|
|
||
| subpath = url_parts.fragment if url_parts.fragment != "" else None | ||
| qualifiers = url_parts.query if url_parts.query != "" else None | ||
|
|
||
| path = url_parts.path | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we use a more descriptive name for
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah sure, agreed |
||
| path = path.split("@") | ||
|
|
||
| if index_in_list(1, path): | ||
| version = path[1] | ||
| else: | ||
| version = None | ||
|
|
||
| path = path[0] | ||
|
|
||
| path = path.split("/") | ||
|
|
||
| name = None | ||
| namespace = None | ||
|
|
||
| # pkg:github/TG1999/fetchcode | ||
| if index_in_list(2, path): | ||
| name = path[2] | ||
| namespace = path[1] | ||
|
|
||
| # pkg:crago/clap@2.3.3 | ||
| elif index_in_list(1, path): | ||
| name = path[1] | ||
|
|
||
| type = path[0] | ||
|
|
||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. All the code above is parsing a purl which already exists in a tested and more robust form in the packaeurl library. Please use that library instead. |
||
| converter = { | ||
| "bitbucket": build_bitbucket, | ||
| "cargo": build_cargo, | ||
| "gem": build_gem, | ||
| "github": build_github, | ||
| "gitlab": build_gitlab, | ||
| } | ||
|
|
||
| if type in converter: | ||
| url = converter[type]( | ||
| name=name, | ||
| namespace=namespace, | ||
| version=version, | ||
| qualifiers=qualifiers, | ||
| subpath=subpath, | ||
| ) | ||
| return url | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| # fetchcode is a free software tool from nexB Inc. and others. | ||
| # Visit https://github.com/nexB/fetchcode for support and download. | ||
| # | ||
| # Copyright (c) nexB Inc. and others. All rights reserved. | ||
| # http://nexb.com and http://aboutcode.org | ||
| # | ||
| # This software is licensed under the Apache License version 2.0. | ||
| # | ||
| # You may not use this software except in compliance with the License. | ||
| # You may obtain a copy of the License at: | ||
| # http://apache.org/licenses/LICENSE-2.0 | ||
| # Unless required by applicable law or agreed to in writing, software distributed | ||
| # under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR | ||
| # CONDITIONS OF ANY KIND, either express or implied. See the License for the | ||
| # specific language governing permissions and limitations under the License. | ||
|
|
||
| from fetchcode.purl2url import purl2url | ||
|
|
||
|
|
||
| def test_convert_with_purls_string(): | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. purl2url should be part of the packageurl library IMHO |
||
| purls_url = { | ||
| "pkg:github/tg1999/fetchcode": "https://github.com/tg1999/fetchcode", | ||
| "pkg:github/tg1999/fetchcode@master": "https://github.com/tg1999/fetchcode/tree/master", | ||
| "pkg:github/tg1999/fetchcode@master#tests": "https://github.com/tg1999/fetchcode/tree/master/tests", | ||
| "pkg:github": None, | ||
| "pkg:github/tg1999": None, | ||
| "pkg:cargo/clap@2.3.3": "https://crates.io/api/v1/crates/clap/2.3.3/download", | ||
| "pkg:cargo/rand@0.7.2": "https://crates.io/api/v1/crates/rand/0.7.2/download", | ||
| "pkg:cargo/structopt@0.3.11": "https://crates.io/api/v1/crates/structopt/0.3.11/download", | ||
| "pkg:cargo/structopt": None, | ||
| "pkg:cargo": None, | ||
| "pkg:gem/jruby-launcher@1.1.2?platform=java": "https://rubygems.org/downloads/jruby-launcher-1.1.2.gem", | ||
| "pkg:gem/ruby-advisory-db-check@0.12.4": "https://rubygems.org/downloads/ruby-advisory-db-check-0.12.4.gem", | ||
| "pkg:gem/package-name": None, | ||
| "pkg:gem": None, | ||
| "pkg:bitbucket/birkenfeld/pygments-main": "https://bitbucket.org/birkenfeld/pygments-main", | ||
| "pkg:bitbucket/birkenfeld/pygments-main@244fd47e07d1014f0aed9c": "https://bitbucket.org/birkenfeld/pygments-main/src/244fd47e07d1014f0aed9c", | ||
| "pkg:bitbucket/birkenfeld/pygments-main@master#views": "https://bitbucket.org/birkenfeld/pygments-main/src/master/views", | ||
| "pkg:bitbucket/birkenfeld": None, | ||
| "pkg:bitbucket": None, | ||
| "pkg:gitlab/tg1999/firebase@master": "https://gitlab.com/tg1999/firebase/-/tree/master", | ||
| "pkg:gitlab/tg1999/firebase@1a122122#views": "https://gitlab.com/tg1999/firebase/-/tree/1a122122/views", | ||
| "pkg:gitlab/tg1999/firebase": "https://gitlab.com/tg1999/firebase", | ||
| "pkg:gitlab/tg1999": None, | ||
| "pkg:gitlab": None, | ||
| } | ||
|
|
||
| for purl, url in purls_url.items(): | ||
| assert url == purl2url(purl) | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do not create a function for something so trivial, also in general using indexes on a list is often a sign that there must be a better way to do the work.