From 461b7bb51963dae410baebade5290b22dc45cc87 Mon Sep 17 00:00:00 2001 From: vBarbaros Date: Sat, 4 Dec 2021 15:25:25 -0500 Subject: [PATCH] Add support for ruby-gem registry purls --- README.md | 5 +- pypurl/purlutils.py | 22 ++++- setup.py | 4 +- tests/test_ruby_gem_purl.py | 181 ++++++++++++++++++++++++++++++++++++ 4 files changed, 207 insertions(+), 5 deletions(-) create mode 100644 tests/test_ruby_gem_purl.py diff --git a/README.md b/README.md index cd1698c..91a7ca6 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,7 @@ * BitBucket * PyPi * npm +* Ruby Gem ### Main concepts: @@ -120,7 +121,7 @@ $ python -m unittest tests/*.py # Expected output ... -Ran 138 tests in 0.009s +Ran 163 tests in 0.006s OK @@ -135,7 +136,7 @@ this module ## TODO -- add support for other repositories, besides the currently implemented (GitHub, Gitlab, BitBucket, PyPi) +- add support for other repositories, besides the currently implemented (GitHub, Gitlab, BitBucket, PyPi, npm, RubyGem) ## [License](https://github.com/vBarbaros/pypurl/blob/main/LICENSE) diff --git a/pypurl/purlutils.py b/pypurl/purlutils.py index 9ff3333..16444d1 100644 --- a/pypurl/purlutils.py +++ b/pypurl/purlutils.py @@ -138,8 +138,14 @@ def parse_durl(download_url): if __is_npm_with_namespace(durl_info_list, purl_dict): purl_dict['name'] = durl_info_list[3] + elif __is_pkg_with_name_and_version_combined(purl_dict): + purl_dict['name'] = __remove_version_from_name(durl_info_list[-1]) else: purl_dict['name'] = durl_info_list[2] + + if purl_dict['name'] == '': + return {} + return purl_dict @@ -187,15 +193,27 @@ def build_purl_dict_from_params_optionals(purl_dict, version, qualifiers, subpat return purl_dict purl_dict['subpath'] = str(subpath) + return purl_dict +def __remove_version_from_name(combined_name_version): + name_parts = combined_name_version.split('-') + name_parts_remove_last = [n for n in name_parts if '.gem' not in n] + return '-'.join(name_parts_remove_last) + + +def __is_pkg_with_name_and_version_combined(purl_dict): + return purl_dict['type'] in ['gem'] + + def __is_npm_with_namespace(durl_info_list, purl_dict): return purl_dict['type'] == 'npm' and len(durl_info_list) == 6 def __get_types_no_namespaces(): - return ['pypi', 'npm'] + return ['pypi', 'npm', 'gem'] + def __type_from_host(type_list): if 'npmjs' in type_list: @@ -208,5 +226,7 @@ def __type_from_host(type_list): return 'pypi' elif 'bitbucket' in type_list: return 'bitbucket' + elif 'rubygems' in type_list: + return 'gem' else: return '' diff --git a/setup.py b/setup.py index ceea61b..f007a12 100644 --- a/setup.py +++ b/setup.py @@ -1,9 +1,9 @@ from setuptools import setup setup(name='pypurl', - version='v0.5.0', + version='v0.6.0', python_requires='>=3.6', - description='Implementation of an easy way to build and handle Package URLs.', + description='Implementation of an easy way to build and handle Package URLs', author='Victor Barbaros', url='https://github.com/vBarbaros/pypurl', ) diff --git a/tests/test_ruby_gem_purl.py b/tests/test_ruby_gem_purl.py new file mode 100644 index 0000000..13ad4e4 --- /dev/null +++ b/tests/test_ruby_gem_purl.py @@ -0,0 +1,181 @@ +import unittest +from pypurl.purl import Purl + + +class RubyGemPurlTestCase(unittest.TestCase): + def setUp(self): + self.purl_obj = Purl() + print('Running ruby-gem-repository tests... OK') + + def test_ruby_gem_purl_to_dict_version_success(self): + purl_with_version = 'pkg:gem/aws-partitions@1.463.0' + actual = self.purl_obj.purl_to_dict(purl_with_version) + self.assertEqual(actual['scheme'], 'pkg') + self.assertEqual(actual['type'], 'gem') + self.assertEqual(actual['namespace'], '') + self.assertEqual(actual['name'], 'aws-partitions') + self.assertEqual(actual['version'], '1.463.0') + + def test_ruby_gem_purl_to_dict_version_qualifier_success(self): + purl_with_version_qualifiers = 'pkg:gem/aws-partitions@1.463.0?param1=one,param2=two' + actual = self.purl_obj.purl_to_dict(purl_with_version_qualifiers) + self.assertEqual(actual['scheme'], 'pkg') + self.assertEqual(actual['type'], 'gem') + self.assertEqual(actual['namespace'], '') + self.assertEqual(actual['name'], 'aws-partitions') + self.assertEqual(actual['version'], '1.463.0') + self.assertEqual(actual['qualifiers'], 'param1=one,param2=two') + + def test_ruby_gem_purl_to_dict_version_qualifier_path_success(self): + purl_with_version_qualifiers_subpath = 'pkg:gem/aws-partitions@1.463.0?param1=one,param2=two#/src/main/sub-path' + actual = self.purl_obj.purl_to_dict(purl_with_version_qualifiers_subpath) + self.assertEqual(actual['scheme'], 'pkg') + self.assertEqual(actual['type'], 'gem') + self.assertEqual(actual['namespace'], '') + self.assertEqual(actual['name'], 'aws-partitions') + self.assertEqual(actual['version'], '1.463.0') + self.assertEqual(actual['qualifiers'], 'param1=one,param2=two') + self.assertEqual(actual['subpath'], '/src/main/sub-path') + + def test_ruby_gem_purl_to_dict_no_pkg_fail(self): + 'pkg:gem/aws-partitions@1.463.0' + purl_with_version_qualifiers_subpath = 'gem/aws-partitions@1.463.0?param1=one,param2=two#/src/main/sub-path' + actual = self.purl_obj.purl_to_dict(purl_with_version_qualifiers_subpath) + self.assertEqual(actual, {}) + + def test_ruby_gem_purl_to_dict_no_type_fail(self): + purl_with_version_qualifiers_subpath = 'pkg:aws-partitions@1.463.0?param1=one,param2=two#/src/main/sub-path' + actual = self.purl_obj.purl_to_dict(purl_with_version_qualifiers_subpath) + self.assertEqual(actual, {}) + + def test_ruby_gem_purl_to_dict_no_namespace_success(self): + purl_with_version_qualifiers_subpath = 'pkg:gem/aws-partitions@1.463.0?param1=one,param2=two#/src/main/sub-path' + actual = self.purl_obj.purl_to_dict(purl_with_version_qualifiers_subpath) + self.assertEqual(actual['scheme'], 'pkg') + self.assertEqual(actual['type'], 'gem') + self.assertEqual(actual['namespace'], '') + self.assertEqual(actual['name'], 'aws-partitions') + self.assertEqual(actual['version'], '1.463.0') + self.assertEqual(actual['qualifiers'], 'param1=one,param2=two') + self.assertEqual(actual['subpath'], '/src/main/sub-path') + + def test_ruby_gem_purl_to_dict_no_name_fail(self): + purl_with_version_qualifiers_subpath = 'pkg:gem@1.463.0?param1=one,param2=two#/src/main/sub-path' + actual = self.purl_obj.purl_to_dict(purl_with_version_qualifiers_subpath) + self.assertEqual(actual, {}) + + def test_ruby_gem_purl_to_dict_no_type_wrong_url_fail(self): + purl_with_version_qualifiers_subpath = 'pkg:/aws-partitions@1.463.0?param1=one,param2=two#/src/main/sub-path' + actual = self.purl_obj.purl_to_dict(purl_with_version_qualifiers_subpath) + self.assertEqual(actual, {}) + + def test_ruby_gem_purl_to_dict_no_name_wrong_url_fail(self): + purl_with_version_qualifiers_subpath = 'pkg:gem/@1.463.0?param1=one,param2=two#/src/main/sub-path' + actual = self.purl_obj.purl_to_dict(purl_with_version_qualifiers_subpath) + self.assertEqual(actual, {}) + + def test_ruby_gem_durl_to_dict_all_success(self): + durl = 'https://rubygems.org/downloads/aws-partitions-1.463.0.gem' + actual = self.purl_obj.durl_to_dict(durl, '1.463.0', 'param1=one,param2=two', '/src/main/sub-path') + self.assertEqual(actual['scheme'], 'pkg') + self.assertEqual(actual['type'], 'gem') + self.assertEqual(actual['namespace'], '') + self.assertEqual(actual['name'], 'aws-partitions') + self.assertEqual(actual['version'], '1.463.0') + self.assertEqual(actual['qualifiers'], 'param1=one,param2=two') + self.assertEqual(actual['subpath'], '/src/main/sub-path') + + def test_ruby_gem_durl_to_dict_version_qualifier_success(self): + durl = 'https://rubygems.org/downloads/aws-partitions-1.463.0.gem' + actual = self.purl_obj.durl_to_dict(durl, '1.463.0', 'param1=one,param2=two') + self.assertEqual(actual['scheme'], 'pkg') + self.assertEqual(actual['type'], 'gem') + self.assertEqual(actual['namespace'], '') + self.assertEqual(actual['name'], 'aws-partitions') + self.assertEqual(actual['version'], '1.463.0') + self.assertEqual(actual['qualifiers'], 'param1=one,param2=two') + + def test_ruby_gem_durl_to_dict_version_success(self): + durl = 'https://rubygems.org/downloads/aws-partitions-1.463.0.gem' + actual = self.purl_obj.durl_to_dict(durl, '1.463.0') + self.assertEqual(actual['scheme'], 'pkg') + self.assertEqual(actual['type'], 'gem') + self.assertEqual(actual['namespace'], '') + self.assertEqual(actual['name'], 'aws-partitions') + self.assertEqual(actual['version'], '1.463.0') + + def test_ruby_gem_durl_to_dict_main_success(self): + durl = 'https://rubygems.org/downloads/aws-partitions-1.463.0.gem' + actual = self.purl_obj.durl_to_dict(durl) + self.assertEqual(actual['scheme'], 'pkg') + self.assertEqual(actual['type'], 'gem') + self.assertEqual(actual['namespace'], '') + self.assertEqual(actual['name'], 'aws-partitions') + + def test_ruby_gem_durl_to_dict_main_wrong_http_fail(self): + durl = 'https:rubygems.org/downloads/aws-partitions-1.463.0.gem' + actual = self.purl_obj.durl_to_dict(durl) + self.assertEqual(actual, {}) + + def test_ruby_gem_durl_to_dict_main_wrong_type_fail(self): + durl = 'https://rubygems/downloads/aws-partitions-1.463.0.gem' + actual = self.purl_obj.durl_to_dict(durl) + self.assertEqual(actual, {}) + + def test_ruby_gem_durl_to_dict_main_wrong_namespace_fail(self): + durl = 'https://rubygems.org//aws-partitions-1.463.0.gem' + actual = self.purl_obj.durl_to_dict(durl) + self.assertEqual(actual, {}) + + def test_ruby_gem_durl_to_dict_main_wrong_name_fail(self): + durl = 'https://rubygems.org/downloads/1.463.0.gem' + actual = self.purl_obj.durl_to_dict(durl) + self.assertEqual(actual, {}) + + def test_ruby_gem_durl_to_purl_all_success(self): + durl = 'https://rubygems.org/downloads/aws-partitions-1.463.0.gem' + actual = self.purl_obj.durl_to_purl(durl, '1.463.0', 'param1=one,param2=two', '/src/main/sub-path') + expect = 'pkg:gem/aws-partitions@1.463.0?param1=one,param2=two#/src/main/sub-path' + self.assertEqual(expect, actual) + + def test_ruby_gem_durl_to_purl_version_qualifier_success(self): + durl = 'https://rubygems.org/downloads/aws-partitions-1.463.0.gem' + actual = self.purl_obj.durl_to_purl(durl, '1.463.0', 'param1=one,param2=two') + expect = 'pkg:gem/aws-partitions@1.463.0?param1=one,param2=two' + self.assertEqual(expect, actual) + + def test_ruby_gem_durl_to_purl_version_success(self): + durl = 'https://rubygems.org/downloads/aws-partitions-1.463.0.gem' + actual = self.purl_obj.durl_to_purl(durl, '1.463.0') + expect = 'pkg:gem/aws-partitions@1.463.0' + self.assertEqual(expect, actual) + + def test_ruby_gem_durl_to_purl_main_success(self): + durl = 'https://rubygems.org/downloads/aws-partitions-1.463.0.gem' + actual = self.purl_obj.durl_to_purl(durl) + expect = 'pkg:gem/aws-partitions' + self.assertEqual(expect, actual) + + def test_ruby_gem_params_to_purl_all_success(self): + actual = self.purl_obj.params_to_purl('gem', '', 'aws-partitions', '1.463.0', 'param1=one,param2=two','/src/main/sub-path') + expect = 'pkg:gem/aws-partitions@1.463.0?param1=one,param2=two#/src/main/sub-path' + self.assertEqual(expect, actual) + + def test_ruby_gem_params_to_purl_version_qualifier_success(self): + actual = self.purl_obj.params_to_purl('gem', '', 'aws-partitions', '1.463.0', 'param1=one,param2=two') + expect = 'pkg:gem/aws-partitions@1.463.0?param1=one,param2=two' + self.assertEqual(expect, actual) + + def test_ruby_gem_params_to_purl_version_success(self): + actual = self.purl_obj.params_to_purl('gem', '', 'aws-partitions', '1.463.0') + expect = 'pkg:gem/aws-partitions@1.463.0' + self.assertEqual(expect, actual) + + def test_ruby_gem_params_to_purl_main_success(self): + actual = self.purl_obj.params_to_purl('gem', '', 'aws-partitions') + expect = 'pkg:gem/aws-partitions' + self.assertEqual(expect, actual) + + +if __name__ == '__main__': + unittest.main()