diff --git a/Library/Homebrew/formula.rb b/Library/Homebrew/formula.rb index d38253dff26ab..1ae1da199f650 100644 --- a/Library/Homebrew/formula.rb +++ b/Library/Homebrew/formula.rb @@ -273,8 +273,7 @@ def initialize(name, path, spec, alias_path: nil, tap: nil, force_bottle: false) Tap.from_path(path) end - @pypi_packages_info = T.let(self.class.pypi_packages_info || PypiPackages.from_json_file(@tap, @name), - PypiPackages) + @pypi_packages_info = T.let(self.class.pypi_packages_info || PypiPackages.new, PypiPackages) @full_name = T.let(T.must(full_name_with_optional_tap(name)), String) @full_alias_name = T.let(full_name_with_optional_tap(@alias_name), T.nilable(String)) @@ -4000,25 +3999,18 @@ def head(val = nil, specs = {}, &block) # ``` sig { params( - package_name: T.nilable(String), - extra_packages: T.nilable(T.any(String, T::Array[String])), - exclude_packages: T.nilable(T.any(String, T::Array[String])), - dependencies: T.nilable(T.any(String, T::Array[String])), - needs_manual_update: T::Boolean, + package_name: T.nilable(String), + extra_packages: T.nilable(T.any(String, T::Array[String])), + exclude_packages: T.nilable(T.any(String, T::Array[String])), + dependencies: T.nilable(T.any(String, T::Array[String])), ).void } def pypi_packages( package_name: nil, extra_packages: nil, exclude_packages: nil, - dependencies: nil, - needs_manual_update: false + dependencies: nil ) - if needs_manual_update - @pypi_packages_info = PypiPackages.new needs_manual_update: true - return - end - if [package_name, extra_packages, exclude_packages, dependencies].all?(&:nil?) raise ArgumentError, "must provide at least one argument" end diff --git a/Library/Homebrew/pypi_packages.rb b/Library/Homebrew/pypi_packages.rb index dbb0ce4192614..582c8c633c9d5 100644 --- a/Library/Homebrew/pypi_packages.rb +++ b/Library/Homebrew/pypi_packages.rb @@ -16,56 +16,23 @@ class PypiPackages sig { returns(T::Array[String]) } attr_reader :dependencies - sig { params(tap: T.nilable(Tap), formula_name: String).returns(T.attached_class) } - def self.from_json_file(tap, formula_name) - list_entry = tap&.pypi_formula_mappings&.fetch(formula_name, nil) - - return new(defined_pypi_mapping: false) if list_entry.nil? - - case T.cast(list_entry, T.any(FalseClass, String, T::Hash[String, T.any(String, T::Array[String])])) - when false - new needs_manual_update: true - when String - new package_name: list_entry - when Hash - package_name = list_entry["package_name"] - extra_packages = list_entry.fetch("extra_packages", []) - exclude_packages = list_entry.fetch("exclude_packages", []) - dependencies = list_entry.fetch("dependencies", []) - - new package_name:, extra_packages:, exclude_packages:, dependencies: - end - end - sig { params( - package_name: T.nilable(String), - extra_packages: T::Array[String], - exclude_packages: T::Array[String], - dependencies: T::Array[String], - needs_manual_update: T::Boolean, - defined_pypi_mapping: T::Boolean, + package_name: T.nilable(String), + extra_packages: T::Array[String], + exclude_packages: T::Array[String], + dependencies: T::Array[String], ).void } def initialize( package_name: nil, extra_packages: [], exclude_packages: [], - dependencies: [], - needs_manual_update: false, - defined_pypi_mapping: true + dependencies: [] ) @package_name = T.let(package_name, T.nilable(String)) @extra_packages = T.let(extra_packages, T::Array[String]) @exclude_packages = T.let(exclude_packages, T::Array[String]) @dependencies = T.let(dependencies, T::Array[String]) - @needs_manual_update = T.let(needs_manual_update, T::Boolean) - @defined_pypi_mapping = T.let(defined_pypi_mapping, T::Boolean) end - - sig { returns(T::Boolean) } - def defined_pypi_mapping? = @defined_pypi_mapping - - sig { returns(T::Boolean) } - def needs_manual_update? = @needs_manual_update end diff --git a/Library/Homebrew/tap.rb b/Library/Homebrew/tap.rb index 4e6c6db241b97..8a920ac416469 100644 --- a/Library/Homebrew/tap.rb +++ b/Library/Homebrew/tap.rb @@ -25,8 +25,6 @@ class Tap private_constant :HOMEBREW_TAP_MIGRATIONS_FILE HOMEBREW_TAP_AUTOBUMP_FILE = ".github/autobump.txt" private_constant :HOMEBREW_TAP_AUTOBUMP_FILE - HOMEBREW_TAP_PYPI_FORMULA_MAPPINGS_FILE = "pypi_formula_mappings.json" - private_constant :HOMEBREW_TAP_PYPI_FORMULA_MAPPINGS_FILE HOMEBREW_TAP_SYNCED_VERSIONS_FORMULAE_FILE = "synced_versions_formulae.json" private_constant :HOMEBREW_TAP_SYNCED_VERSIONS_FORMULAE_FILE HOMEBREW_TAP_DISABLED_NEW_USR_LOCAL_RELOCATION_FORMULAE_FILE = "disabled_new_usr_local_relocation_formulae.json" @@ -40,7 +38,6 @@ class Tap #{HOMEBREW_TAP_FORMULA_RENAMES_FILE} #{HOMEBREW_TAP_CASK_RENAMES_FILE} #{HOMEBREW_TAP_MIGRATIONS_FILE} - #{HOMEBREW_TAP_PYPI_FORMULA_MAPPINGS_FILE} #{HOMEBREW_TAP_SYNCED_VERSIONS_FORMULAE_FILE} #{HOMEBREW_TAP_DISABLED_NEW_USR_LOCAL_RELOCATION_FORMULAE_FILE} #{HOMEBREW_TAP_AUDIT_EXCEPTIONS_DIR}/*.json @@ -258,7 +255,6 @@ def clear_cache @audit_exceptions = nil @style_exceptions = nil - @pypi_formula_mappings = nil @synced_versions_formulae = nil @config = nil @@ -1081,18 +1077,6 @@ def style_exceptions T.nilable(T::Hash[Symbol, T.untyped])) end - # Hash with pypi formula mappings - sig { overridable.returns(T::Hash[String, T.untyped]) } - def pypi_formula_mappings - return @pypi_formula_mappings if @pypi_formula_mappings - - @pypi_formula_mappings = T.let( - T.cast(read_formula_list(path/HOMEBREW_TAP_PYPI_FORMULA_MAPPINGS_FILE), T::Hash[String, T.untyped]), - T.nilable(T::Hash[String, T.untyped]), - ) - T.must(@pypi_formula_mappings) - end - # Array with synced versions formulae sig { overridable.returns(T::Array[T::Array[String]]) } def synced_versions_formulae @@ -1441,14 +1425,6 @@ def style_exceptions end, T.nilable(T::Hash[Symbol, T.untyped])) end - sig { override.returns(T::Hash[String, T.untyped]) } - def pypi_formula_mappings - @pypi_formula_mappings ||= T.let(begin - ensure_installed! - super - end, T.nilable(T::Hash[String, T.untyped])) - end - sig { override.returns(T::Array[T::Array[String]]) } def synced_versions_formulae @synced_versions_formulae ||= T.let(begin diff --git a/Library/Homebrew/tap_auditor.rb b/Library/Homebrew/tap_auditor.rb index 6d62d21f3df42..7a5063546c5fa 100644 --- a/Library/Homebrew/tap_auditor.rb +++ b/Library/Homebrew/tap_auditor.rb @@ -5,7 +5,7 @@ module Homebrew # Auditor for checking common violations in {Tap}s. class TapAuditor attr_reader :name, :path, :formula_names, :formula_aliases, :formula_renames, :cask_tokens, - :tap_audit_exceptions, :tap_style_exceptions, :tap_pypi_formula_mappings, :problems + :tap_audit_exceptions, :tap_style_exceptions, :problems sig { params(tap: Tap, strict: T.nilable(T::Boolean)).void } def initialize(tap, strict:) @@ -15,7 +15,6 @@ def initialize(tap, strict:) @path = tap.path @tap_audit_exceptions = tap.audit_exceptions @tap_style_exceptions = tap.style_exceptions - @tap_pypi_formula_mappings = tap.pypi_formula_mappings @tap_synced_versions_formulae = tap.synced_versions_formulae @tap_autobump = tap.autobump @tap_official = tap.official? @@ -55,7 +54,6 @@ def audit_json_files def audit_tap_formula_lists check_formula_list_directory "audit_exceptions", @tap_audit_exceptions check_formula_list_directory "style_exceptions", @tap_style_exceptions - check_formula_list "pypi_formula_mappings", @tap_pypi_formula_mappings check_formula_list "formula_renames", @formula_renames.values check_formula_list ".github/autobump.txt", @tap_autobump unless @tap_official check_formula_list "synced_versions_formulae", @tap_synced_versions_formulae.flatten diff --git a/Library/Homebrew/test/pypi_packages_spec.rb b/Library/Homebrew/test/pypi_packages_spec.rb deleted file mode 100644 index e28f7ff4e7d39..0000000000000 --- a/Library/Homebrew/test/pypi_packages_spec.rb +++ /dev/null @@ -1,142 +0,0 @@ -# frozen_string_literal: true - -require "pypi_packages" - -RSpec.describe PypiPackages do - describe ".from_json_file" do - let(:tap) { Tap.fetch("homebrew", "foo") } - let(:formula_name) { "test-formula" } - let(:mappings) { nil } - - before do - allow(tap).to receive(:pypi_formula_mappings).and_return(mappings) - end - - context "when JSON is `nil`" do - it "returns an instance with defined_pypi_mapping: false" do - pkgs = described_class.from_json_file(tap, formula_name) - expect(pkgs).to be_a(described_class) - expect(pkgs.defined_pypi_mapping?).to be(false) - expect(pkgs.needs_manual_update?).to be(false) - expect(pkgs.package_name).to be_nil - end - end - - context "when JSON is an empty hash" do - let(:mappings) { {} } - - it "returns an instance with defined_pypi_mapping: false" do - pkgs = described_class.from_json_file(tap, formula_name) - expect(pkgs).to be_a(described_class) - expect(pkgs.defined_pypi_mapping?).to be(false) - expect(pkgs.needs_manual_update?).to be(false) - expect(pkgs.package_name).to be_nil - end - end - - context "when mapping entry is `false`" do - let(:mappings) { { formula_name => false } } - - it "returns an instance with needs_manual_update: true" do - pkgs = described_class.from_json_file(tap, formula_name) - expect(pkgs).to be_a(described_class) - expect(pkgs.defined_pypi_mapping?).to be(true) - expect(pkgs.needs_manual_update?).to be(true) - expect(pkgs.package_name).to be_nil - end - end - - context "when mapping entry is a String" do - let(:mappings) { { formula_name => "bar" } } - - it "returns an instance with package_name set" do - pkgs = described_class.from_json_file(tap, formula_name) - expect(pkgs.package_name).to eq("bar") - expect(pkgs.extra_packages).to eq([]) - expect(pkgs.exclude_packages).to eq([]) - expect(pkgs.dependencies).to eq([]) - expect(pkgs.defined_pypi_mapping?).to be(true) - expect(pkgs.needs_manual_update?).to be(false) - end - end - - context "when mapping entry is `true`" do - let(:mappings) { { formula_name => true } } - - it "raises a Sorbet type error" do - expect do - described_class.from_json_file(tap, formula_name) - end.to raise_error(TypeError, /got type TrueClass/) - end - end - - context "when mapping entry is a Hash" do - let(:mappings) do - { - formula_name => { - "package_name" => "bar", - "extra_packages" => ["baz"], - "exclude_packages" => ["qux"], - "dependencies" => ["quux"], - }, - } - end - - it "returns an instance with all fields populated" do - pkgs = described_class.from_json_file(tap, formula_name) - expect(pkgs.package_name).to eq("bar") - expect(pkgs.extra_packages).to eq(["baz"]) - expect(pkgs.exclude_packages).to eq(["qux"]) - expect(pkgs.dependencies).to eq(["quux"]) - expect(pkgs.defined_pypi_mapping?).to be(true) - expect(pkgs.needs_manual_update?).to be(false) - end - end - - context "when mapping entry hash omits optional keys" do - let(:mappings) do - { formula_name => { "package_name" => "bar" } } - end - - it "fills missing keys with empty arrays" do - pkgs = described_class.from_json_file(tap, formula_name) - expect(pkgs.package_name).to eq("bar") - expect(pkgs.extra_packages).to eq([]) - expect(pkgs.exclude_packages).to eq([]) - expect(pkgs.dependencies).to eq([]) - end - end - - context "when mapping entry hash uses Array for `package_name`" do - let(:mappings) do - { formula_name => { "package_name" => ["bar"] } } - end - - it "raises a Sorbet type error" do - expect do - described_class.from_json_file(tap, formula_name) - end.to raise_error(TypeError, /got type Array/) - end - end - - context "when mapping entry hash uses String for keys" do - let(:mappings) do - { formula_name => { "extra_packages" => "bar" } } - end - - it "raises a Sorbet type error" do - expect do - described_class.from_json_file(tap, formula_name) - end.to raise_error(TypeError, /got type String/) - end - end - - context "when tap is `nil`" do - it "fills missing keys with empty arrays" do - pkgs = described_class.from_json_file(nil, formula_name) - expect(pkgs.defined_pypi_mapping?).to be(false) - expect(pkgs.package_name).to be_nil - end - end - end -end diff --git a/Library/Homebrew/test/spec_helper.rb b/Library/Homebrew/test/spec_helper.rb index e1c308e4e861d..54f5bbf72aaab 100644 --- a/Library/Homebrew/test/spec_helper.rb +++ b/Library/Homebrew/test/spec_helper.rb @@ -312,7 +312,6 @@ CoreTap.instance.path/"tap_migrations.json", CoreTap.instance.path/"audit_exceptions", CoreTap.instance.path/"style_exceptions", - CoreTap.instance.path/"pypi_formula_mappings.json", *Pathname.glob("#{HOMEBREW_CELLAR}/*/"), HOMEBREW_LIBRARY_PATH/"test/.vscode", HOMEBREW_LIBRARY_PATH/"test/.cursor", diff --git a/Library/Homebrew/test/tap_spec.rb b/Library/Homebrew/test/tap_spec.rb index 0852d3ecd6c02..f25722207b79b 100644 --- a/Library/Homebrew/test/tap_spec.rb +++ b/Library/Homebrew/test/tap_spec.rb @@ -58,17 +58,6 @@ class Foo < Formula JSON end - (path/"pypi_formula_mappings.json").write <<~JSON - { - "formula1": "foo", - "formula2": { - "package_name": "foo", - "extra_packages": ["bar"], - "exclude_packages": ["baz"] - } - } - JSON - [ cmd_file, manpage_file, @@ -619,22 +608,6 @@ def setup_completion(link:) end end - describe "#pypi_formula_mappings" do - it "returns the pypi_formula_mappings hash" do - setup_tap_files - - expected_result = { - "formula1" => "foo", - "formula2" => { - "package_name" => "foo", - "extra_packages" => ["bar"], - "exclude_packages" => ["baz"], - }, - } - expect(homebrew_foo_tap.pypi_formula_mappings).to eq expected_result - end - end - describe "#formula_file?" do it "matches files from Formula/" do tap = described_class.fetch("hard/core") @@ -767,7 +740,6 @@ class Foo < Formula tap_migrations.json audit_exceptions/formula_list.json style_exceptions/formula_hash.json - pypi_formula_mappings.json ].each do |file| (path/file).dirname.mkpath (path/file).write formula_list_file_json @@ -788,7 +760,6 @@ class Foo < Formula expect(core_tap.tap_migrations).to eq formula_list_file_contents expect(core_tap.audit_exceptions).to eq({ formula_list: formula_list_file_contents }) expect(core_tap.style_exceptions).to eq({ formula_hash: formula_list_file_contents }) - expect(core_tap.pypi_formula_mappings).to eq formula_list_file_contents end end diff --git a/Library/Homebrew/utils/pypi.rb b/Library/Homebrew/utils/pypi.rb index f898154d3bbde..c310da47057bb 100644 --- a/Library/Homebrew/utils/pypi.rb +++ b/Library/Homebrew/utils/pypi.rb @@ -237,17 +237,13 @@ def self.update_python_resources!(formula, version: nil, package_name: nil, extr exclude_packages: nil, dependencies: nil, install_dependencies: false, print_only: false, silent: false, verbose: false, ignore_errors: false, ignore_non_pypi_packages: false) - list_entry = formula.pypi_packages_info - if list_entry.defined_pypi_mapping? && package_name.blank? && extra_packages.blank? && exclude_packages.blank? + if [package_name, extra_packages, exclude_packages, dependencies].all?(&:blank?) + list_entry = formula.pypi_packages_info - if list_entry.needs_manual_update? && !print_only - odie "The resources for \"#{formula.name}\" need special attention. Please update them manually." - else - package_name = list_entry.package_name - extra_packages = list_entry.extra_packages - exclude_packages = list_entry.exclude_packages - dependencies = list_entry.dependencies - end + package_name = list_entry.package_name + extra_packages = list_entry.extra_packages + exclude_packages = list_entry.exclude_packages + dependencies = list_entry.dependencies end missing_dependencies = Array(dependencies).reject do |dependency|