diff --git a/Library/Homebrew/resource_auditor.rb b/Library/Homebrew/resource_auditor.rb index 796af321e5..6e28607a41 100644 --- a/Library/Homebrew/resource_auditor.rb +++ b/Library/Homebrew/resource_auditor.rb @@ -108,8 +108,16 @@ module Homebrew return unless url.match?(%r{^https?://files\.pythonhosted\.org/packages/}) return if name == owner.name # Skip the top-level package name as we only care about `resource "foo"` blocks. - url =~ %r{/(?[^/]+)-} - pypi_package_name = Regexp.last_match(:package_name).to_s.gsub(/[_.]/, "-") + if url.end_with? ".whl" + path = URI(url).path + return unless path.present? + + pypi_package_name, = File.basename(path).split("-", 2) + else + url =~ %r{/(?[^/]+)-} + pypi_package_name = Regexp.last_match(:package_name).to_s.gsub(/[_.]/, "-") + end + return if name.casecmp(pypi_package_name).zero? problem "resource name should be `#{pypi_package_name}` to match the PyPI package name" diff --git a/Library/Homebrew/test/formula_auditor_spec.rb b/Library/Homebrew/test/formula_auditor_spec.rb index cb52b57c58..8417849849 100644 --- a/Library/Homebrew/test/formula_auditor_spec.rb +++ b/Library/Homebrew/test/formula_auditor_spec.rb @@ -503,7 +503,7 @@ RSpec.describe Homebrew::FormulaAuditor do end describe "#audit_resource_name_matches_pypi_package_name_in_url" do - it "reports a problem if the resource name does not match the python package name" do + it "reports a problem if the resource name does not match the python sdist name" do fa = formula_auditor "foo", <<~RUBY class Foo < Formula url "https://brew.sh/foo-1.0.tgz" @@ -521,6 +521,25 @@ RSpec.describe Homebrew::FormulaAuditor do expect(fa.problems.first[:message]) .to match("resource name should be `FooSomething` to match the PyPI package name") end + + it "reports a problem if the resource name does not match the python wheel name" do + fa = formula_auditor "foo", <<~RUBY + class Foo < Formula + url "https://brew.sh/foo-1.0.tgz" + sha256 "abc123" + homepage "https://brew.sh" + + resource "Something" do + url "https://files.pythonhosted.org/packages/FooSomething-1.0.0-py3-none-any.whl" + sha256 "def456" + end + end + RUBY + + fa.audit_specs + expect(fa.problems.first[:message]) + .to match("resource name should be `FooSomething` to match the PyPI package name") + end end describe "#check_service_command" do diff --git a/Library/Homebrew/utils/pypi.rb b/Library/Homebrew/utils/pypi.rb index db9f6337e7..59fb275b5f 100644 --- a/Library/Homebrew/utils/pypi.rb +++ b/Library/Homebrew/utils/pypi.rb @@ -73,12 +73,22 @@ module PyPI return end - sdist = json["urls"].find { |url| url["packagetype"] == "sdist" } - return if sdist.nil? + dist = json["urls"].find do |url| + url["packagetype"] == "sdist" + end + + # If there isn't an sdist, we use the first universal wheel. + if dist.nil? + dist = json["urls"].find do |url| + url["filename"].end_with?("-none-any.whl") + end + end + + return if dist.nil? @pypi_info = [ - PyPI.normalize_python_package(json["info"]["name"]), sdist["url"], - sdist["digests"]["sha256"], json["info"]["version"] + PyPI.normalize_python_package(json["info"]["name"]), dist["url"], + dist["digests"]["sha256"], json["info"]["version"] ] end