diff --git a/fetchcode/package.py b/fetchcode/package.py index 4469b690..06fdba56 100644 --- a/fetchcode/package.py +++ b/fetchcode/package.py @@ -327,3 +327,36 @@ def get_rubygems_data_from_purl(purl): download_url=download_url, **purl.to_dict(), ) + + +@router.route("pkg:homebrew/.*") +def get_homebrew_data_from_purl(purl): + """ + Generate `Package` object from the `purl` string of homebrew type + """ + purl = PackageURL.from_string(purl) + name = purl.name + base_path = "https://formulae.brew.sh/api/formula" + api_url = f"{base_path}/{name}.json" + response = get_response(api_url) + declared_license = response.get("license") + homepage_url = response.get("homepage") + urls = response.get("urls") or {} + stable_url = urls.get("stable") or {} + download_url = stable_url.get("url") + yield Package( + homepage_url=homepage_url, + api_url=api_url, + declared_license=declared_license, + download_url=download_url, + **purl.to_dict(), + ) + versions = response.get("versions") or {} + version_purl = PackageURL(type=purl.type, name=name, version=versions.get("stable")) + yield Package( + homepage_url=homepage_url, + api_url=api_url, + declared_license=declared_license, + download_url=download_url, + **version_purl.to_dict(), + ) diff --git a/tests/data/homebrew1.json b/tests/data/homebrew1.json new file mode 100644 index 00000000..64eb8b8b --- /dev/null +++ b/tests/data/homebrew1.json @@ -0,0 +1,75 @@ +{ + "0": { + "type": "homebrew", + "namespace": null, + "name": "node", + "version": null, + "qualifiers": {}, + "subpath": null, + "primary_language": null, + "description": null, + "release_date": null, + "parties": [], + "keywords": [], + "homepage_url": "https://nodejs.org/", + "download_url": "https://nodejs.org/dist/v14.13.1/node-v14.13.1.tar.gz", + "api_url": "https://formulae.brew.sh/api/formula/node.json", + "size": null, + "sha1": null, + "md5": null, + "sha256": null, + "sha512": null, + "bug_tracking_url": null, + "code_view_url": null, + "vcs_url": null, + "copyright": null, + "license_expression": null, + "declared_license": "MIT", + "notice_text": null, + "root_path": null, + "dependencies": [], + "contains_source_code": null, + "source_packages": [], + "purl": "pkg:homebrew/node", + "repository_homepage_url": null, + "repository_download_url": null, + "api_data_url": null + }, + "1": { + "type": "homebrew", + "namespace": null, + "name": "node", + "version": "14.13.1", + "qualifiers": {}, + "subpath": null, + "primary_language": null, + "description": null, + "release_date": null, + "parties": [], + "keywords": [], + "homepage_url": "https://nodejs.org/", + "download_url": "https://nodejs.org/dist/v14.13.1/node-v14.13.1.tar.gz", + "api_url": "https://formulae.brew.sh/api/formula/node.json", + "size": null, + "sha1": null, + "md5": null, + "sha256": null, + "sha512": null, + "bug_tracking_url": null, + "code_view_url": null, + "vcs_url": null, + "copyright": null, + "license_expression": null, + "declared_license": "MIT", + "notice_text": null, + "root_path": null, + "dependencies": [], + "contains_source_code": null, + "source_packages": [], + "purl": "pkg:homebrew/node@14.13.1", + "repository_homepage_url": null, + "repository_download_url": null, + "api_data_url": null + } + +} \ No newline at end of file diff --git a/tests/data/homebrew2.json b/tests/data/homebrew2.json new file mode 100644 index 00000000..cad2cc85 --- /dev/null +++ b/tests/data/homebrew2.json @@ -0,0 +1,72 @@ +{ + "0":{ + "api_data_url": null, + "api_url": "https://formulae.brew.sh/api/formula/wget.json", + "bug_tracking_url": null, + "code_view_url": null, + "contains_source_code": null, + "copyright": null, + "declared_license": "GPL-3.0-or-later", + "dependencies": [], + "description": null, + "download_url": "https://ftp.gnu.org/gnu/wget/wget-1.21.1.tar.gz", + "homepage_url": "https://www.gnu.org/software/wget/", + "keywords": [], + "license_expression": null, + "md5": null, + "name": "wget", + "namespace": null, + "notice_text": null, + "parties": [], + "primary_language": null, + "purl": "pkg:homebrew/wget@1.21.1", + "qualifiers": {}, + "release_date": null, + "repository_download_url": null, + "repository_homepage_url": null, + "root_path": null, + "sha1": null, + "sha256": null, + "sha512": null, + "size": null, + "source_packages": [], + "subpath": null, + "type": "homebrew", + "vcs_url": null, + "version": "1.21.1"}, + + "1" :{"api_data_url": null, + "api_url": "https://formulae.brew.sh/api/formula/wget.json", + "bug_tracking_url": null, + "code_view_url": null, + "contains_source_code": null, + "copyright": null, + "declared_license": "GPL-3.0-or-later", + "dependencies": [], + "description": null, + "download_url": "https://ftp.gnu.org/gnu/wget/wget-1.21.1.tar.gz", + "homepage_url": "https://www.gnu.org/software/wget/", + "keywords": [], + "license_expression": null, + "md5": null, + "name": "wget", + "namespace": null, + "notice_text": null, + "parties": [], + "primary_language": null, + "purl": "pkg:homebrew/wget@1.21.1", + "qualifiers": {}, + "release_date": null, + "repository_download_url": null, + "repository_homepage_url": null, + "root_path": null, + "sha1": null, + "sha256": null, + "sha512": null, + "size": null, + "source_packages": [], + "subpath": null, + "type": "homebrew", + "vcs_url": null, + "version": "1.21.1"} + } \ No newline at end of file diff --git a/tests/data/homebrew_mock_data1.json b/tests/data/homebrew_mock_data1.json new file mode 100644 index 00000000..3f523aa3 --- /dev/null +++ b/tests/data/homebrew_mock_data1.json @@ -0,0 +1,124 @@ +{ + "name": "node", + "full_name": "node", + "oldname": null, + "aliases": [ + "node.js", + "node@14", + "nodejs", + "npm" + ], + "versioned_formulae": [ + "node@12", + "node@10" + ], + "desc": "Platform built on V8 to build network applications", + "license": "MIT", + "homepage": "https://nodejs.org/", + "versions": { + "stable": "14.13.1", + "head": "HEAD", + "bottle": true + }, + "urls": { + "stable": { + "url": "https://nodejs.org/dist/v14.13.1/node-v14.13.1.tar.gz", + "tag": null, + "revision": null + } + }, + "revision": 0, + "version_scheme": 0, + "bottle": { + "stable": { + "rebuild": 0, + "cellar": ":any", + "prefix": "/usr/local", + "root_url": "https://homebrew.bintray.com/bottles", + "files": { + "catalina": { + "url": "https://homebrew.bintray.com/bottles/node-14.13.1.catalina.bottle.tar.gz", + "sha256": "c5574d926c10ecb8a18faa551f6a15c362512134577110c2678d52db3382ba42" + }, + "mojave": { + "url": "https://homebrew.bintray.com/bottles/node-14.13.1.mojave.bottle.tar.gz", + "sha256": "3d42a543356788cb20a3cd91306e9e533c2939b7609c3dc91ffdd405fab1b25f" + }, + "high_sierra": { + "url": "https://homebrew.bintray.com/bottles/node-14.13.1.high_sierra.bottle.tar.gz", + "sha256": "8c9d9dd8a341bd74aec4e8ba1a8abb8ba92e137d771290613676798f0b4a61ba" + } + } + } + }, + "keg_only": false, + "bottle_disabled": false, + "options": [], + "build_dependencies": [ + "pkg-config", + "python@3.8" + ], + "dependencies": [ + "icu4c" + ], + "recommended_dependencies": [], + "optional_dependencies": [], + "uses_from_macos": [], + "requirements": [], + "conflicts_with": [], + "caveats": null, + "installed": [], + "linked_keg": null, + "pinned": false, + "outdated": false, + "deprecated": false, + "disabled": false, + "analytics": { + "install": { + "30d": { + "node": 405637, + "node --HEAD": 44, + "node --with-full-icu": 1, + "node --without-npm": 1 + }, + "90d": { + "node": 1074821, + "node --HEAD": 117, + "node --without-npm": 3, + "Node": 1, + "node --with-full-icu": 1 + }, + "365d": { + "node": 4314220, + "node --HEAD": 617, + "node --without-npm": 29, + "node --without-icu4c": 13, + "node --with-openssl@1.1": 6 + } + }, + "install_on_request": { + "30d": { + "node": 294250, + "node --HEAD": 15 + }, + "90d": { + "node": 787407, + "node --HEAD": 52, + "Node": 1 + }, + "365d": { + "node": 3134446, + "node --HEAD": 343, + "node --without-icu4c": 13, + "node --without-npm": 9, + "node --with-openssl@1.1": 6 + } + }, + "build_error": { + "30d": { + "node": 0 + } + } + }, + "generated_date": "2020-10-11" +} \ No newline at end of file diff --git a/tests/data/homebrew_mock_data2.json b/tests/data/homebrew_mock_data2.json new file mode 100644 index 00000000..b82f717b --- /dev/null +++ b/tests/data/homebrew_mock_data2.json @@ -0,0 +1 @@ +{"name":"wget","full_name":"wget","tap":"homebrew/core","oldname":null,"aliases":[],"versioned_formulae":[],"desc":"Internet file retriever","license":"GPL-3.0-or-later","homepage":"https://www.gnu.org/software/wget/","versions":{"stable":"1.21.1","head":"HEAD","bottle":true},"urls":{"stable":{"url":"https://ftp.gnu.org/gnu/wget/wget-1.21.1.tar.gz","tag":null,"revision":null}},"revision":0,"version_scheme":0,"bottle":{"stable":{"rebuild":0,"cellar":"/usr/local/Cellar","prefix":"/usr/local","root_url":"https://homebrew.bintray.com/bottles","files":{"arm64_big_sur":{"url":"https://homebrew.bintray.com/bottles/wget-1.21.1.arm64_big_sur.bottle.tar.gz","sha256":"e9034fc9062d5d28972135be031876672aff18fa945ce37e9c2ee1e2c4287f3a"},"big_sur":{"url":"https://homebrew.bintray.com/bottles/wget-1.21.1.big_sur.bottle.tar.gz","sha256":"e6ea2a50b8196206f7072360e713535bb16fb786c8b5fe23cab05757e0f67b13"},"catalina":{"url":"https://homebrew.bintray.com/bottles/wget-1.21.1.catalina.bottle.tar.gz","sha256":"88116cb28d6b85e441d1bb9df0a1454b84f8b9d0e8817a5bee0f228acc59e75a"},"mojave":{"url":"https://homebrew.bintray.com/bottles/wget-1.21.1.mojave.bottle.tar.gz","sha256":"ae4e6f1dc4ecaf2bbed7700e8d64cdc671bf9d6c085ba335f119861fd15956fe"}}}},"keg_only":false,"bottle_disabled":false,"options":[],"build_dependencies":["pkg-config"],"dependencies":["libidn2","openssl@1.1"],"recommended_dependencies":[],"optional_dependencies":[],"uses_from_macos":[],"requirements":[],"conflicts_with":[],"caveats":null,"installed":[{"version":"1.21.1","used_options":[],"built_as_bottle":true,"poured_from_bottle":true,"runtime_dependencies":[{"full_name":"gettext","version":"0.21"},{"full_name":"libunistring","version":"0.9.10"},{"full_name":"libidn2","version":"2.3.0"},{"full_name":"openssl@1.1","version":"1.1.1i"}],"installed_as_dependency":false,"installed_on_request":true}],"linked_keg":"1.21.1","pinned":false,"outdated":false,"deprecated":false,"deprecation_date":null,"deprecation_reason":null,"disabled":false,"disable_date":null,"disable_reason":null,"analytics":{"install":{"30d":{"wget":218835,"wget --HEAD":36},"90d":{"wget":482230,"wget --HEAD":93},"365d":{"wget":1385786,"wget --HEAD":134}},"install_on_request":{"30d":{"wget":217646,"wget --HEAD":36},"90d":{"wget":479575,"wget --HEAD":93},"365d":{"wget":1364206,"wget --HEAD":133}},"build_error":{"30d":{"wget":0}}},"generated_date":"2021-02-19"} diff --git a/tests/test_package.py b/tests/test_package.py index 64b12337..9692c789 100644 --- a/tests/test_package.py +++ b/tests/test_package.py @@ -97,3 +97,19 @@ def test_rubygems_packages(mock_get): mock_get.side_effect = side_effect packages = list(info(purl)) match_data(packages, expected_data) + + +@mock.patch("fetchcode.package.get_response") +def test_homebrew_packages(mock_get): + side_effect = [file_data("tests/data/homebrew_mock_data1.json")] + purl = "pkg:homebrew/node" + expected_data = file_data("tests/data/homebrew1.json") + mock_get.side_effect = side_effect + packages = list(info(purl)) + match_data(packages, expected_data) + side_effect = [file_data("tests/data/homebrew_mock_data2.json")] + purl = "pkg:homebrew/wget@1.21.1" + expected_data = file_data("tests/data/homebrew2.json") + mock_get.side_effect = side_effect + packages = list(info(purl)) + match_data(packages, expected_data)