diff --git a/Library/Homebrew/dev-cmd/update-python-resources.rb b/Library/Homebrew/dev-cmd/update-python-resources.rb index 736268b875..936dad5aba 100644 --- a/Library/Homebrew/dev-cmd/update-python-resources.rb +++ b/Library/Homebrew/dev-cmd/update-python-resources.rb @@ -27,7 +27,6 @@ module Homebrew description: "Use the specified when finding resources for . "\ "If no version is specified, the current version for will be used." flag "--package-name=", - depends_on: "--version", description: "Use the specified when finding resources for . "\ "If no package name is specified, it will be inferred from the formula's stable URL." comma_array "--extra-packages=", diff --git a/Library/Homebrew/tap.rb b/Library/Homebrew/tap.rb index d4a33d8ab7..02e60e15cb 100644 --- a/Library/Homebrew/tap.rb +++ b/Library/Homebrew/tap.rb @@ -21,11 +21,13 @@ class Tap HOMEBREW_TAP_FORMULA_RENAMES_FILE = "formula_renames.json" HOMEBREW_TAP_MIGRATIONS_FILE = "tap_migrations.json" HOMEBREW_TAP_AUDIT_EXCEPTIONS_DIR = "audit_exceptions" + HOMEBREW_TAP_FORMULA_LISTS_DIR = "formula_lists" HOMEBREW_TAP_JSON_FILES = %W[ #{HOMEBREW_TAP_FORMULA_RENAMES_FILE} #{HOMEBREW_TAP_MIGRATIONS_FILE} #{HOMEBREW_TAP_AUDIT_EXCEPTIONS_DIR}/*.json + #{HOMEBREW_TAP_FORMULA_LISTS_DIR}/*.json ].freeze def self.fetch(*args) @@ -112,6 +114,7 @@ class Tap @formula_renames = nil @tap_migrations = nil @audit_exceptions = nil + @formula_lists = nil @config = nil remove_instance_variable(:@private) if instance_variable_defined?(:@private) end @@ -560,22 +563,12 @@ class Tap # Hash with audit exceptions def audit_exceptions - @audit_exceptions = {} + @audit_exceptions = read_formula_list_directory HOMEBREW_TAP_AUDIT_EXCEPTIONS_DIR + end - Pathname.glob(path/HOMEBREW_TAP_AUDIT_EXCEPTIONS_DIR/"*").each do |exception_file| - list_name = exception_file.basename.to_s.chomp(".json").to_sym - list_contents = begin - JSON.parse exception_file.read - rescue JSON::ParserError - opoo "#{exception_file} contains invalid JSON" - end - - next if list_contents.nil? - - @audit_exceptions[list_name] = list_contents - end - - @audit_exceptions + # Hash with formula lists + def formula_lists + @formula_lists = read_formula_list_directory HOMEBREW_TAP_FORMULA_LISTS_DIR end def ==(other) @@ -636,6 +629,25 @@ class Tap end end end + + def read_formula_list_directory(directory) + list = {} + + Pathname.glob(path/directory/"*").each do |exception_file| + list_name = exception_file.basename.to_s.chomp(".json").to_sym + list_contents = begin + JSON.parse exception_file.read + rescue JSON::ParserError + opoo "#{exception_file} contains invalid JSON" + end + + next if list_contents.nil? + + list[list_name] = list_contents + end + + list + end end # A specialized {Tap} class for the core formulae. @@ -739,6 +751,13 @@ class CoreTap < Tap end end + def formula_lists + @formula_lists ||= begin + self.class.ensure_installed! + super + end + end + # @private def formula_file_to_name(file) file.basename(".rb").to_s diff --git a/Library/Homebrew/tap_auditor.rb b/Library/Homebrew/tap_auditor.rb index d8294815f2..17be78d11c 100644 --- a/Library/Homebrew/tap_auditor.rb +++ b/Library/Homebrew/tap_auditor.rb @@ -15,13 +15,14 @@ module Homebrew @name = tap.name @path = tap.path @tap_audit_exceptions = tap.audit_exceptions + @tap_formula_lists = tap.formula_lists @problems = [] end sig { void } def audit audit_json_files - audit_tap_audit_exceptions + audit_tap_formula_lists end sig { void } @@ -35,32 +36,38 @@ module Homebrew end sig { void } - def audit_tap_audit_exceptions - @tap_audit_exceptions.each do |list_name, formula_names| - unless [Hash, Array].include? formula_names.class + def audit_tap_formula_lists + tap_lists = { + audit_exceptions: @tap_audit_exceptions, + formula_lists: @tap_formula_lists, + } + tap_lists.each do |list_directory, list| + list.each do |list_name, formula_names| + unless [Hash, Array].include? formula_names.class + problem <<~EOS + #{list_directory}/#{list_name}.json should contain a JSON array + of formula names or a JSON object mapping formula names to values + EOS + next + end + + formula_names = formula_names.keys if formula_names.is_a? Hash + + invalid_formulae = [] + formula_names.each do |name| + invalid_formulae << name if Formula[name].tap != @name + rescue FormulaUnavailableError + invalid_formulae << name + end + + next if invalid_formulae.empty? + problem <<~EOS - audit_exceptions/#{list_name}.json should contain a JSON array - of formula names or a JSON object mapping formula names to values + #{list_directory}/#{list_name}.json references + formulae that are not found in the #{@name} tap. + Invalid formulae: #{invalid_formulae.join(", ")} EOS - next end - - formula_names = formula_names.keys if formula_names.is_a? Hash - - invalid_formulae = [] - formula_names.each do |name| - invalid_formulae << name if Formula[name].tap != @name - rescue FormulaUnavailableError - invalid_formulae << name - end - - next if invalid_formulae.empty? - - problem <<~EOS - audit_exceptions/#{list_name}.json references - formulae that are not found in the #{@name} tap. - Invalid formulae: #{invalid_formulae.join(", ")} - EOS end end diff --git a/Library/Homebrew/utils/pypi.rb b/Library/Homebrew/utils/pypi.rb index 292f827ab0..ad75aa6f0e 100644 --- a/Library/Homebrew/utils/pypi.rb +++ b/Library/Homebrew/utils/pypi.rb @@ -26,8 +26,9 @@ module PyPI url end - # Get name, URL and SHA-256 checksum for a given PyPI package. - def get_pypi_info(package, version) + # Get name, URL, SHA-256 checksum, and latest version for a given PyPI package. + def get_pypi_info(package, version = nil) + package = package.split("[").first metadata_url = if version.present? "https://pypi.org/pypi/#{package}/#{version}/json" else @@ -46,15 +47,15 @@ module PyPI sdist = json["urls"].find { |url| url["packagetype"] == "sdist" } return json["info"]["name"] if sdist.nil? - [json["info"]["name"], sdist["url"], sdist["digests"]["sha256"]] + [json["info"]["name"], sdist["url"], sdist["digests"]["sha256"], json["info"]["version"]] end # Return true if resources were checked (even if no change). def update_python_resources!(formula, version: nil, package_name: nil, extra_packages: nil, exclude_packages: nil, print_only: false, silent: false, ignore_non_pypi_packages: false) - auto_update_list = formula.tap.audit_exceptions[:automatic_resource_update_list] - if package_name.blank? && extra_packages.blank? && !print_only && + auto_update_list = formula.tap.formula_lists[:pypi_automatic_resource_update_list] + if package_name.blank? && extra_packages.blank? && exclude_packages.blank? && !print_only && auto_update_list.present? && auto_update_list.key?(formula.full_name) list_entry = auto_update_list[formula.full_name] @@ -70,18 +71,12 @@ module PyPI end end + version ||= formula.version if package_name.blank? package_name ||= url_to_pypi_package_name formula.stable.url - version ||= formula.version extra_packages ||= [] exclude_packages ||= [] - # opoo "package_name: #{package_name}" - # opoo "version: #{version}" - # opoo "extra_packages: #{extra_packages}" - # opoo "exclude_packages: #{exclude_packages}" - # odie "" - - if package_name.nil? + if package_name.blank? return if ignore_non_pypi_packages odie <<~EOS @@ -140,7 +135,7 @@ module PyPI EOS end - found_packages.merge!(JSON.parse(pipgrip_output).sort.to_h) do |conflicting_package, old_version, new_version| + found_packages.merge!(JSON.parse(pipgrip_output).to_h) do |conflicting_package, old_version, new_version| next old_version if old_version == new_version odie "Conflicting versions found for the `#{conflicting_package}` resource: #{old_version}, #{new_version}" @@ -148,11 +143,11 @@ module PyPI end # Remove extra packages that may be included in pipgrip output - exclude_list = %W[#{package_name.downcase} argparse pip setuptools wheel wsgiref] + exclude_list = %W[#{package_name.split("[").first.downcase} argparse pip setuptools wheel wsgiref] found_packages.delete_if { |package| exclude_list.include? package } new_resource_blocks = "" - found_packages.each do |package, package_version| + found_packages.sort.each do |package, package_version| if exclude_packages.include? package ohai "Excluding \"#{package}==#{package_version}\"" if !print_only && !silent next