From cd6777fc7323df277213f220cfe5f3e21779fe28 Mon Sep 17 00:00:00 2001 From: Eric Knibbe Date: Fri, 30 May 2025 16:42:32 -0400 Subject: [PATCH 01/34] audits: quote and reword problem description text --- Library/Homebrew/formula_auditor.rb | 44 +++---- Library/Homebrew/resource_auditor.rb | 16 +-- Library/Homebrew/rubocops/caveats.rb | 2 +- Library/Homebrew/rubocops/checksum.rb | 8 +- Library/Homebrew/rubocops/class.rb | 6 +- Library/Homebrew/rubocops/components_order.rb | 4 +- .../rubocops/components_redundancy.rb | 2 +- Library/Homebrew/rubocops/dependency_order.rb | 4 +- Library/Homebrew/rubocops/lines.rb | 107 +++++++++--------- Library/Homebrew/rubocops/options.rb | 2 +- Library/Homebrew/rubocops/patches.rb | 8 +- .../Homebrew/rubocops/shared/desc_helper.rb | 4 +- .../rubocops/shared/homepage_helper.rb | 13 +-- .../shared/on_system_conditionals_helper.rb | 11 +- .../Homebrew/rubocops/shared/url_helper.rb | 42 +++---- Library/Homebrew/rubocops/text.rb | 12 +- Library/Homebrew/rubocops/urls.rb | 8 +- Library/Homebrew/rubocops/uses_from_macos.rb | 4 +- Library/Homebrew/rubocops/version.rb | 6 +- Library/Homebrew/test/formula_auditor_spec.rb | 26 ++--- .../cask/on_system_conditionals_spec.rb | 18 +-- .../Homebrew/test/rubocops/caveats_spec.rb | 2 +- .../rubocops/checksum/checksum_case_spec.rb | 6 +- .../test/rubocops/checksum/checksum_spec.rb | 16 +-- .../test/rubocops/class/class_name_spec.rb | 6 +- .../Homebrew/test/rubocops/class/test_spec.rb | 18 +-- .../test/rubocops/components_order_spec.rb | 22 ++-- .../test/rubocops/dependency_order_spec.rb | 32 +++--- Library/Homebrew/test/rubocops/desc_spec.rb | 4 +- .../Homebrew/test/rubocops/homepage_spec.rb | 16 +-- .../test/rubocops/lines/quictls_check_spec.rb | 2 +- .../Homebrew/test/rubocops/options_spec.rb | 2 +- .../Homebrew/test/rubocops/patches_spec.rb | 10 +- .../test/rubocops/provided_by_macos_spec.rb | 2 +- .../test/rubocops/shell_commands_spec.rb | 20 ++-- .../test/rubocops/text/miscellaneous_spec.rb | 60 +++++----- .../test/rubocops/text/mpi_check_spec.rb | 2 +- .../text/on_system_conditionals_spec.rb | 42 +++---- .../rubocops/text/option_declarations_spec.rb | 12 +- .../rubocops/text/shell_variables_spec.rb | 10 +- .../test/rubocops/text/std_npm_args_spec.rb | 6 +- .../test/rubocops/text/strict_spec.rb | 48 ++++---- Library/Homebrew/test/rubocops/text_spec.rb | 18 +-- .../Homebrew/test/rubocops/urls/git_spec.rb | 4 +- .../test/rubocops/urls/git_strict_spec.rb | 4 +- .../Homebrew/test/rubocops/urls/pypi_spec.rb | 4 +- Library/Homebrew/test/rubocops/urls_spec.rb | 57 +++++----- .../test/rubocops/uses_from_macos_spec.rb | 6 +- .../Homebrew/test/rubocops/version_spec.rb | 6 +- 49 files changed, 390 insertions(+), 394 deletions(-) diff --git a/Library/Homebrew/formula_auditor.rb b/Library/Homebrew/formula_auditor.rb index b08a3c013c..4aa06f0bf6 100644 --- a/Library/Homebrew/formula_auditor.rb +++ b/Library/Homebrew/formula_auditor.rb @@ -114,7 +114,7 @@ module Homebrew ln -s #{formula.path.to_s.gsub(formula.tap.path, "..")} #{alias_name} EOS else - problem "Formula has other versions so create an alias named #{alias_name}." + problem "Formula has other versions so create an alias named '#{alias_name}'." end end @@ -153,7 +153,7 @@ module Homebrew next if synced_formula == name if (synced_version = Formulary.factory(synced_formula).version) != version - problem "Version of `#{synced_formula}` (#{synced_version}) should match version of `#{name}` (#{version})" + problem "Version of #{synced_formula} (#{synced_version}) should match version of #{name} (#{version})" end end @@ -188,7 +188,7 @@ module Homebrew return if formula.core_formula? return unless Formula.core_names.include?(name) - problem "Formula name conflicts with existing core formula." + problem "Formula name conflicts with an existing formula in homebrew/core." end PERMITTED_LICENSE_MISMATCHES = { @@ -226,7 +226,7 @@ module Homebrew problem <<~EOS Formula #{formula.name} contains incompatible licenses: #{incompatible_licenses}. Formulae in homebrew/core must either use a Debian Free Software Guidelines license - or be released into the public domain. See #{Formatter.url("https://docs.brew.sh/License-Guidelines")} + or be released into the public domain: #{Formatter.url("https://docs.brew.sh/License-Guidelines")} EOS end @@ -327,7 +327,7 @@ module Homebrew end end - problem "Dependency '#{dep}' does not define option #{opt.name.inspect}" + problem "Dependency '#{dep}' does not define option: #{opt.name.inspect}" end problem "Don't use 'git' as a dependency (it's always available)" if @new_formula && dep.name == "git" @@ -448,7 +448,7 @@ module Homebrew if T.must(tap).formula_renames.key?(conflict.name) || T.must(tap).aliases.include?(conflict.name) problem "Formula conflict should be declared using " \ - "canonical name (#{conflicting_formula.name}) instead of #{conflict.name}" + "canonical name (#{conflicting_formula.name}) instead of '#{conflict.name}'" end reverse_conflict_found = T.let(false, T::Boolean) @@ -457,7 +457,7 @@ module Homebrew if T.must(tap).formula_renames.key?(reverse_conflict.name) || T.must(tap).aliases.include?(reverse_conflict.name) problem "Formula #{conflicting_formula.name} conflict should be declared using " \ - "canonical name (#{reverse_conflict_formula.name}) instead of #{reverse_conflict.name}" + "canonical name (#{reverse_conflict_formula.name}) instead of '#{reverse_conflict.name}'" end reverse_conflict_found ||= reverse_conflict_formula == formula @@ -651,7 +651,7 @@ module Homebrew metadata = SharedAudits.github_repo_data(user, repo) return if metadata.nil? - problem "GitHub repo is archived" if metadata["archived"] + problem "GitHub repository is archived" if metadata["archived"] end def audit_gitlab_repository_archived @@ -663,7 +663,7 @@ module Homebrew metadata = SharedAudits.gitlab_repo_data(user, repo) return if metadata.nil? - problem "GitLab repo is archived" if metadata["archived"] + problem "GitLab repository is archived" if metadata["archived"] end def audit_github_repository @@ -712,7 +712,7 @@ module Homebrew end def audit_specs - problem "Head-only (no stable download)" if head_only?(formula) + problem "HEAD-only (no stable download)" if head_only?(formula) %w[Stable HEAD].each do |name| spec_name = name.downcase.to_sym @@ -759,7 +759,7 @@ module Homebrew if formula.head && @versioned_formula && !formula.tap&.audit_exception(:versioned_head_spec_allowlist, formula.name) - problem "Versioned formulae should not have a `HEAD` spec" + problem "Versioned formulae should not have a `head` spec" end stable = formula.stable @@ -771,7 +771,7 @@ module Homebrew stable_version_string = version.to_s if stable_version_string.start_with?("HEAD") - problem "Stable: non-HEAD version name (#{stable_version_string}) should not begin with HEAD" + problem "Stable: non-HEAD version (#{stable_version_string}) should not begin with `HEAD`" end stable_url_version = Version.parse(stable.url) @@ -790,7 +790,7 @@ module Homebrew return if formula.tap&.audit_exception :unstable_allowlist, formula.name, version_prefix return if formula.tap&.audit_exception :unstable_devel_allowlist, formula.name, version_prefix - problem "Stable version URLs should not contain #{matched}" + problem "Stable: version URLs should not contain `#{matched}`" when %r{download\.gnome\.org/sources}, %r{ftp\.gnome\.org/pub/GNOME/sources}i version_prefix = stable.version.major_minor return if formula.tap&.audit_exception :gnome_devel_allowlist, formula.name, version_prefix @@ -800,11 +800,11 @@ module Homebrew return if stable_url_version >= Version.new("40.0") return if stable_url_minor_version.even? - problem "#{stable.version} is a development release" + problem "Stable: version (#{stable.version}) is a development release" when %r{isc.org/isc/bind\d*/}i return if stable_url_minor_version.even? - problem "#{stable.version} is a development release" + problem "Stable: version (#{stable.version}) is a development release" when %r{https?://gitlab\.com/([\w-]+)/([\w-]+)} owner = T.must(Regexp.last_match(1)) @@ -845,7 +845,7 @@ module Homebrew if !newest_committed[:version].nil? && current_version < newest_committed[:version] && current_version_scheme == previous_committed[:version_scheme] - problem "stable version should not decrease (from #{newest_committed[:version]} to #{current_version})" + problem "Stable: version should not decrease (from #{newest_committed[:version]} to #{current_version})" end end @@ -867,14 +867,14 @@ module Homebrew !current_revision.zero? && current_revision == newest_committed[:revision] && current_revision == previous_committed[:revision] - problem "'revision #{current_revision}' should be removed" + problem "`revision #{current_revision}` should be removed" elsif current_version == previous_committed[:version] && !previous_committed[:revision].nil? && current_revision < previous_committed[:revision] - problem "revision should not decrease (from #{previous_committed[:revision]} to #{current_revision})" + problem "`revision` should not decrease (from #{previous_committed[:revision]} to #{current_revision})" elsif newest_committed[:revision] && current_revision > (newest_committed[:revision] + 1) - problem "revisions should only increment by 1" + problem "`revision` should only increment by 1" end end @@ -891,10 +891,10 @@ module Homebrew return if previous_committed[:version_scheme].nil? if current_version_scheme < previous_committed[:version_scheme] - problem "version_scheme should not decrease (from #{previous_committed[:version_scheme]} " \ + problem "`version_scheme` should not decrease (from #{previous_committed[:version_scheme]} " \ "to #{current_version_scheme})" elsif current_version_scheme > (previous_committed[:version_scheme] + 1) - problem "version_schemes should only increment by 1" + problem "`version_scheme` should only increment by 1" end end @@ -935,7 +935,7 @@ module Homebrew bin_names.each do |name| shell_commands.each do |cmd| if text.to_s.match?(/test do.*#{cmd}[(\s]+['"]#{Regexp.escape(name)}[\s'"]/m) - problem %Q(fully scope test #{cmd} calls, e.g. #{cmd} "\#{bin}/#{name}") + problem %Q(Fully scope test `#{cmd}` calls, e.g.: #{cmd} "\#{bin}/#{name}") end end end diff --git a/Library/Homebrew/resource_auditor.rb b/Library/Homebrew/resource_auditor.rb index 8e8a856d72..77216138e6 100644 --- a/Library/Homebrew/resource_auditor.rb +++ b/Library/Homebrew/resource_auditor.rb @@ -63,7 +63,7 @@ module Homebrew url_strategy = DownloadStrategyDetector.detect(url) if (using == :git || url_strategy == GitDownloadStrategy) && specs[:tag] && !specs[:revision] - problem "Git should specify :revision when a :tag is specified." + problem "Git should specify `revision:` when a `tag:` is specified." end return unless using @@ -71,7 +71,7 @@ module Homebrew if using == :cvs mod = specs[:module] - problem "Redundant :module value in URL" if mod == name + problem "Redundant `module:` value in URL" if mod == name if url.match?(%r{:[^/]+$}) mod = url.split(":").last @@ -79,14 +79,14 @@ module Homebrew if mod == name problem "Redundant CVS module appended to URL" else - problem "Specify CVS module as `:module => \"#{mod}\"` instead of appending it to the URL" + problem "Specify CVS module as `module: \"#{mod}\"` instead of appending it to the URL" end end end return if url_strategy != DownloadStrategyDetector.detect("", using) - problem "Redundant :using value in URL" + problem "Redundant `using:` value in URL" end def audit_checksum @@ -125,7 +125,7 @@ module Homebrew return if name.casecmp(pypi_package_name).zero? - problem "resource name should be `#{pypi_package_name}` to match the PyPI package name" + problem "`resource` name should be '#{pypi_package_name}' to match the PyPI package name" end def audit_urls @@ -166,12 +166,12 @@ module Homebrew remote_exists = Utils::Git.remote_exists?(url) attempts += 1 end - problem "The URL #{url} is not a valid git URL" unless remote_exists + problem "The URL #{url} is not a valid Git URL" unless remote_exists elsif strategy <= SubversionDownloadStrategy next unless DevelopmentTools.subversion_handles_most_https_certificates? next unless Utils::Svn.available? - problem "The URL #{url} is not a valid svn URL" unless Utils::Svn.remote_exists? url + problem "The URL #{url} is not a valid SVN URL" unless Utils::Svn.remote_exists? url end end end @@ -188,7 +188,7 @@ module Homebrew .match(%r{ref: refs/heads/(.*?)\s+HEAD})&.to_a&.second return if branch.blank? || branch == specs[:branch] - problem "Use `branch: \"#{branch}\"` to specify the default branch" + problem "Specify the default branch as `branch: \"#{branch}\"`" end def problem(text) diff --git a/Library/Homebrew/rubocops/caveats.rb b/Library/Homebrew/rubocops/caveats.rb index 99ae5b826b..8d228e10fa 100644 --- a/Library/Homebrew/rubocops/caveats.rb +++ b/Library/Homebrew/rubocops/caveats.rb @@ -30,7 +30,7 @@ module RuboCop def audit_formula(_formula_nodes) caveats_strings.each do |n| if regex_match_group(n, /\bsetuid\b/i) - problem "Don't recommend `setuid` in the caveats, suggest `sudo` instead." + problem "Instead of recommending `setuid` in the caveats, suggest `sudo`." end problem "Don't use ANSI escape codes in the caveats." if regex_match_group(n, /\e/) diff --git a/Library/Homebrew/rubocops/checksum.rb b/Library/Homebrew/rubocops/checksum.rb index 44d749db0d..e2040ec606 100644 --- a/Library/Homebrew/rubocops/checksum.rb +++ b/Library/Homebrew/rubocops/checksum.rb @@ -28,17 +28,17 @@ module RuboCop return if checksum.nil? if regex_match_group(checksum, /^$/) - problem "sha256 is empty" + problem "`sha256` is empty" return end if string_content(checksum).size != 64 && regex_match_group(checksum, /^\w*$/) - problem "sha256 should be 64 characters" + problem "`sha256` should be 64 characters" end return unless regex_match_group(checksum, /[^a-f0-9]+/i) - add_offense(T.must(@offensive_source_range), message: "sha256 contains invalid characters") + add_offense(T.must(@offensive_source_range), message: "`sha256` contains invalid characters") end end @@ -54,7 +54,7 @@ module RuboCop next if checksum.nil? next unless regex_match_group(checksum, /[A-F]+/) - add_offense(@offensive_source_range, message: "sha256 should be lowercase") do |corrector| + add_offense(@offensive_source_range, message: "`sha256` should be lowercase") do |corrector| correction = T.must(@offensive_node).source.downcase corrector.insert_before(T.must(@offensive_node).source_range, correction) corrector.remove(T.must(@offensive_node).source_range) diff --git a/Library/Homebrew/rubocops/class.rb b/Library/Homebrew/rubocops/class.rb index 2088ef1a59..d2b46d8faa 100644 --- a/Library/Homebrew/rubocops/class.rb +++ b/Library/Homebrew/rubocops/class.rb @@ -23,7 +23,7 @@ module RuboCop parent_class = class_name(parent_class_node) return unless DEPRECATED_CLASSES.include?(parent_class) - problem "#{parent_class} is deprecated, use Formula instead" do |corrector| + problem "`#{parent_class}` is deprecated, use `Formula` instead" do |corrector| corrector.replace(parent_class_node.source_range, "Formula") end end @@ -49,14 +49,14 @@ module RuboCop p1, p2 = params if (match = string_content(p1).match(%r{(/usr/local/(s?bin))})) offending_node(p1) - problem "use \#{#{match[2]}} instead of #{match[1]} in #{node}" do |corrector| + problem "Use `\#{#{match[2]}}` instead of `#{match[1]}` in `#{node}`" do |corrector| corrector.replace(p1.source_range, p1.source.sub(match[1], "\#{#{match[2]}}")) end end if node == :shell_output && node_equals?(p2, 0) offending_node(p2) - problem "Passing 0 to shell_output() is redundant" do |corrector| + problem "Passing 0 to `shell_output` is redundant" do |corrector| corrector.remove(range_with_surrounding_comma(range_with_surrounding_space(range: p2.source_range, side: :left))) end diff --git a/Library/Homebrew/rubocops/components_order.rb b/Library/Homebrew/rubocops/components_order.rb index 14ccb3973e..7b6fc8c8ba 100644 --- a/Library/Homebrew/rubocops/components_order.rb +++ b/Library/Homebrew/rubocops/components_order.rb @@ -39,7 +39,7 @@ module RuboCop if on_method_blocks.length > 1 @offensive_node = on_method_blocks.second - problem "there can only be one `#{on_method}` block in a formula." + problem "There can only be one `#{on_method}` block in a formula." end check_on_system_block_content(component_precedence_list, on_method_blocks.first) @@ -112,7 +112,7 @@ module RuboCop on_system_blocks.each do |on_method, blocks| if blocks.length > 1 - problem "there can only be one `#{on_method}` block in a resource block." + problem "There can only be one `#{on_method}` block in a resource block." next end end diff --git a/Library/Homebrew/rubocops/components_redundancy.rb b/Library/Homebrew/rubocops/components_redundancy.rb index 50557ab187..724f0af7bf 100644 --- a/Library/Homebrew/rubocops/components_redundancy.rb +++ b/Library/Homebrew/rubocops/components_redundancy.rb @@ -32,7 +32,7 @@ module RuboCop url_args = arg.keys.each.map(&:value) if method_called?(body_node, :sha256) && url_args.include?(:tag) && url_args.include?(:revision) - problem "Do not use both sha256 and tag/revision." + problem "Do not use both `sha256` and `tag:`/`revision:`." end end end diff --git a/Library/Homebrew/rubocops/dependency_order.rb b/Library/Homebrew/rubocops/dependency_order.rb index 3f9a343d6d..92ea918d88 100644 --- a/Library/Homebrew/rubocops/dependency_order.rb +++ b/Library/Homebrew/rubocops/dependency_order.rb @@ -108,8 +108,8 @@ module RuboCop offending_node(node_1) - problem "dependency \"#{dependency_name(node_1)}\" (line #{l1}) should be put before dependency " \ - "\"#{dependency_name(node_2)}\" (line #{l2})" do |corrector| + problem "`dependency \"#{dependency_name(node_1)}\"` (line #{l1}) should be put before " \ + "`dependency \"#{dependency_name(node_2)}\"` (line #{l2})" do |corrector| indentation = " " * (start_column(node_2) - line_start_column(node_2)) line_breaks = "\n" corrector.insert_before(node_2.source_range, diff --git a/Library/Homebrew/rubocops/lines.rb b/Library/Homebrew/rubocops/lines.rb index 698aee4fc1..c3b0c578e5 100644 --- a/Library/Homebrew/rubocops/lines.rb +++ b/Library/Homebrew/rubocops/lines.rb @@ -165,41 +165,42 @@ module RuboCop next unless unless_modifier?(method.parent) correct = method.source.gsub("out?", "?") - problem "Use if #{correct} instead of unless #{method.source}" + problem "Use `if #{correct}` instead of `unless #{method.source}`" end find_instance_method_call(body_node, :build, :with?) do |method| next unless unless_modifier?(method.parent) correct = method.source.gsub("?", "out?") - problem "Use if #{correct} instead of unless #{method.source}" + problem "Use `if #{correct}` instead of `unless #{method.source}`" end find_instance_method_call(body_node, :build, :with?) do |method| next unless expression_negated?(method) - problem "Don't negate 'build.with?': use 'build.without?'" + problem "Instead of negating `build.with?`, use `build.without?`" end find_instance_method_call(body_node, :build, :without?) do |method| next unless expression_negated?(method) - problem "Don't negate 'build.without?': use 'build.with?'" + problem "Instead of negating `build.without?`, use `build.with?`" end find_instance_method_call(body_node, :build, :without?) do |method| arg = parameters(method).first next unless (match = regex_match_group(arg, /^-?-?without-(.*)/)) - problem "Don't duplicate 'without': " \ - "Use `build.without? \"#{match[1]}\"` to check for \"--without-#{match[1]}\"" + problem "Instead of duplicating `without`, " \ + "use `build.without? \"#{match[1]}\"` to check for \"--without-#{match[1]}\"" end find_instance_method_call(body_node, :build, :with?) do |method| arg = parameters(method).first next unless (match = regex_match_group(arg, /^-?-?with-(.*)/)) - problem "Don't duplicate 'with': Use `build.with? \"#{match[1]}\"` to check for \"--with-#{match[1]}\"" + problem "Instead of duplicating `with`, " \ + "use `build.with? \"#{match[1]}\"` to check for '--with-#{match[1]}'" end find_instance_method_call(body_node, :build, :include?) do @@ -234,8 +235,8 @@ module RuboCop return if formula_tap != "homebrew-core" find_method_with_args(body_node, :depends_on, "mpich") do - problem "Formulae in homebrew/core should use 'depends_on \"open-mpi\"' " \ - "instead of '#{T.must(@offensive_node).source}'." do |corrector| + problem "Formulae in homebrew/core should use `depends_on \"open-mpi\"` " \ + "instead of `#{T.must(@offensive_node).source}`." do |corrector| corrector.replace(T.must(@offensive_node).source_range, "depends_on \"open-mpi\"") end end @@ -252,15 +253,15 @@ module RuboCop return if (body_node = formula_nodes.body_node).nil? find_method_with_args(body_node, :local_npm_install_args) do - problem "Use 'std_npm_args' instead of '#{T.cast(@offensive_node, - RuboCop::AST::SendNode).method_name}'." do |corrector| + problem "Use `std_npm_args` instead of `#{T.cast(@offensive_node, + RuboCop::AST::SendNode).method_name}`." do |corrector| corrector.replace(T.must(@offensive_node).source_range, "std_npm_args(prefix: false)") end end find_method_with_args(body_node, :std_npm_install_args) do |method| - problem "Use 'std_npm_args' instead of '#{T.cast(@offensive_node, - RuboCop::AST::SendNode).method_name}'." do |corrector| + problem "Use `std_npm_args` instead of `#{T.cast(@offensive_node, + RuboCop::AST::SendNode).method_name}`." do |corrector| if (param = parameters(method).first.source) == "libexec" corrector.replace(T.must(@offensive_node).source_range, "std_npm_args") else @@ -293,8 +294,8 @@ module RuboCop return if formula_tap != "homebrew-core" find_method_with_args(body_node, :depends_on, "quictls") do - problem "Formulae in homebrew/core should use 'depends_on \"openssl@3\"' " \ - "instead of '#{T.must(@offensive_node).source}'." do |corrector| + problem "Formulae in homebrew/core should use `depends_on \"openssl@3\"` " \ + "instead of `#{T.must(@offensive_node).source}`." do |corrector| corrector.replace(T.must(@offensive_node).source_range, "depends_on \"openssl@3\"") end end @@ -311,7 +312,7 @@ module RuboCop return if formula_tap != "homebrew-core" return unless depends_on?("pyoxidizer") - problem "Formulae in homebrew/core should not use '#{T.must(@offensive_node).source}'." + problem "Formulae in homebrew/core should not use `#{T.must(@offensive_node).source}`." end end @@ -505,7 +506,7 @@ module RuboCop end end - # This cop makes sure the `MacOS` module is not used in Linux-facing formula code + # This cop makes sure the `MacOS` module is not used in Linux-facing formula code. class MacOSOnLinux < FormulaCop include OnSystemConditionalsHelper @@ -676,7 +677,7 @@ module RuboCop # FileUtils is included in Formula # encfs modifies a file with this name, so check for some leading characters find_instance_method_call(body_node, "FileUtils", nil) do |method_node| - problem "Don't need 'FileUtils.' before #{method_node.method_name}" + problem "No need for `FileUtils.` before `#{method_node.method_name}`" end # Check for long inreplace block vars @@ -684,45 +685,41 @@ module RuboCop block_arg = node.arguments.children.first next if block_arg.source.size <= 1 - problem "\"inreplace do |s|\" is preferred over \"|#{block_arg.source}|\"." + problem "`inreplace do |s|` is preferred over `|#{block_arg.source}|`." end [:rebuild, :version_scheme].each do |method_name| find_method_with_args(body_node, method_name, 0) do - problem "'#{method_name} 0' should be removed" + problem "`#{method_name} 0` should be removed" end end find_instance_call(body_node, "ARGV") do |_method_node| - problem "Use build instead of ARGV to check options" + problem "Use `build.with?` or `build.without?` instead of `ARGV` to check options" end find_instance_method_call(body_node, :man, :+) do |method| next unless (match = regex_match_group(parameters(method).first, /^man[1-8]$/)) - problem "\"#{method.source}\" should be \"#{match[0]}\"" + problem "`#{method.source}` should be `#{match[0]}`" end # Avoid hard-coding compilers find_every_method_call_by_name(body_node, :system).each do |method| - next if @formula_name == "bazel" # TODO: Remove shim bypass in bazel. - param = parameters(method).first if (match = regex_match_group(param, %r{^(/usr/bin/)?(gcc|clang|cc|c[89]9)(\s|$)})) - problem "Use \"\#{ENV.cc}\" instead of hard-coding \"#{match[2]}\"" + problem "Use `\#{ENV.cc}` instead of hard-coding `#{match[2]}`" elsif (match = regex_match_group(param, %r{^(/usr/bin/)?((g|clang|c)\+\+)(\s|$)})) - problem "Use \"\#{ENV.cxx}\" instead of hard-coding \"#{match[2]}\"" + problem "Use `\#{ENV.cxx}` instead of hard-coding `#{match[2]}`" end end find_instance_method_call(body_node, "ENV", :[]=) do |method| - next if @formula_name == "bazel" # TODO: Remove shim bypass in bazel. - param = parameters(method)[1] if (match = regex_match_group(param, %r{^(/usr/bin/)?(gcc|clang|cc|c[89]9)(\s|$)})) - problem "Use \"\#{ENV.cc}\" instead of hard-coding \"#{match[2]}\"" + problem "Use `\#{ENV.cc}` instead of hard-coding `#{match[2]}`" elsif (match = regex_match_group(param, %r{^(/usr/bin/)?((g|clang|c)\+\+)(\s|$)})) - problem "Use \"\#{ENV.cxx}\" instead of hard-coding \"#{match[2]}\"" + problem "Use `\#{ENV.cxx}` instead of hard-coding `#{match[2]}`" end end @@ -730,18 +727,18 @@ module RuboCop formula_path_strings(body_node, :share) do |p| next unless (match = regex_match_group(p, %r{^(/(man))/?})) - problem "\"\#{share}#{match[1]}\" should be \"\#{#{match[2]}}\"" + problem "`\#{share}#{match[1]}` should be `\#{#{match[2]}}`" end formula_path_strings(body_node, :prefix) do |p| if (match = regex_match_group(p, %r{^(/share/(info|man))$})) - problem ['"#', "{prefix}", match[1], '" should be "#{', match[2], '}"'].join + problem ["`#", "{prefix}", match[1], '` should be `#{', match[2], "}`"].join end if (match = regex_match_group(p, %r{^((/share/man/)(man[1-8]))})) - problem ['"#', "{prefix}", match[1], '" should be "#{', match[3], '}"'].join + problem ["`#", "{prefix}", match[1], '` should be `#{', match[3], "}`"].join end if (match = regex_match_group(p, %r{^(/(bin|include|libexec|lib|sbin|share|Frameworks))}i)) - problem ['"#', "{prefix}", match[1], '" should be "#{', match[2].downcase, '}"'].join + problem ["`#", "{prefix}", match[1], '` should be `#{', match[2].downcase, "}`"].join end end @@ -750,13 +747,13 @@ module RuboCop next if key.nil? || value.nil? next unless (match = regex_match_group(value, /^(lua|perl|python|ruby)(\d*)/)) - problem "#{match[1]} modules should be vendored rather than use deprecated `#{method.source}`" + problem "#{match[1]} modules should be vendored rather than using deprecated `#{method.source}`" end find_every_method_call_by_name(body_node, :system).each do |method| next unless (match = regex_match_group(parameters(method).first, /^(env|export)(\s+)?/)) - problem "Use ENV instead of invoking '#{match[1]}' to modify the environment" + problem "Use `ENV` instead of invoking `#{match[1]}` to modify the environment" end find_every_method_call_by_name(body_node, :depends_on).each do |method| @@ -768,7 +765,7 @@ module RuboCop find_strings(option).each do |dependency| next unless (match = regex_match_group(dependency, /(with(out)?-\w+|c\+\+11)/)) - problem "Dependency #{string_content(dep)} should not use option #{match[0]}" + problem "Dependency '#{string_content(dep)}' should not use option `#{match[0]}`" end end end @@ -776,21 +773,21 @@ module RuboCop find_instance_method_call(body_node, :version, :==) do |method| next unless parameters_passed?(method, ["HEAD"]) - problem "Use 'build.head?' instead of inspecting 'version'" + problem "Use `build.head?` instead of inspecting `version`" end find_instance_method_call(body_node, "ARGV", :include?) do |method| next unless parameters_passed?(method, ["--HEAD"]) - problem "Use \"if build.head?\" instead" + problem "Use `if build.head?` instead" end find_const(body_node, "MACOS_VERSION") do - problem "Use MacOS.version instead of MACOS_VERSION" + problem "Use `MacOS.version` instead of `MACOS_VERSION`" end find_const(body_node, "MACOS_FULL_VERSION") do - problem "Use MacOS.full_version instead of MACOS_FULL_VERSION" + problem "Use `MacOS.full_version` instead of `MACOS_FULL_VERSION`" end conditional_dependencies(body_node) do |node, method, param, dep_node| @@ -799,30 +796,30 @@ module RuboCop if (method == :include? && regex_match_group(param, /^with-#{dep}$/)) || (method == :with? && regex_match_group(param, /^#{dep}$/)) offending_node(dep_node.parent) - problem "Replace #{node.source} with #{dep_node.parent.source} => :optional" + problem "Replace `#{node.source}` with `#{dep_node.parent.source} => :optional`" end elsif node.unless? if (method == :include? && regex_match_group(param, /^without-#{dep}$/)) || (method == :without? && regex_match_group(param, /^#{dep}$/)) offending_node(dep_node.parent) - problem "Replace #{node.source} with #{dep_node.parent.source} => :recommended" + problem "Replace `#{node.source}` with `#{dep_node.parent.source} => :recommended`" end end end find_method_with_args(body_node, :fails_with, :llvm) do - problem "'fails_with :llvm' is now a no-op so should be removed" + problem "`fails_with :llvm` is now a no-op and should be removed" end find_method_with_args(body_node, :needs, :openmp) do - problem "'needs :openmp' should be replaced with 'depends_on \"gcc\"'" + problem "`needs :openmp` should be replaced with `depends_on \"gcc\"`" end find_method_with_args(body_node, :system, /^(otool|install_name_tool|lipo)/) do problem "Use ruby-macho instead of calling #{T.must(@offensive_node).source}" end - problem "Use new-style test definitions (test do)" if find_method_def(body_node, :test) + problem "Use new-style test definitions (`test do`)" if find_method_def(body_node, :test) find_method_with_args(body_node, :skip_clean, :all) do problem "`skip_clean :all` is deprecated; brew no longer strips symbols. " \ @@ -830,7 +827,7 @@ module RuboCop end if find_method_def(processed_source.ast) - problem "Define method #{method_name(@offensive_node)} in the class body, not at the top-level" + problem "Define method `#{method_name(@offensive_node)}` in the class body, not at the top-level" end find_instance_method_call(body_node, :build, :universal?) do @@ -849,7 +846,7 @@ module RuboCop next if tap_style_exception? :runtime_cpu_detection_allowlist problem "Formulae should be verified as having support for runtime hardware detection before " \ - "using ENV.runtime_cpu_detection." + "using `ENV.runtime_cpu_detection`." end find_every_method_call_by_name(body_node, :depends_on).each do |method| @@ -864,7 +861,7 @@ module RuboCop param = parameters(method).first next unless node_equals?(param, "CI") - problem 'Don\'t use ENV["CI"] for Homebrew CI checks.' + problem 'Don\'t use `ENV["CI"]` for Homebrew CI checks.' end find_instance_method_call(body_node, "Dir", :[]) do |method| @@ -874,7 +871,7 @@ module RuboCop next unless path.str_type? next unless (match = regex_match_group(path, /^[^*{},]+$/)) - problem "Dir([\"#{string_content(path)}\"]) is unnecessary; just use \"#{match[0]}\"" + problem "`Dir([\"#{string_content(path)}\"])` is unnecessary; just use `#{match[0]}`" end fileutils_methods = Regexp.new( @@ -946,7 +943,7 @@ module RuboCop end end - # This cop ensures that new formulae depending on removed Requirements are not used + # This cop ensures that new formulae depending on removed Requirements are not used. class Requirements < FormulaCop sig { override.params(_formula_nodes: FormulaNodes).void } def audit_formula(_formula_nodes) @@ -969,16 +966,16 @@ module RuboCop return if formula_tap != "homebrew-core" find_method_with_args(body_node, :depends_on, "rustup") do - problem "Formulae in homebrew/core should use 'depends_on \"rust\"' " \ - "instead of '#{T.must(@offensive_node).source}'." do |corrector| + problem "Formulae in homebrew/core should use `depends_on \"rust\"` " \ + "instead of `#{T.must(@offensive_node).source}`." do |corrector| corrector.replace(T.must(@offensive_node).source_range, "depends_on \"rust\"") end end [:build, [:build, :test], [:test, :build]].each do |type| find_method_with_args(body_node, :depends_on, "rustup" => type) do - problem "Formulae in homebrew/core should use 'depends_on \"rust\" => #{type}' " \ - "instead of '#{T.must(@offensive_node).source}'." do |corrector| + problem "Formulae in homebrew/core should use `depends_on \"rust\" => #{type}` " \ + "instead of `#{T.must(@offensive_node).source}`." do |corrector| corrector.replace(T.must(@offensive_node).source_range, "depends_on \"rust\" => #{type}") end end diff --git a/Library/Homebrew/rubocops/options.rb b/Library/Homebrew/rubocops/options.rb index 8958b94dd8..b92fca4bbe 100644 --- a/Library/Homebrew/rubocops/options.rb +++ b/Library/Homebrew/rubocops/options.rb @@ -30,7 +30,7 @@ module RuboCop if !/with(out)?-/.match?(option) && option != "cxx11" && option != "universal" - problem "Options should begin with with/without. " \ + problem "Options should begin with `with` or `without`. " \ "Migrate '--#{option}' with `deprecated_option`." end diff --git a/Library/Homebrew/rubocops/patches.rb b/Library/Homebrew/rubocops/patches.rb index 4cc7a74066..5fd3a72741 100644 --- a/Library/Homebrew/rubocops/patches.rb +++ b/Library/Homebrew/rubocops/patches.rb @@ -30,14 +30,14 @@ module RuboCop if inline_patches.empty? && patch_end? offending_patch_end_node(node) - add_offense(@offense_source_range, message: "patch is missing 'DATA'") + add_offense(@offense_source_range, message: "Patch is missing `patch :DATA`") end patches_node = find_method_def(body_node, :patches) return if patches_node.nil? legacy_patches = find_strings(patches_node) - problem "Use the patch DSL instead of defining a 'patches' method" + problem "Use the `patch` DSL instead of defining a `patches` method" legacy_patches.each { |p| patch_problems(p) } end @@ -63,7 +63,7 @@ module RuboCop if regex_match_group(patch_url_node, bitbucket_regex) owner, repo, commit = patch_url_node.source.match(bitbucket_regex).captures correct_url = "https://api.bitbucket.org/2.0/repositories/#{owner}/#{repo}/diff/#{commit}" - problem "Bitbucket patches should use the api url: #{correct_url}" do |corrector| + problem "Bitbucket patches should use the API URL: #{correct_url}" do |corrector| corrector.replace(patch_url_node.source_range, %Q("#{correct_url}")) end end @@ -118,7 +118,7 @@ module RuboCop return if !patch_data?(patch) || patch_end? offending_node(patch) - problem "patch is missing '__END__'" + problem "Patch is missing `__END__`" end def_node_search :patch_data?, <<~AST diff --git a/Library/Homebrew/rubocops/shared/desc_helper.rb b/Library/Homebrew/rubocops/shared/desc_helper.rb index 6e458f1378..cfab0c1978 100644 --- a/Library/Homebrew/rubocops/shared/desc_helper.rb +++ b/Library/Homebrew/rubocops/shared/desc_helper.rb @@ -21,7 +21,7 @@ module RuboCop def audit_desc(type, name, desc_call) # Check if a desc is present. if desc_call.nil? - problem "#{type.to_s.capitalize} should have a desc (Description)." + problem "#{type.to_s.capitalize} should have a `desc` (description)." return end @@ -32,7 +32,7 @@ module RuboCop # Check if the desc is empty. desc_length = string_content(desc).length if desc_length.zero? - problem "The desc (description) should not be an empty string." + problem "The `desc` (description) should not be an empty string." return end diff --git a/Library/Homebrew/rubocops/shared/homepage_helper.rb b/Library/Homebrew/rubocops/shared/homepage_helper.rb index f5f53d3544..2ecef2bec9 100644 --- a/Library/Homebrew/rubocops/shared/homepage_helper.rb +++ b/Library/Homebrew/rubocops/shared/homepage_helper.rb @@ -19,10 +19,10 @@ module RuboCop def audit_homepage(type, content, homepage_node, homepage_parameter_node) @offensive_node = T.let(homepage_node, T.nilable(RuboCop::AST::Node)) - problem "#{type.to_s.capitalize} should have a homepage." if content.empty? + problem "#{type.to_s.capitalize} should have a `homepage`." if content.empty? @offensive_node = homepage_parameter_node - problem "The homepage should start with http or https." unless content.match?(%r{^https?://}) + problem "The `homepage` should start with http or https." unless content.match?(%r{^https?://}) case content # Freedesktop is complicated to handle - It has SSL/TLS, but only on certain subdomains. @@ -31,10 +31,9 @@ module RuboCop # "Software" is redirected to https://wiki.freedesktop.org/www/Software/project_name when %r{^http://((?:www|nice|libopenraw|liboil|telepathy|xorg)\.)?freedesktop\.org/(?:wiki/)?} if content.include?("Software") - problem "Freedesktop homepages should be styled " \ - "`https://wiki.freedesktop.org/www/Software/project_name`" + problem "Freedesktop homepages should be styled: https://wiki.freedesktop.org/www/Software/project_name" else - problem "Freedesktop homepages should be styled `https://wiki.freedesktop.org/project_name`" + problem "Freedesktop homepages should be styled: https://wiki.freedesktop.org/project_name" end # Google Code homepages should end in a slash @@ -45,13 +44,13 @@ module RuboCop when %r{^http://([^/]*)\.(sf|sourceforge)\.net(/|$)} fixed = "https://#{Regexp.last_match(1)}.sourceforge.io/" - problem "Sourceforge homepages should be `#{fixed}`" do |corrector| + problem "SourceForge homepages should be: #{fixed}" do |corrector| corrector.replace(homepage_parameter_node.source_range, "\"#{fixed}\"") end when /readthedocs\.org/ fixed = content.sub("readthedocs.org", "readthedocs.io") - problem "Readthedocs homepages should be `#{fixed}`" do |corrector| + problem "Readthedocs homepages should be: #{fixed}" do |corrector| corrector.replace(homepage_parameter_node.source_range, "\"#{fixed}\"") end diff --git a/Library/Homebrew/rubocops/shared/on_system_conditionals_helper.rb b/Library/Homebrew/rubocops/shared/on_system_conditionals_helper.rb index f973dd72b6..beb8a48a05 100644 --- a/Library/Homebrew/rubocops/shared/on_system_conditionals_helper.rb +++ b/Library/Homebrew/rubocops/shared/on_system_conditionals_helper.rb @@ -69,8 +69,8 @@ module RuboCop end offending_node(on_system_node) - problem "Don't use `#{on_system_node.source}` in `#{parent_string}`, " \ - "use `#{if_statement_string}#{if_conditional}` instead." do |corrector| + problem "Instead of using `#{on_system_node.source}` in `#{parent_string}`, " \ + "use `#{if_statement_string}#{if_conditional}`." do |corrector| block_node = offending_node.parent next if block_node.type != :block @@ -108,7 +108,7 @@ module RuboCop next if node_is_allowed?(method_node, allowed_methods:, allowed_blocks:) offending_node(method_node) - problem "Don't use `#{method_node.source}`, use `on_arm` and `on_intel` blocks instead." + problem "Instead of `#{method_node.source}`, use `on_arm` and `on_intel` blocks." end end end @@ -171,7 +171,7 @@ module RuboCop next if node_is_allowed?(method_node, allowed_methods:, allowed_blocks:) offending_node(method_node) - problem "Don't use `#{method_node.source}`, use `on_{macos_version}` blocks instead." + problem "Instead of `#{method_node.source}`, use `on_{macos_version}` blocks." end end end @@ -209,8 +209,7 @@ module RuboCop def if_statement_problem(if_node, if_statement_string, on_system_method_string, else_method: nil, else_node: nil, autocorrect: true) offending_node(if_node) - problem "Don't use `#{if_statement_string}`, " \ - "use `#{on_system_method_string} do` instead." do |corrector| + problem "Instead of `#{if_statement_string}`, use `#{on_system_method_string} do`." do |corrector| next unless autocorrect # TODO: could fix corrector to handle this but punting for now. next if if_node.unless? diff --git a/Library/Homebrew/rubocops/shared/url_helper.rb b/Library/Homebrew/rubocops/shared/url_helper.rb index 0a49816f13..e715ff607d 100644 --- a/Library/Homebrew/rubocops/shared/url_helper.rb +++ b/Library/Homebrew/rubocops/shared/url_helper.rb @@ -38,37 +38,37 @@ module RuboCop # URLs must be ASCII; IDNs must be punycode ascii_pattern = /[^\p{ASCII}]+/ audit_urls(urls, ascii_pattern) do |_, url| - problem "Please use the ASCII (Punycode encoded host, URL-encoded path and query) version of #{url}." + problem "Please use the ASCII (Punycode-encoded host, URL-encoded path and query) version of #{url}." end # GNU URLs; doesn't apply to mirrors gnu_pattern = %r{^(?:https?|ftp)://ftpmirror\.gnu\.org/(.*)} audit_urls(urls, gnu_pattern) do |match, url| - problem "Please use \"https://ftp.gnu.org/gnu/#{match[1]}\" instead of #{url}." + problem "#{url} should be: https://ftp.gnu.org/gnu/#{match[1]}" end # Fossies upstream requests they aren't used as primary URLs # https://github.com/Homebrew/homebrew-core/issues/14486#issuecomment-307753234 fossies_pattern = %r{^https?://fossies\.org/} audit_urls(urls, fossies_pattern) do - problem "Please don't use fossies.org in the url (using as a mirror is fine)" + problem "Please don't use \"fossies.org\" in the `url` (using as a mirror is fine)" end apache_pattern = %r{^https?://(?:[^/]*\.)?apache\.org/(?:dyn/closer\.cgi\?path=/?|dist/)(.*)}i audit_urls(urls, apache_pattern) do |match, url| next if url == livecheck_url - problem "#{url} should be `https://www.apache.org/dyn/closer.lua?path=#{match[1]}`" + problem "#{url} should be: https://www.apache.org/dyn/closer.lua?path=#{match[1]}" end version_control_pattern = %r{^(cvs|bzr|hg|fossil)://} audit_urls(urls, version_control_pattern) do |match, _| - problem "Use of the #{match[1]}:// scheme is deprecated, pass `:using => :#{match[1]}` instead" + problem "Use of the \"#{match[1]}://\" scheme is deprecated, pass `using: :#{match[1]}` instead" end svn_pattern = %r{^svn\+http://} audit_urls(urls, svn_pattern) do |_, _| - problem "Use of the svn+http:// scheme is deprecated, pass `:using => :svn` instead" + problem "Use of the \"svn+http://\" scheme is deprecated, pass `using: :svn` instead" end audit_urls(mirrors, /.*/) do |_, mirror| @@ -117,22 +117,22 @@ module RuboCop apache_mirror_pattern = %r{^https?://(?:[^/]*\.)?apache\.org/dyn/closer\.(?:cgi|lua)\?path=/?(.*)}i audit_urls(mirrors, apache_mirror_pattern) do |match, mirror| - problem "Please use `https://archive.apache.org/dist/#{match[1]}` as a mirror instead of #{mirror}." + problem "#{mirror} should be: https://archive.apache.org/dist/#{match[1]}" end cpan_pattern = %r{^http://search\.mcpan\.org/CPAN/(.*)}i audit_urls(urls, cpan_pattern) do |match, url| - problem "#{url} should be `https://cpan.metacpan.org/#{match[1]}`" + problem "#{url} should be: https://cpan.metacpan.org/#{match[1]}" end gnome_pattern = %r{^(http|ftp)://ftp\.gnome\.org/pub/gnome/(.*)}i audit_urls(urls, gnome_pattern) do |match, url| - problem "#{url} should be `https://download.gnome.org/#{match[2]}`" + problem "#{url} should be: https://download.gnome.org/#{match[2]}" end debian_pattern = %r{^git://anonscm\.debian\.org/users/(.*)}i audit_urls(urls, debian_pattern) do |match, url| - problem "#{url} should be `https://anonscm.debian.org/git/users/#{match[1]}`" + problem "#{url} should be: https://anonscm.debian.org/git/users/#{match[1]}" end # Prefer HTTP/S when possible over FTP protocol due to possible firewalls. @@ -143,7 +143,7 @@ module RuboCop cpan_ftp_pattern = %r{^ftp://ftp\.cpan\.org/pub/CPAN(.*)}i audit_urls(urls, cpan_ftp_pattern) do |match_obj, url| - problem "#{url} should be `http://search.cpan.org/CPAN#{match_obj[1]}`" + problem "#{url} should be: http://search.cpan.org/CPAN#{match_obj[1]}" end # SourceForge url patterns @@ -155,26 +155,26 @@ module RuboCop next if url.include? "/p/" if url =~ /(\?|&)use_mirror=/ - problem "Don't use #{Regexp.last_match(1)}use_mirror in SourceForge urls (url is #{url})." + problem "Don't use \"#{Regexp.last_match(1)}use_mirror\" in SourceForge URLs (`url` is #{url})." end - problem "Don't use /download in SourceForge urls (url is #{url})." if url.end_with?("/download") + problem "Don't use \"/download\" in SourceForge URLs (`url` is #{url})." if url.end_with?("/download") if url.match?(%r{^https?://(sourceforge|sf)\.}) && url != livecheck_url - problem "Use https://downloads.sourceforge.net to get geolocation (url is #{url})." + problem "Use \"https://downloads.sourceforge.net\" to get geolocation (`url` is #{url})." end if url.match?(%r{^https?://prdownloads\.}) - problem "Don't use prdownloads in SourceForge urls (url is #{url})." + problem "Don't use \"prdownloads\" in SourceForge URLs (`url` is #{url})." end if url.match?(%r{^http://\w+\.dl\.}) - problem "Don't use specific dl mirrors in SourceForge urls (url is #{url})." + problem "Don't use specific \"dl\" mirrors in SourceForge URLs (`url` is #{url})." end # sf.net does HTTPS -> HTTP redirects. if url.match?(%r{^https?://downloads?\.sf\.net}) - problem "Use https://downloads.sourceforge.net instead of downloads.sf.net (url is #{url})" + problem "Use \"https://downloads.sourceforge.net\" instead of \"downloads.sf.net\" (`url` is #{url})" end end @@ -236,14 +236,14 @@ module RuboCop audit_urls(urls, archive_gh_pattern) do |_, url| next if url.end_with?(".git") - problem "Use /archive/ URLs for GitHub tarballs (url is #{url})." + problem "Use /archive/ URLs for GitHub tarballs (`url` is #{url})." end archive_refs_gh_pattern = %r{https://.*github.+/archive/(?![a-fA-F0-9]{40})(?!refs/(tags|heads)/)(.*)\.tar\.gz$} audit_urls(urls, archive_refs_gh_pattern) do |match, url| next if url.end_with?(".git") - problem "Use refs/tags/#{match[2]} or refs/heads/#{match[2]} for GitHub references (url is #{url})." + problem %Q(Use "refs/tags/#{match[2]}" or "refs/heads/#{match[2]}" for GitHub references (`url` is #{url}).) end # Don't use GitHub .zip files @@ -253,7 +253,7 @@ module RuboCop next if url.include?("releases/download") next if url.include?("desktop.githubusercontent.com/releases/") - problem "Use GitHub tarballs rather than zipballs (url is #{url})." + problem "Use GitHub tarballs rather than zipballs (`url` is #{url})." end # Don't use GitHub codeload URLs @@ -270,7 +270,7 @@ module RuboCop # Check for Maven Central URLs, prefer HTTPS redirector over specific host maven_pattern = %r{https?://(?:central|repo\d+)\.maven\.org/maven2/(.+)$} audit_urls(urls, maven_pattern) do |match, url| - problem "#{url} should be `https://search.maven.org/remotecontent?filepath=#{match[1]}`" + problem "#{url} should be: https://search.maven.org/remotecontent?filepath=#{match[1]}" end end end diff --git a/Library/Homebrew/rubocops/text.rb b/Library/Homebrew/rubocops/text.rb index 21c15615b8..7b7469b10f 100644 --- a/Library/Homebrew/rubocops/text.rb +++ b/Library/Homebrew/rubocops/text.rb @@ -45,19 +45,19 @@ module RuboCop # processed_source.ast is passed instead of body_node because `require` would be outside body_node find_method_with_args(processed_source.ast, :require, "language/go") do - problem "require \"language/go\" is no longer necessary or correct" + problem '`require "language/go"` is no longer necessary or correct' end find_instance_method_call(body_node, "Formula", :factory) do - problem "\"Formula.factory(name)\" is deprecated in favor of \"Formula[name]\"" + problem "`Formula.factory(name)` is deprecated in favour of `Formula[name]`" end find_method_with_args(body_node, :revision, 0) do - problem "\"revision 0\" is unnecessary" + problem "`revision 0` is unnecessary" end find_method_with_args(body_node, :system, "xcodebuild") do - problem %q(use "xcodebuild *args" instead of "system 'xcodebuild', *args") + problem "Use `xcodebuild *args` instead of `system 'xcodebuild', *args`" end if !depends_on?(:xcode) && method_called_ever?(body_node, :xcodebuild) @@ -72,7 +72,7 @@ module RuboCop find_method_with_args(method_node, :system, "cargo", "build") do |m| next if parameters_passed?(m, [/--lib/]) - problem "use \"cargo\", \"install\", *std_cargo_args" + problem 'Use `"cargo", "install", *std_cargo_args`' end end @@ -80,7 +80,7 @@ module RuboCop next if parameters_passed?(d, [/vendor-only/]) next if @formula_name == "goose" # needed in 2.3.0 - problem "use \"dep\", \"ensure\", \"-vendor-only\"" + problem 'Use `"dep", "ensure", "-vendor-only"`' end find_every_method_call_by_name(body_node, :system).each do |m| diff --git a/Library/Homebrew/rubocops/urls.rb b/Library/Homebrew/rubocops/urls.rb index a37ba8705e..cbd9bcb393 100644 --- a/Library/Homebrew/rubocops/urls.rb +++ b/Library/Homebrew/rubocops/urls.rb @@ -54,13 +54,13 @@ module RuboCop # Check pypi URLs pypi_pattern = %r{^https?://pypi\.python\.org/} audit_urls(urls, pypi_pattern) do |_, url| - problem "use the `Source` url found on PyPI downloads page (`#{get_pypi_url(url)}`)" + problem "Use the \"Source\" URL found on the PyPI downloads page (#{get_pypi_url(url)})" end # Require long files.pythonhosted.org URLs pythonhosted_pattern = %r{^https?://files\.pythonhosted\.org/packages/source/} audit_urls(urls, pythonhosted_pattern) do |_, url| - problem "use the `Source` url found on PyPI downloads page (`#{get_pypi_url(url)}`)" + problem "Use the \"Source\" URL found on the PyPI downloads page (#{get_pypi_url(url)})" end end @@ -84,7 +84,7 @@ module RuboCop next if url_has_revision?(parameters(url).last) offending_node(url) - problem "Formulae in homebrew/core should specify a revision for git URLs" + problem "Formulae in homebrew/core should specify a revision for Git URLs" end end @@ -107,7 +107,7 @@ module RuboCop next if url_has_tag?(parameters(url).last) offending_node(url) - problem "Formulae in homebrew/core should specify a tag for git URLs" + problem "Formulae in homebrew/core should specify a tag for Git URLs" end end diff --git a/Library/Homebrew/rubocops/uses_from_macos.rb b/Library/Homebrew/rubocops/uses_from_macos.rb index 621f3bc3ed..8ebbc96483 100644 --- a/Library/Homebrew/rubocops/uses_from_macos.rb +++ b/Library/Homebrew/rubocops/uses_from_macos.rb @@ -66,7 +66,7 @@ module RuboCop return if PROVIDED_BY_MACOS_FORMULAE.include? @formula_name problem "Formulae that are `keg_only :provided_by_macos` should be " \ - "added to the `PROVIDED_BY_MACOS_FORMULAE` list (in the Homebrew/brew repo)" + "added to the `PROVIDED_BY_MACOS_FORMULAE` list (in the Homebrew/brew repository)" end end end @@ -116,7 +116,7 @@ module RuboCop next if ALLOWED_USES_FROM_MACOS_DEPS.include? dep_name next if ProvidedByMacos::PROVIDED_BY_MACOS_FORMULAE.include? dep_name - problem "`uses_from_macos` should only be used for macOS dependencies, not #{dep_name}." + problem "`uses_from_macos` should only be used for macOS dependencies, not '#{dep_name}'." end end end diff --git a/Library/Homebrew/rubocops/version.rb b/Library/Homebrew/rubocops/version.rb index 82863ab3a1..4492e57d9e 100644 --- a/Library/Homebrew/rubocops/version.rb +++ b/Library/Homebrew/rubocops/version.rb @@ -15,13 +15,13 @@ module RuboCop version = string_content(parameters(version_node).first) - problem "version is set to an empty string" if version.empty? + problem "Version is set to an empty string" if version.empty? - problem "version #{version} should not have a leading 'v'" if version.start_with?("v") + problem "Version #{version} should not have a leading 'v'" if version.start_with?("v") return unless version.match?(/_\d+$/) - problem "version #{version} should not end with an underline and a number" + problem "Version #{version} should not end with an underline and a number" end end end diff --git a/Library/Homebrew/test/formula_auditor_spec.rb b/Library/Homebrew/test/formula_auditor_spec.rb index 8b363aebd2..ce873129ba 100644 --- a/Library/Homebrew/test/formula_auditor_spec.rb +++ b/Library/Homebrew/test/formula_auditor_spec.rb @@ -519,7 +519,7 @@ RSpec.describe Homebrew::FormulaAuditor do fa.audit_specs expect(fa.problems.first[:message]) - .to match("resource name should be `FooSomething` to match the PyPI package name") + .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 @@ -538,7 +538,7 @@ RSpec.describe Homebrew::FormulaAuditor do fa.audit_specs expect(fa.problems.first[:message]) - .to match("resource name should be `FooSomething` to match the PyPI package name") + .to match("`resource` name should be 'FooSomething' to match the PyPI package name") end end @@ -788,7 +788,7 @@ RSpec.describe Homebrew::FormulaAuditor do RUBY fa.audit_specs - expect(fa.problems.first[:message]).to match "Versioned formulae should not have a `HEAD` spec" + expect(fa.problems.first[:message]).to match "Versioned formulae should not have a `head` spec" end it "allows versioned formulae on the allowlist to have a `HEAD` spec" do @@ -911,7 +911,7 @@ RSpec.describe Homebrew::FormulaAuditor do context "when uncommitted should not decrease" do before { formula_gsub "foo-1.0.tar.gz", "foo-0.9.tar.gz" } - it { is_expected.to match("stable version should not decrease (from 1.0 to 0.9)") } + it { is_expected.to match("Stable: version should not decrease (from 1.0 to 0.9)") } end context "when committed can decrease" do @@ -991,31 +991,31 @@ RSpec.describe Homebrew::FormulaAuditor do describe "with the same version, should not decrease" do before { formula_gsub_origin_commit "revision 2", "revision 1" } - it { is_expected.to match("revision should not decrease (from 2 to 1)") } + it { is_expected.to match("`revision` should not decrease (from 2 to 1)") } end describe "should not be removed with the same version" do before { formula_gsub_origin_commit "revision 2" } - it { is_expected.to match("revision should not decrease (from 2 to 0)") } + it { is_expected.to match("`revision` should not decrease (from 2 to 0)") } end describe "should not decrease with the same, uncommitted version" do before { formula_gsub "revision 2", "revision 1" } - it { is_expected.to match("revision should not decrease (from 2 to 1)") } + it { is_expected.to match("`revision` should not decrease (from 2 to 1)") } end describe "should be removed with a newer version" do before { formula_gsub_origin_commit "foo-1.0.tar.gz", "foo-1.1.tar.gz" } - it { is_expected.to match("'revision 2' should be removed") } + it { is_expected.to match("`revision 2` should be removed") } end describe "should be removed with a newer local version" do before { formula_gsub "foo-1.0.tar.gz", "foo-1.1.tar.gz" } - it { is_expected.to match("'revision 2' should be removed") } + it { is_expected.to match("`revision 2` should be removed") } end describe "should not warn on an newer version revision removal" do @@ -1044,7 +1044,7 @@ RSpec.describe Homebrew::FormulaAuditor do formula_gsub "revision 2", "revision 4" end - it { is_expected.to match("revisions should only increment by 1") } + it { is_expected.to match("`revision` should only increment by 1") } end describe "should not warn on past increment by more than 1" do @@ -1094,7 +1094,7 @@ RSpec.describe Homebrew::FormulaAuditor do describe "should not decrease with the same version" do before { formula_gsub_origin_commit "version_scheme 1" } - it { is_expected.to match("version_scheme should not decrease (from 1 to 0)") } + it { is_expected.to match("`version_scheme` should not decrease (from 1 to 0)") } end describe "should not decrease with a new version" do @@ -1104,7 +1104,7 @@ RSpec.describe Homebrew::FormulaAuditor do formula_gsub_origin_commit "version_scheme 1", "" end - it { is_expected.to match("version_scheme should not decrease (from 1 to 0)") } + it { is_expected.to match("`version_scheme` should not decrease (from 1 to 0)") } end describe "should only increment by 1" do @@ -1115,7 +1115,7 @@ RSpec.describe Homebrew::FormulaAuditor do formula_gsub_origin_commit "# no version_scheme", "version_scheme 3" end - it { is_expected.to match("version_schemes should only increment by 1") } + it { is_expected.to match("`version_scheme` should only increment by 1") } end end end diff --git a/Library/Homebrew/test/rubocops/cask/on_system_conditionals_spec.rb b/Library/Homebrew/test/rubocops/cask/on_system_conditionals_spec.rb index 7777d226af..fbbc8fc645 100644 --- a/Library/Homebrew/test/rubocops/cask/on_system_conditionals_spec.rb +++ b/Library/Homebrew/test/rubocops/cask/on_system_conditionals_spec.rb @@ -19,7 +19,7 @@ RSpec.describe RuboCop::Cop::Cask::OnSystemConditionals, :config do cask 'foo' do postflight do on_intel do - ^^^^^^^^ Don't use `on_intel` in `postflight do`, use `if Hardware::CPU.intel?` instead. + ^^^^^^^^ Instead of using `on_intel` in `postflight do`, use `if Hardware::CPU.intel?`. foobar end end @@ -43,7 +43,7 @@ RSpec.describe RuboCop::Cop::Cask::OnSystemConditionals, :config do cask 'foo' do postflight do on_monterey do - ^^^^^^^^^^^ Don't use `on_monterey` in `postflight do`, use `if MacOS.version == :monterey` instead. + ^^^^^^^^^^^ Instead of using `on_monterey` in `postflight do`, use `if MacOS.version == :monterey`. foobar end end @@ -67,7 +67,7 @@ RSpec.describe RuboCop::Cop::Cask::OnSystemConditionals, :config do cask 'foo' do postflight do on_monterey :or_older do - ^^^^^^^^^^^^^^^^^^^^^ Don't use `on_monterey :or_older` in `postflight do`, use `if MacOS.version <= :monterey` instead. + ^^^^^^^^^^^^^^^^^^^^^ Instead of using `on_monterey :or_older` in `postflight do`, use `if MacOS.version <= :monterey`. foobar end end @@ -171,7 +171,7 @@ RSpec.describe RuboCop::Cop::Cask::OnSystemConditionals, :config do expect_offense <<~CASK cask 'foo' do if Hardware::CPU.arm? && other_condition - ^^^^^^^^^^^^^^^^^^ Don't use `Hardware::CPU.arm?`, use `on_arm` and `on_intel` blocks instead. + ^^^^^^^^^^^^^^^^^^ Instead of `Hardware::CPU.arm?`, use `on_arm` and `on_intel` blocks. sha256 "67cdb8a02803ef37fdbf7e0be205863172e41a561ca446cd84f0d7ab35a99d94" else sha256 "8c62a2b791cf5f0da6066a0a4b6e85f62949cd60975da062df44adf887f4370b" @@ -184,7 +184,7 @@ RSpec.describe RuboCop::Cop::Cask::OnSystemConditionals, :config do expect_offense <<~CASK cask 'foo' do if Hardware::CPU.intel? && other_condition - ^^^^^^^^^^^^^^^^^^^^ Don't use `Hardware::CPU.intel?`, use `on_arm` and `on_intel` blocks instead. + ^^^^^^^^^^^^^^^^^^^^ Instead of `Hardware::CPU.intel?`, use `on_arm` and `on_intel` blocks. sha256 "67cdb8a02803ef37fdbf7e0be205863172e41a561ca446cd84f0d7ab35a99d94" else sha256 "8c62a2b791cf5f0da6066a0a4b6e85f62949cd60975da062df44adf887f4370b" @@ -200,7 +200,7 @@ RSpec.describe RuboCop::Cop::Cask::OnSystemConditionals, :config do sha256 "67cdb8a02803ef37fdbf7e0be205863172e41a561ca446cd84f0d7ab35a99d94" url "https://example.com/foo-#{version}-#{Hardware::CPU.arch}.zip" - ^^^^^^^^^^^^^^^^^^ Don't use `Hardware::CPU.arch`, use `on_arm` and `on_intel` blocks instead. + ^^^^^^^^^^^^^^^^^^ Instead of `Hardware::CPU.arch`, use `on_arm` and `on_intel` blocks. end CASK end @@ -211,7 +211,7 @@ RSpec.describe RuboCop::Cop::Cask::OnSystemConditionals, :config do expect_offense <<~CASK cask 'foo' do if MacOS.version == :catalina - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Don't use `if MacOS.version == :catalina`, use `on_catalina do` instead. + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Instead of `if MacOS.version == :catalina`, use `on_catalina do`. version "1.0.0" else version "2.0.0" @@ -224,7 +224,7 @@ RSpec.describe RuboCop::Cop::Cask::OnSystemConditionals, :config do expect_offense <<~CASK cask 'foo' do if MacOS.version <= :catalina - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Don't use `if MacOS.version <= :catalina`, use `on_catalina :or_older do` instead. + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Instead of `if MacOS.version <= :catalina`, use `on_catalina :or_older do`. version "1.0.0" else version "2.0.0" @@ -237,7 +237,7 @@ RSpec.describe RuboCop::Cop::Cask::OnSystemConditionals, :config do expect_offense <<~CASK cask 'foo' do if MacOS.version >= :catalina - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Don't use `if MacOS.version >= :catalina`, use `on_catalina :or_newer do` instead. + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Instead of `if MacOS.version >= :catalina`, use `on_catalina :or_newer do`. version "1.0.0" else version "2.0.0" diff --git a/Library/Homebrew/test/rubocops/caveats_spec.rb b/Library/Homebrew/test/rubocops/caveats_spec.rb index 93a80060be..6b262fd278 100644 --- a/Library/Homebrew/test/rubocops/caveats_spec.rb +++ b/Library/Homebrew/test/rubocops/caveats_spec.rb @@ -13,7 +13,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::Caveats do url "https://brew.sh/foo-1.0.tgz" def caveats "setuid" - ^^^^^^^^ FormulaAudit/Caveats: Don't recommend `setuid` in the caveats, suggest `sudo` instead. + ^^^^^^^^ FormulaAudit/Caveats: Instead of recommending `setuid` in the caveats, suggest `sudo`. end end RUBY diff --git a/Library/Homebrew/test/rubocops/checksum/checksum_case_spec.rb b/Library/Homebrew/test/rubocops/checksum/checksum_case_spec.rb index c05e29827d..612a0b5383 100644 --- a/Library/Homebrew/test/rubocops/checksum/checksum_case_spec.rb +++ b/Library/Homebrew/test/rubocops/checksum/checksum_case_spec.rb @@ -13,12 +13,12 @@ RSpec.describe RuboCop::Cop::FormulaAudit::ChecksumCase do stable do url "https://github.com/foo-lang/foo-compiler/archive/0.18.0.tar.gz" sha256 "5cf6e1ae0A645b426c0a7cc7cd3f7d1605ffa1ac5756a39a8b2268ddc7ea0e9a" - ^ FormulaAudit/ChecksumCase: sha256 should be lowercase + ^ FormulaAudit/ChecksumCase: `sha256` should be lowercase resource "foo-package" do url "https://github.com/foo-lang/foo-package/archive/0.18.0.tar.gz" sha256 "5cf6e1Ae0a645b426b047aa4cc7cd3f7d1605ffa1ac5756a39a8b2268ddc7ea9" - ^ FormulaAudit/ChecksumCase: sha256 should be lowercase + ^ FormulaAudit/ChecksumCase: `sha256` should be lowercase end end end @@ -32,7 +32,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::ChecksumCase do resource "foo-outside" do url "https://github.com/foo-lang/foo-outside/archive/0.18.0.tar.gz" sha256 "A4cc7cd3f7d1605ffa1ac5755cf6e1ae0a645b426b047a6a39a8b2268ddc7ea9" - ^ FormulaAudit/ChecksumCase: sha256 should be lowercase + ^ FormulaAudit/ChecksumCase: `sha256` should be lowercase end stable do url "https://github.com/foo-lang/foo-compiler/archive/0.18.0.tar.gz" diff --git a/Library/Homebrew/test/rubocops/checksum/checksum_spec.rb b/Library/Homebrew/test/rubocops/checksum/checksum_spec.rb index a50b7122a7..b82593f96b 100644 --- a/Library/Homebrew/test/rubocops/checksum/checksum_spec.rb +++ b/Library/Homebrew/test/rubocops/checksum/checksum_spec.rb @@ -13,12 +13,12 @@ RSpec.describe RuboCop::Cop::FormulaAudit::Checksum do stable do url "https://github.com/foo-lang/foo-compiler/archive/0.18.0.tar.gz" sha256 "" - ^^ FormulaAudit/Checksum: sha256 is empty + ^^ FormulaAudit/Checksum: `sha256` is empty resource "foo-package" do url "https://github.com/foo-lang/foo-package/archive/0.18.0.tar.gz" sha256 "" - ^^ FormulaAudit/Checksum: sha256 is empty + ^^ FormulaAudit/Checksum: `sha256` is empty end end end @@ -32,12 +32,12 @@ RSpec.describe RuboCop::Cop::FormulaAudit::Checksum do stable do url "https://github.com/foo-lang/foo-compiler/archive/0.18.0.tar.gz" sha256 "5cf6e1ae0a645b426c0474cc7cd3f7d1605ffa1ac5756a39a8b2268ddc7ea0e9ad" - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/Checksum: sha256 should be 64 characters + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/Checksum: `sha256` should be 64 characters resource "foo-package" do url "https://github.com/foo-lang/foo-package/archive/0.18.0.tar.gz" sha256 "5cf6e1ae0a645b426c047aaa4cc7cd3f7d1605ffa1ac5756a39a8b2268ddc7ea0e9" - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/Checksum: sha256 should be 64 characters + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/Checksum: `sha256` should be 64 characters end end end @@ -51,12 +51,12 @@ RSpec.describe RuboCop::Cop::FormulaAudit::Checksum do stable do url "https://github.com/foo-lang/foo-compiler/archive/0.18.0.tar.gz" sha256 "5cf6e1ae0a645b426c0k7cc7cd3f7d1605ffa1ac5756a39a8b2268ddc7ea0e9a" - ^ FormulaAudit/Checksum: sha256 contains invalid characters + ^ FormulaAudit/Checksum: `sha256` contains invalid characters resource "foo-package" do url "https://github.com/foo-lang/foo-package/archive/0.18.0.tar.gz" sha256 "5cf6e1ae0a645b426x047aa4cc7cd3f7d1605ffa1ac5756a39a8b2268ddc7ea9" - ^ FormulaAudit/Checksum: sha256 contains invalid characters + ^ FormulaAudit/Checksum: `sha256` contains invalid characters end end end @@ -70,7 +70,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::Checksum do bottle do sha256 catalina: "5cf6e1ae0a645b426c0474cc7cd3f7d1605ffa1ac5756a39a8b2268ddc7ea0e9ad" - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/Checksum: sha256 should be 64 characters + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/Checksum: `sha256` should be 64 characters end end RUBY @@ -83,7 +83,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::Checksum do bottle do sha256 cellar: :any, catalina: "5cf6e1ae0a645b426c0474cc7cd3f7d1605ffa1ac5756a39a8b2268ddc7ea0e9ad" - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/Checksum: sha256 should be 64 characters + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/Checksum: `sha256` should be 64 characters end end RUBY diff --git a/Library/Homebrew/test/rubocops/class/class_name_spec.rb b/Library/Homebrew/test/rubocops/class/class_name_spec.rb index 78050236a1..49fbc0812f 100644 --- a/Library/Homebrew/test/rubocops/class/class_name_spec.rb +++ b/Library/Homebrew/test/rubocops/class/class_name_spec.rb @@ -14,7 +14,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::ClassName do it "reports and corrects an offense when using ScriptFileFormula" do expect_offense(<<~RUBY) class Foo < ScriptFileFormula - ^^^^^^^^^^^^^^^^^ FormulaAudit/ClassName: ScriptFileFormula is deprecated, use Formula instead + ^^^^^^^^^^^^^^^^^ FormulaAudit/ClassName: `ScriptFileFormula` is deprecated, use `Formula` instead url 'https://brew.sh/foo-1.0.tgz' end RUBY @@ -24,7 +24,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::ClassName do it "reports and corrects an offense when using GithubGistFormula" do expect_offense(<<~RUBY) class Foo < GithubGistFormula - ^^^^^^^^^^^^^^^^^ FormulaAudit/ClassName: GithubGistFormula is deprecated, use Formula instead + ^^^^^^^^^^^^^^^^^ FormulaAudit/ClassName: `GithubGistFormula` is deprecated, use `Formula` instead url 'https://brew.sh/foo-1.0.tgz' end RUBY @@ -34,7 +34,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::ClassName do it "reports and corrects an offense when using AmazonWebServicesFormula" do expect_offense(<<~RUBY) class Foo < AmazonWebServicesFormula - ^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/ClassName: AmazonWebServicesFormula is deprecated, use Formula instead + ^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/ClassName: `AmazonWebServicesFormula` is deprecated, use `Formula` instead url 'https://brew.sh/foo-1.0.tgz' end RUBY diff --git a/Library/Homebrew/test/rubocops/class/test_spec.rb b/Library/Homebrew/test/rubocops/class/test_spec.rb index cabeddb71e..deb36fc66f 100644 --- a/Library/Homebrew/test/rubocops/class/test_spec.rb +++ b/Library/Homebrew/test/rubocops/class/test_spec.rb @@ -6,46 +6,46 @@ RSpec.describe RuboCop::Cop::FormulaAudit::Test do subject(:cop) { described_class.new } it "reports and corrects an offense when /usr/local/bin is found in test calls" do - expect_offense(<<~RUBY) + expect_offense(<<~'RUBY') class Foo < Formula url 'https://brew.sh/foo-1.0.tgz' test do system "/usr/local/bin/test" - ^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/Test: use \#{bin} instead of /usr/local/bin in system + ^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/Test: Use `#{bin}` instead of `/usr/local/bin` in `system` end end RUBY - expect_correction(<<~RUBY) + expect_correction(<<~'RUBY') class Foo < Formula url 'https://brew.sh/foo-1.0.tgz' test do - system "\#{bin}/test" + system "#{bin}/test" end end RUBY end it "reports and corrects an offense when passing 0 as the second parameter to shell_output" do - expect_offense(<<~RUBY) + expect_offense(<<~'RUBY') class Foo < Formula url 'https://brew.sh/foo-1.0.tgz' test do - shell_output("\#{bin}/test", 0) - ^ FormulaAudit/Test: Passing 0 to shell_output() is redundant + shell_output("#{bin}/test", 0) + ^ FormulaAudit/Test: Passing 0 to `shell_output` is redundant end end RUBY - expect_correction(<<~RUBY) + expect_correction(<<~'RUBY') class Foo < Formula url 'https://brew.sh/foo-1.0.tgz' test do - shell_output("\#{bin}/test") + shell_output("#{bin}/test") end end RUBY diff --git a/Library/Homebrew/test/rubocops/components_order_spec.rb b/Library/Homebrew/test/rubocops/components_order_spec.rb index 8fce98e573..a52843b836 100644 --- a/Library/Homebrew/test/rubocops/components_order_spec.rb +++ b/Library/Homebrew/test/rubocops/components_order_spec.rb @@ -511,7 +511,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::ComponentsOrder do end on_macos do - ^^^^^^^^^^^ FormulaAudit/ComponentsOrder: there can only be one `on_macos` block in a formula. + ^^^^^^^^^^^ FormulaAudit/ComponentsOrder: There can only be one `on_macos` block in a formula. depends_on "foo" end end @@ -527,7 +527,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::ComponentsOrder do end on_linux do - ^^^^^^^^^^^ FormulaAudit/ComponentsOrder: there can only be one `on_linux` block in a formula. + ^^^^^^^^^^^ FormulaAudit/ComponentsOrder: There can only be one `on_linux` block in a formula. depends_on "foo" end end @@ -543,7 +543,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::ComponentsOrder do end on_intel do - ^^^^^^^^^^^ FormulaAudit/ComponentsOrder: there can only be one `on_intel` block in a formula. + ^^^^^^^^^^^ FormulaAudit/ComponentsOrder: There can only be one `on_intel` block in a formula. depends_on "foo" end end @@ -559,7 +559,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::ComponentsOrder do end on_arm do - ^^^^^^^^^ FormulaAudit/ComponentsOrder: there can only be one `on_arm` block in a formula. + ^^^^^^^^^ FormulaAudit/ComponentsOrder: There can only be one `on_arm` block in a formula. depends_on "foo" end end @@ -575,7 +575,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::ComponentsOrder do end on_monterey do - ^^^^^^^^^^^^^^ FormulaAudit/ComponentsOrder: there can only be one `on_monterey` block in a formula. + ^^^^^^^^^^^^^^ FormulaAudit/ComponentsOrder: There can only be one `on_monterey` block in a formula. depends_on "foo" end end @@ -591,7 +591,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::ComponentsOrder do end on_monterey :or_older do - ^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/ComponentsOrder: there can only be one `on_monterey` block in a formula. + ^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/ComponentsOrder: There can only be one `on_monterey` block in a formula. depends_on "foo" end end @@ -881,7 +881,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::ComponentsOrder do url "https://brew.sh/foo-1.0.tgz" resource do - ^^^^^^^^^^^ FormulaAudit/ComponentsOrder: there can only be one `on_macos` block in a resource block. + ^^^^^^^^^^^ FormulaAudit/ComponentsOrder: There can only be one `on_macos` block in a resource block. on_macos do url "https://brew.sh/resource1.tar.gz" sha256 "586372eb92059873e29eba4f9dec8381541b4d3834660707faf8ba59146dfc35" @@ -902,7 +902,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::ComponentsOrder do url "https://brew.sh/foo-1.0.tgz" resource do - ^^^^^^^^^^^ FormulaAudit/ComponentsOrder: there can only be one `on_linux` block in a resource block. + ^^^^^^^^^^^ FormulaAudit/ComponentsOrder: There can only be one `on_linux` block in a resource block. on_linux do url "https://brew.sh/resource1.tar.gz" sha256 "586372eb92059873e29eba4f9dec8381541b4d3834660707faf8ba59146dfc35" @@ -923,7 +923,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::ComponentsOrder do url "https://brew.sh/foo-1.0.tgz" resource do - ^^^^^^^^^^^ FormulaAudit/ComponentsOrder: there can only be one `on_intel` block in a resource block. + ^^^^^^^^^^^ FormulaAudit/ComponentsOrder: There can only be one `on_intel` block in a resource block. on_intel do url "https://brew.sh/resource1.tar.gz" sha256 "586372eb92059873e29eba4f9dec8381541b4d3834660707faf8ba59146dfc35" @@ -944,7 +944,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::ComponentsOrder do url "https://brew.sh/foo-1.0.tgz" resource do - ^^^^^^^^^^^ FormulaAudit/ComponentsOrder: there can only be one `on_arm` block in a resource block. + ^^^^^^^^^^^ FormulaAudit/ComponentsOrder: There can only be one `on_arm` block in a resource block. on_arm do url "https://brew.sh/resource1.tar.gz" sha256 "586372eb92059873e29eba4f9dec8381541b4d3834660707faf8ba59146dfc35" @@ -965,7 +965,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::ComponentsOrder do url "https://brew.sh/foo-1.0.tgz" resource do - ^^^^^^^^^^^ FormulaAudit/ComponentsOrder: there can only be one `on_monterey` block in a resource block. + ^^^^^^^^^^^ FormulaAudit/ComponentsOrder: There can only be one `on_monterey` block in a resource block. on_monterey do url "https://brew.sh/resource1.tar.gz" sha256 "586372eb92059873e29eba4f9dec8381541b4d3834660707faf8ba59146dfc35" diff --git a/Library/Homebrew/test/rubocops/dependency_order_spec.rb b/Library/Homebrew/test/rubocops/dependency_order_spec.rb index bbcfe253e4..80a465a938 100644 --- a/Library/Homebrew/test/rubocops/dependency_order_spec.rb +++ b/Library/Homebrew/test/rubocops/dependency_order_spec.rb @@ -13,7 +13,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::DependencyOrder do url "https://brew.sh/foo-1.0.tgz" uses_from_macos "apple" if build.with? "foo" uses_from_macos "foo" => :optional - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/DependencyOrder: dependency "foo" (line 5) should be put before dependency "apple" (line 4) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/DependencyOrder: `dependency "foo"` (line 5) should be put before `dependency "apple"` (line 4) end RUBY @@ -34,7 +34,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::DependencyOrder do url "https://brew.sh/foo-1.0.tgz" uses_from_macos "foo" uses_from_macos "bar" - ^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/DependencyOrder: dependency "bar" (line 5) should be put before dependency "foo" (line 4) + ^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/DependencyOrder: `dependency "bar"` (line 5) should be put before `dependency "foo"` (line 4) end RUBY @@ -55,7 +55,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::DependencyOrder do url "https://brew.sh/foo-1.0.tgz" uses_from_macos FooRequirement uses_from_macos "bar" - ^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/DependencyOrder: dependency "bar" (line 5) should be put before dependency "FooRequirement" (line 4) + ^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/DependencyOrder: `dependency "bar"` (line 5) should be put before `dependency "FooRequirement"` (line 4) end RUBY @@ -77,13 +77,13 @@ RSpec.describe RuboCop::Cop::FormulaAudit::DependencyOrder do head do uses_from_macos "apple" if build.with? "foo" uses_from_macos "bar" - ^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/DependencyOrder: dependency "bar" (line 6) should be put before dependency "apple" (line 5) + ^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/DependencyOrder: `dependency "bar"` (line 6) should be put before `dependency "apple"` (line 5) uses_from_macos "foo" => :optional - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/DependencyOrder: dependency "foo" (line 7) should be put before dependency "apple" (line 5) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/DependencyOrder: `dependency "foo"` (line 7) should be put before `dependency "apple"` (line 5) end uses_from_macos "apple" if build.with? "foo" uses_from_macos "foo" => :optional - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/DependencyOrder: dependency "foo" (line 10) should be put before dependency "apple" (line 9) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/DependencyOrder: `dependency "foo"` (line 10) should be put before `dependency "apple"` (line 9) end RUBY @@ -122,9 +122,9 @@ RSpec.describe RuboCop::Cop::FormulaAudit::DependencyOrder do on_arm do uses_from_macos "apple" if build.with? "foo" uses_from_macos "bar" - ^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/DependencyOrder: dependency "bar" (line 6) should be put before dependency "apple" (line 5) + ^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/DependencyOrder: `dependency "bar"` (line 6) should be put before `dependency "apple"` (line 5) uses_from_macos "foo" => :optional - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/DependencyOrder: dependency "foo" (line 7) should be put before dependency "apple" (line 5) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/DependencyOrder: `dependency "foo"` (line 7) should be put before `dependency "apple"` (line 5) end end RUBY @@ -151,7 +151,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::DependencyOrder do url "https://brew.sh/foo-1.0.tgz" depends_on "apple" if build.with? "foo" depends_on "foo" => :optional - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/DependencyOrder: dependency "foo" (line 5) should be put before dependency "apple" (line 4) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/DependencyOrder: `dependency "foo"` (line 5) should be put before `dependency "apple"` (line 4) end RUBY @@ -172,7 +172,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::DependencyOrder do url "https://brew.sh/foo-1.0.tgz" depends_on "foo" depends_on "bar" - ^^^^^^^^^^^^^^^^ FormulaAudit/DependencyOrder: dependency "bar" (line 5) should be put before dependency "foo" (line 4) + ^^^^^^^^^^^^^^^^ FormulaAudit/DependencyOrder: `dependency "bar"` (line 5) should be put before `dependency "foo"` (line 4) end RUBY @@ -193,7 +193,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::DependencyOrder do url "https://brew.sh/foo-1.0.tgz" depends_on FooRequirement depends_on "bar" - ^^^^^^^^^^^^^^^^ FormulaAudit/DependencyOrder: dependency "bar" (line 5) should be put before dependency "FooRequirement" (line 4) + ^^^^^^^^^^^^^^^^ FormulaAudit/DependencyOrder: `dependency "bar"` (line 5) should be put before `dependency "FooRequirement"` (line 4) end RUBY @@ -215,13 +215,13 @@ RSpec.describe RuboCop::Cop::FormulaAudit::DependencyOrder do head do depends_on "apple" if build.with? "foo" depends_on "bar" - ^^^^^^^^^^^^^^^^ FormulaAudit/DependencyOrder: dependency "bar" (line 6) should be put before dependency "apple" (line 5) + ^^^^^^^^^^^^^^^^ FormulaAudit/DependencyOrder: `dependency "bar"` (line 6) should be put before `dependency "apple"` (line 5) depends_on "foo" => :optional - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/DependencyOrder: dependency "foo" (line 7) should be put before dependency "apple" (line 5) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/DependencyOrder: `dependency "foo"` (line 7) should be put before `dependency "apple"` (line 5) end depends_on "apple" if build.with? "foo" depends_on "foo" => :optional - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/DependencyOrder: dependency "foo" (line 10) should be put before dependency "apple" (line 9) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/DependencyOrder: `dependency "foo"` (line 10) should be put before `dependency "apple"` (line 9) end RUBY @@ -260,9 +260,9 @@ RSpec.describe RuboCop::Cop::FormulaAudit::DependencyOrder do on_linux do depends_on "apple" if build.with? "foo" depends_on "bar" - ^^^^^^^^^^^^^^^^ FormulaAudit/DependencyOrder: dependency "bar" (line 6) should be put before dependency "apple" (line 5) + ^^^^^^^^^^^^^^^^ FormulaAudit/DependencyOrder: `dependency "bar"` (line 6) should be put before `dependency "apple"` (line 5) depends_on "foo" => :optional - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/DependencyOrder: dependency "foo" (line 7) should be put before dependency "apple" (line 5) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/DependencyOrder: `dependency "foo"` (line 7) should be put before `dependency "apple"` (line 5) end end RUBY diff --git a/Library/Homebrew/test/rubocops/desc_spec.rb b/Library/Homebrew/test/rubocops/desc_spec.rb index 29ecf06de7..173e07033d 100644 --- a/Library/Homebrew/test/rubocops/desc_spec.rb +++ b/Library/Homebrew/test/rubocops/desc_spec.rb @@ -9,7 +9,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::Desc do it "reports an offense when there is no `desc`" do expect_offense(<<~RUBY) class Foo < Formula - ^^^^^^^^^^^^^^^^^^^ FormulaAudit/Desc: Formula should have a desc (Description). + ^^^^^^^^^^^^^^^^^^^ FormulaAudit/Desc: Formula should have a `desc` (description). url 'https://brew.sh/foo-1.0.tgz' end RUBY @@ -20,7 +20,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::Desc do class Foo < Formula url 'https://brew.sh/foo-1.0.tgz' desc '' - ^^^^^^^ FormulaAudit/Desc: The desc (description) should not be an empty string. + ^^^^^^^ FormulaAudit/Desc: The `desc` (description) should not be an empty string. end RUBY end diff --git a/Library/Homebrew/test/rubocops/homepage_spec.rb b/Library/Homebrew/test/rubocops/homepage_spec.rb index 6b845603c4..3857ee4bc8 100644 --- a/Library/Homebrew/test/rubocops/homepage_spec.rb +++ b/Library/Homebrew/test/rubocops/homepage_spec.rb @@ -19,7 +19,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::Homepage do expect_offense(<<~RUBY) class Foo < Formula homepage "ftp://brew.sh/foo" - ^^^^^^^^^^^^^^^^^^^ FormulaAudit/Homepage: The homepage should start with http or https. + ^^^^^^^^^^^^^^^^^^^ FormulaAudit/Homepage: The `homepage` should start with http or https. url "https://brew.sh/foo-1.0.tgz" end RUBY @@ -29,7 +29,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::Homepage do expect_offense(<<~RUBY) class Foo < Formula homepage "http://www.freedesktop.org/wiki/bar" - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/Homepage: Freedesktop homepages should be styled `https://wiki.freedesktop.org/project_name` + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/Homepage: Freedesktop homepages should be styled: https://wiki.freedesktop.org/project_name url "https://brew.sh/foo-1.0.tgz" end RUBY @@ -39,7 +39,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::Homepage do expect_offense(<<~RUBY) class Foo < Formula homepage "http://www.freedesktop.org/wiki/Software/baz" - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/Homepage: Freedesktop homepages should be styled `https://wiki.freedesktop.org/www/Software/project_name` + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/Homepage: Freedesktop homepages should be styled: https://wiki.freedesktop.org/www/Software/project_name url "https://brew.sh/foo-1.0.tgz" end RUBY @@ -79,7 +79,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::Homepage do RUBY end - describe "for Sourceforge" do + describe "for SourceForge" do correct_formula = <<~RUBY class Foo < Formula homepage "https://foo.sourceforge.io/" @@ -91,7 +91,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::Homepage do expect_offense(<<~RUBY) class Foo < Formula homepage "http://foo.sourceforge.net/" - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/Homepage: Sourceforge homepages should be `https://foo.sourceforge.io/` + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/Homepage: SourceForge homepages should be: https://foo.sourceforge.io/ url "https://brew.sh/foo-1.0.tgz" end RUBY @@ -103,7 +103,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::Homepage do expect_offense(<<~RUBY) class Foo < Formula homepage "http://foo.sourceforge.net" - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/Homepage: Sourceforge homepages should be `https://foo.sourceforge.io/` + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/Homepage: SourceForge homepages should be: https://foo.sourceforge.io/ url "https://brew.sh/foo-1.0.tgz" end RUBY @@ -115,7 +115,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::Homepage do expect_offense(<<~RUBY) class Foo < Formula homepage "http://foo.sf.net/" - ^^^^^^^^^^^^^^^^^^^^ FormulaAudit/Homepage: Sourceforge homepages should be `https://foo.sourceforge.io/` + ^^^^^^^^^^^^^^^^^^^^ FormulaAudit/Homepage: SourceForge homepages should be: https://foo.sourceforge.io/ url "https://brew.sh/foo-1.0.tgz" end RUBY @@ -128,7 +128,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::Homepage do expect_offense(<<~RUBY) class Foo < Formula homepage "https://foo.readthedocs.org" - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/Homepage: Readthedocs homepages should be `https://foo.readthedocs.io` + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/Homepage: Readthedocs homepages should be: https://foo.readthedocs.io url "https://brew.sh/foo-1.0.tgz" end RUBY diff --git a/Library/Homebrew/test/rubocops/lines/quictls_check_spec.rb b/Library/Homebrew/test/rubocops/lines/quictls_check_spec.rb index 3ee173448d..81150a2dee 100644 --- a/Library/Homebrew/test/rubocops/lines/quictls_check_spec.rb +++ b/Library/Homebrew/test/rubocops/lines/quictls_check_spec.rb @@ -13,7 +13,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::QuicTLSCheck do url 'https://brew.sh/foo-1.0.tgz' depends_on "quictls" - ^^^^^^^^^^^^^^^^^^^^ FormulaAudit/QuicTLSCheck: Formulae in homebrew/core should use 'depends_on "openssl@3"' instead of 'depends_on "quictls"'. + ^^^^^^^^^^^^^^^^^^^^ FormulaAudit/QuicTLSCheck: Formulae in homebrew/core should use `depends_on "openssl@3"` instead of `depends_on "quictls"`. end RUBY end diff --git a/Library/Homebrew/test/rubocops/options_spec.rb b/Library/Homebrew/test/rubocops/options_spec.rb index 5c1d2d376e..604fd98db7 100644 --- a/Library/Homebrew/test/rubocops/options_spec.rb +++ b/Library/Homebrew/test/rubocops/options_spec.rb @@ -32,7 +32,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::Options do url 'https://brew.sh/foo-1.0.tgz' option :cxx11 option "examples", "with-examples" - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/Options: Options should begin with with/without. Migrate '--examples' with `deprecated_option`. + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/Options: Options should begin with `with` or `without`. Migrate '--examples' with `deprecated_option`. end RUBY end diff --git a/Library/Homebrew/test/rubocops/patches_spec.rb b/Library/Homebrew/test/rubocops/patches_spec.rb index 9f568fd453..00c60d1c2b 100644 --- a/Library/Homebrew/test/rubocops/patches_spec.rb +++ b/Library/Homebrew/test/rubocops/patches_spec.rb @@ -24,7 +24,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::Patches do homepage "ftp://brew.sh/foo" url "https://brew.sh/foo-1.0.tgz" def patches - ^^^^^^^^^^^ FormulaAudit/Patches: Use the patch DSL instead of defining a 'patches' method + ^^^^^^^^^^^ FormulaAudit/Patches: Use the `patch` DSL instead of defining a `patches` method DATA end end @@ -83,7 +83,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::Patches do commit = "b354c009a60bcd6d7fc04014e200a1ee9c45c167" fixed_url = "https://api.bitbucket.org/2.0/repositories/multicoreware/x265_git/diff/#{commit}" expect_offense_hash(message: <<~EOS.chomp, severity: :convention, line: 5, column: 4, source:) - FormulaAudit/Patches: Bitbucket patches should use the api url: #{fixed_url} + FormulaAudit/Patches: Bitbucket patches should use the API URL: #{fixed_url} EOS end expected_offense.zip([inspect_source(source).last]).each do |expected, actual| @@ -112,7 +112,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::Patches do expected_offenses = [ { - message: "FormulaAudit/Patches: Use the patch DSL instead of defining a 'patches' method", + message: "FormulaAudit/Patches: Use the `patch` DSL instead of defining a `patches` method", severity: :convention, line: 4, column: 2, @@ -166,7 +166,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::Patches do class Foo < Formula url 'https://brew.sh/foo-1.0.tgz' patch :DATA - ^^^^^^^^^^^ FormulaAudit/Patches: patch is missing '__END__' + ^^^^^^^^^^^ FormulaAudit/Patches: Patch is missing `__END__` end RUBY end @@ -177,7 +177,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::Patches do url 'https://brew.sh/foo-1.0.tgz' end __END__ - ^^^^^^^ FormulaAudit/Patches: patch is missing 'DATA' + ^^^^^^^ FormulaAudit/Patches: Patch is missing `patch :DATA` patch content here RUBY end diff --git a/Library/Homebrew/test/rubocops/provided_by_macos_spec.rb b/Library/Homebrew/test/rubocops/provided_by_macos_spec.rb index 0fa2145e8c..f43d070b46 100644 --- a/Library/Homebrew/test/rubocops/provided_by_macos_spec.rb +++ b/Library/Homebrew/test/rubocops/provided_by_macos_spec.rb @@ -12,7 +12,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::ProvidedByMacos do homepage "https://brew.sh" keg_only :provided_by_macos - ^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/ProvidedByMacos: Formulae that are `keg_only :provided_by_macos` should be added to the `PROVIDED_BY_MACOS_FORMULAE` list (in the Homebrew/brew repo) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/ProvidedByMacos: Formulae that are `keg_only :provided_by_macos` should be added to the `PROVIDED_BY_MACOS_FORMULAE` list (in the Homebrew/brew repository) end RUBY end diff --git a/Library/Homebrew/test/rubocops/shell_commands_spec.rb b/Library/Homebrew/test/rubocops/shell_commands_spec.rb index bcd8601ea9..6d0e1734ff 100644 --- a/Library/Homebrew/test/rubocops/shell_commands_spec.rb +++ b/Library/Homebrew/test/rubocops/shell_commands_spec.rb @@ -26,19 +26,19 @@ RSpec.describe RuboCop::Cop::Homebrew::ShellCommands do end it "reports and corrects an offense when `system` arguments involving interpolation should be separated" do - expect_offense(<<~RUBY) + expect_offense(<<~'RUBY') class Foo < Formula def install - system "\#{bin}/foo bar" - ^^^^^^^^^^^^^^^^ Homebrew/ShellCommands: Separate `system` commands into `"\#{bin}/foo", "bar"` + system "#{bin}/foo bar" + ^^^^^^^^^^^^^^^^ Homebrew/ShellCommands: Separate `system` commands into `"#{bin}/foo", "bar"` end end RUBY - expect_correction(<<~RUBY) + expect_correction(<<~'RUBY') class Foo < Formula def install - system "\#{bin}/foo", "bar" + system "#{bin}/foo", "bar" end end RUBY @@ -151,19 +151,19 @@ RSpec.describe RuboCop::Cop::Homebrew::ShellCommands do end it "reports and corrects an offense when `Utils.popen_read` arguments with interpolation are unseparated" do - expect_offense(<<~RUBY) + expect_offense(<<~'RUBY') class Foo < Formula def install - Utils.popen_read("\#{bin}/foo bar") - ^^^^^^^^^^^^^^^^ Homebrew/ShellCommands: Separate `Utils.popen_read` commands into `"\#{bin}/foo", "bar"` + Utils.popen_read("#{bin}/foo bar") + ^^^^^^^^^^^^^^^^ Homebrew/ShellCommands: Separate `Utils.popen_read` commands into `"#{bin}/foo", "bar"` end end RUBY - expect_correction(<<~RUBY) + expect_correction(<<~'RUBY') class Foo < Formula def install - Utils.popen_read("\#{bin}/foo", "bar") + Utils.popen_read("#{bin}/foo", "bar") end end RUBY diff --git a/Library/Homebrew/test/rubocops/text/miscellaneous_spec.rb b/Library/Homebrew/test/rubocops/text/miscellaneous_spec.rb index baa6a32e6d..f3f15fecd3 100644 --- a/Library/Homebrew/test/rubocops/text/miscellaneous_spec.rb +++ b/Library/Homebrew/test/rubocops/text/miscellaneous_spec.rb @@ -12,7 +12,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::Miscellaneous do desc "foo" url 'https://brew.sh/foo-1.0.tgz' FileUtils.mv "hello" - ^^^^^^^^^^^^^^^^^^^^ FormulaAudit/Miscellaneous: Don't need 'FileUtils.' before mv + ^^^^^^^^^^^^^^^^^^^^ FormulaAudit/Miscellaneous: No need for `FileUtils.` before `mv` end RUBY end @@ -23,7 +23,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::Miscellaneous do desc "foo" url 'https://brew.sh/foo-1.0.tgz' inreplace "foo" do |longvar| - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/Miscellaneous: "inreplace do |s|" is preferred over "|longvar|". + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/Miscellaneous: `inreplace do |s|` is preferred over `|longvar|`. somerandomCall(longvar) end end @@ -37,7 +37,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::Miscellaneous do url 'https://brew.sh/foo-1.0.tgz' bottle do rebuild 0 - ^^^^^^^^^ FormulaAudit/Miscellaneous: 'rebuild 0' should be removed + ^^^^^^^^^ FormulaAudit/Miscellaneous: `rebuild 0` should be removed sha256 "fe0679b932dd43a87fd415b609a7fbac7a069d117642ae8ebaac46ae1fb9f0b3" => :sierra end end @@ -53,7 +53,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::Miscellaneous do sha256 "fe0679b932dd43a87fd415b609a7fbac7a069d117642ae8ebaac46ae1fb9f0b3" => :sierra end fails_with :llvm do - ^^^^^^^^^^^^^^^^ FormulaAudit/Miscellaneous: 'fails_with :llvm' is now a no-op so should be removed + ^^^^^^^^^^^^^^^^ FormulaAudit/Miscellaneous: `fails_with :llvm` is now a no-op and should be removed build 2335 cause "foo" end @@ -68,7 +68,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::Miscellaneous do url 'https://brew.sh/foo-1.0.tgz' def test - ^^^^^^^^ FormulaAudit/Miscellaneous: Use new-style test definitions (test do) + ^^^^^^^^ FormulaAudit/Miscellaneous: Use new-style test definitions (`test do`) assert_equals "1", "1" end end @@ -165,7 +165,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::Miscellaneous do url 'https://brew.sh/foo-1.0.tgz' rm_rf Dir["src/{llvm,test,librustdoc,etc/snapshot.pyc}"] rm_rf Dir["src/snapshot.pyc"] - ^^^^^^^^^^^^^^^^^^ FormulaAudit/Miscellaneous: Dir(["src/snapshot.pyc"]) is unnecessary; just use "src/snapshot.pyc" + ^^^^^^^^^^^^^^^^^^ FormulaAudit/Miscellaneous: `Dir(["src/snapshot.pyc"])` is unnecessary; just use `src/snapshot.pyc` end RUBY end @@ -184,7 +184,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::Miscellaneous do it "reports an offense when top-level functions are defined outside of a class body" do expect_offense(<<~RUBY) def test - ^^^^^^^^ FormulaAudit/Miscellaneous: Define method test in the class body, not at the top-level + ^^^^^^^^ FormulaAudit/Miscellaneous: Define method `test` in the class body, not at the top-level nil end class Foo < Formula @@ -201,7 +201,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::Miscellaneous do url 'https://brew.sh/foo-1.0.tgz' def install man1.install man+"man8" => "faad.1" - ^^^^^^ FormulaAudit/Miscellaneous: "man+"man8"" should be "man8" + ^^^^^^ FormulaAudit/Miscellaneous: `man+"man8"` should be `man8` end end RUBY @@ -214,7 +214,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::Miscellaneous do url 'https://brew.sh/foo-1.0.tgz' def install system "/usr/bin/gcc", "foo" - ^^^^^^^^^^^^^^ FormulaAudit/Miscellaneous: Use "#{ENV.cc}" instead of hard-coding "gcc" + ^^^^^^^^^^^^^^ FormulaAudit/Miscellaneous: Use `#{ENV.cc}` instead of hard-coding `gcc` end end RUBY @@ -227,7 +227,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::Miscellaneous do url 'https://brew.sh/foo-1.0.tgz' def install system "/usr/bin/g++", "-o", "foo", "foo.cc" - ^^^^^^^^^^^^^^ FormulaAudit/Miscellaneous: Use "#{ENV.cxx}" instead of hard-coding "g++" + ^^^^^^^^^^^^^^ FormulaAudit/Miscellaneous: Use `#{ENV.cxx}` instead of hard-coding `g++` end end RUBY @@ -240,20 +240,20 @@ RSpec.describe RuboCop::Cop::FormulaAudit::Miscellaneous do url 'https://brew.sh/foo-1.0.tgz' def install ENV["COMPILER_PATH"] = "/usr/bin/c++" - ^^^^^^^^^^^^^^ FormulaAudit/Miscellaneous: Use "#{ENV.cxx}" instead of hard-coding "c++" + ^^^^^^^^^^^^^^ FormulaAudit/Miscellaneous: Use `#{ENV.cxx}` instead of hard-coding `c++` end end RUBY end it "reports an offense when a hard-coded `gcc` is set as COMPILER_PATH" do - expect_offense(<<~RUBY) + expect_offense(<<~'RUBY') class Foo < Formula desc "foo" url 'https://brew.sh/foo-1.0.tgz' def install ENV["COMPILER_PATH"] = "/usr/bin/gcc" - ^^^^^^^^^^^^^^ FormulaAudit/Miscellaneous: Use "\#{ENV.cc}" instead of hard-coding "gcc" + ^^^^^^^^^^^^^^ FormulaAudit/Miscellaneous: Use `#{ENV.cc}` instead of hard-coding `gcc` end end RUBY @@ -266,7 +266,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::Miscellaneous do url 'https://brew.sh/foo-1.0.tgz' def install mv "#{share}/man", share - ^^^^ FormulaAudit/Miscellaneous: "#{share}/man" should be "#{man}" + ^^^^ FormulaAudit/Miscellaneous: `#{share}/man` should be `#{man}` end end RUBY @@ -279,7 +279,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::Miscellaneous do url 'https://brew.sh/foo-1.0.tgz' def install mv "#{prefix}/libexec", share - ^^^^^^^^ FormulaAudit/Miscellaneous: "#{prefix}/libexec" should be "#{libexec}" + ^^^^^^^^ FormulaAudit/Miscellaneous: `#{prefix}/libexec` should be `#{libexec}` end end RUBY @@ -292,7 +292,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::Miscellaneous do url 'https://brew.sh/foo-1.0.tgz' def install system "./configure", "--INFODIR=#{prefix}/share/info" - ^^^^^^^^^^^ FormulaAudit/Miscellaneous: "#{prefix}/share/info" should be "#{info}" + ^^^^^^^^^^^ FormulaAudit/Miscellaneous: `#{prefix}/share/info` should be `#{info}` end end RUBY @@ -305,7 +305,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::Miscellaneous do url 'https://brew.sh/foo-1.0.tgz' def install system "./configure", "--MANDIR=#{prefix}/share/man/man8" - ^^^^^^^^^^^^^^^ FormulaAudit/Miscellaneous: "#{prefix}/share/man/man8" should be "#{man8}" + ^^^^^^^^^^^^^^^ FormulaAudit/Miscellaneous: `#{prefix}/share/man/man8` should be `#{man8}` end end RUBY @@ -317,7 +317,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::Miscellaneous do desc "foo" url 'https://brew.sh/foo-1.0.tgz' depends_on "lpeg" => :lua51 - ^^^^^^ FormulaAudit/Miscellaneous: lua modules should be vendored rather than use deprecated `depends_on "lpeg" => :lua51` + ^^^^^^ FormulaAudit/Miscellaneous: lua modules should be vendored rather than using deprecated `depends_on "lpeg" => :lua51` end RUBY end @@ -328,7 +328,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::Miscellaneous do desc "foo" url 'https://brew.sh/foo-1.0.tgz' system "export", "var=value" - ^^^^^^^^ FormulaAudit/Miscellaneous: Use ENV instead of invoking 'export' to modify the environment + ^^^^^^^^ FormulaAudit/Miscellaneous: Use `ENV` instead of invoking `export` to modify the environment end RUBY end @@ -339,7 +339,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::Miscellaneous do desc "foo" url 'https://brew.sh/foo-1.0.tgz' depends_on "foo" => "with-bar" - ^^^^^^^^^^ FormulaAudit/Miscellaneous: Dependency foo should not use option with-bar + ^^^^^^^^^^ FormulaAudit/Miscellaneous: Dependency 'foo' should not use option `with-bar` end RUBY end @@ -351,9 +351,9 @@ RSpec.describe RuboCop::Cop::FormulaAudit::Miscellaneous do url 'https://brew.sh/foo-1.0.tgz' depends_on "httpd" => [:build, :test] depends_on "foo" => [:optional, "with-bar"] - ^^^^^^^^^^ FormulaAudit/Miscellaneous: Dependency foo should not use option with-bar + ^^^^^^^^^^ FormulaAudit/Miscellaneous: Dependency 'foo' should not use option `with-bar` depends_on "icu4c" => [:optional, "c++11"] - ^^^^^^^ FormulaAudit/Miscellaneous: Dependency icu4c should not use option c++11 + ^^^^^^^ FormulaAudit/Miscellaneous: Dependency 'icu4c' should not use option `c++11` end RUBY end @@ -364,7 +364,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::Miscellaneous do desc "foo" url 'https://brew.sh/foo-1.0.tgz' if version == "HEAD" - ^^^^^^^^^^^^^^^^^ FormulaAudit/Miscellaneous: Use 'build.head?' instead of inspecting 'version' + ^^^^^^^^^^^^^^^^^ FormulaAudit/Miscellaneous: Use `build.head?` instead of inspecting `version` foo() end end @@ -378,8 +378,8 @@ RSpec.describe RuboCop::Cop::FormulaAudit::Miscellaneous do url 'https://brew.sh/foo-1.0.tgz' test do head = ARGV.include? "--HEAD" - ^^^^ FormulaAudit/Miscellaneous: Use build instead of ARGV to check options - ^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/Miscellaneous: Use "if build.head?" instead + ^^^^ FormulaAudit/Miscellaneous: Use `build.with?` or `build.without?` instead of `ARGV` to check options + ^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/Miscellaneous: Use `if build.head?` instead end end RUBY @@ -391,7 +391,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::Miscellaneous do desc "foo" url 'https://brew.sh/foo-1.0.tgz' needs :openmp - ^^^^^^^^^^^^^ FormulaAudit/Miscellaneous: 'needs :openmp' should be replaced with 'depends_on "gcc"' + ^^^^^^^^^^^^^ FormulaAudit/Miscellaneous: `needs :openmp` should be replaced with `depends_on "gcc"` end RUBY end @@ -403,7 +403,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::Miscellaneous do url 'https://brew.sh/foo-1.0.tgz' test do version = MACOS_VERSION - ^^^^^^^^^^^^^ FormulaAudit/Miscellaneous: Use MacOS.version instead of MACOS_VERSION + ^^^^^^^^^^^^^ FormulaAudit/Miscellaneous: Use `MacOS.version` instead of `MACOS_VERSION` end end RUBY @@ -415,7 +415,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::Miscellaneous do desc "foo" url 'https://brew.sh/foo-1.0.tgz' depends_on "foo" if build.with? "foo" - ^^^^^^^^^^^^^^^^ FormulaAudit/Miscellaneous: Replace depends_on "foo" if build.with? "foo" with depends_on "foo" => :optional + ^^^^^^^^^^^^^^^^ FormulaAudit/Miscellaneous: Replace `depends_on "foo" if build.with? "foo"` with `depends_on "foo" => :optional` end RUBY end @@ -426,7 +426,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::Miscellaneous do desc "foo" url 'https://brew.sh/foo-1.0.tgz' depends_on :foo unless build.without? "foo" - ^^^^^^^^^^^^^^^ FormulaAudit/Miscellaneous: Replace depends_on :foo unless build.without? "foo" with depends_on :foo => :recommended + ^^^^^^^^^^^^^^^ FormulaAudit/Miscellaneous: Replace `depends_on :foo unless build.without? "foo"` with `depends_on :foo => :recommended` end RUBY end @@ -437,7 +437,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::Miscellaneous do desc "foo" url 'https://brew.sh/foo-1.0.tgz' depends_on :foo unless build.include? "without-foo" - ^^^^^^^^^^^^^^^ FormulaAudit/Miscellaneous: Replace depends_on :foo unless build.include? "without-foo" with depends_on :foo => :recommended + ^^^^^^^^^^^^^^^ FormulaAudit/Miscellaneous: Replace `depends_on :foo unless build.include? "without-foo"` with `depends_on :foo => :recommended` end RUBY end diff --git a/Library/Homebrew/test/rubocops/text/mpi_check_spec.rb b/Library/Homebrew/test/rubocops/text/mpi_check_spec.rb index 986f689c75..0ccedc8c52 100644 --- a/Library/Homebrew/test/rubocops/text/mpi_check_spec.rb +++ b/Library/Homebrew/test/rubocops/text/mpi_check_spec.rb @@ -12,7 +12,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::MpiCheck do desc "foo" url 'https://brew.sh/foo-1.0.tgz' depends_on "mpich" - ^^^^^^^^^^^^^^^^^^ FormulaAudit/MpiCheck: Formulae in homebrew/core should use 'depends_on "open-mpi"' instead of 'depends_on "mpich"'. + ^^^^^^^^^^^^^^^^^^ FormulaAudit/MpiCheck: Formulae in homebrew/core should use `depends_on "open-mpi"` instead of `depends_on "mpich"`. end RUBY diff --git a/Library/Homebrew/test/rubocops/text/on_system_conditionals_spec.rb b/Library/Homebrew/test/rubocops/text/on_system_conditionals_spec.rb index 9757208197..aec211e200 100644 --- a/Library/Homebrew/test/rubocops/text/on_system_conditionals_spec.rb +++ b/Library/Homebrew/test/rubocops/text/on_system_conditionals_spec.rb @@ -11,7 +11,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::OnSystemConditionals do class Foo < Formula desc "foo" if OS.linux? - ^^^^^^^^^^^^ FormulaAudit/OnSystemConditionals: Don't use `if OS.linux?`, use `on_linux do` instead. + ^^^^^^^^^^^^ FormulaAudit/OnSystemConditionals: Instead of `if OS.linux?`, use `on_linux do`. url 'https://brew.sh/linux-1.0.tgz' else url 'https://brew.sh/linux-1.0.tgz' @@ -37,7 +37,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::OnSystemConditionals do class Foo < Formula desc "foo" if OS.mac? - ^^^^^^^^^^ FormulaAudit/OnSystemConditionals: Don't use `if OS.mac?`, use `on_macos do` instead. + ^^^^^^^^^^ FormulaAudit/OnSystemConditionals: Instead of `if OS.mac?`, use `on_macos do`. url 'https://brew.sh/mac-1.0.tgz' else url 'https://brew.sh/linux-1.0.tgz' @@ -66,7 +66,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::OnSystemConditionals do def install on_macos do - ^^^^^^^^ FormulaAudit/OnSystemConditionals: Don't use `on_macos` in `def install`, use `if OS.mac?` instead. + ^^^^^^^^ FormulaAudit/OnSystemConditionals: Instead of using `on_macos` in `def install`, use `if OS.mac?`. true end end @@ -95,7 +95,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::OnSystemConditionals do def install on_linux do - ^^^^^^^^ FormulaAudit/OnSystemConditionals: Don't use `on_linux` in `def install`, use `if OS.linux?` instead. + ^^^^^^^^ FormulaAudit/OnSystemConditionals: Instead of using `on_linux` in `def install`, use `if OS.linux?`. true end end @@ -124,7 +124,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::OnSystemConditionals do test do on_macos do - ^^^^^^^^ FormulaAudit/OnSystemConditionals: Don't use `on_macos` in `test do`, use `if OS.mac?` instead. + ^^^^^^^^ FormulaAudit/OnSystemConditionals: Instead of using `on_macos` in `test do`, use `if OS.mac?`. true end end @@ -152,7 +152,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::OnSystemConditionals do class Foo < Formula desc "foo" if Hardware::CPU.arm? - ^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/OnSystemConditionals: Don't use `if Hardware::CPU.arm?`, use `on_arm do` instead. + ^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/OnSystemConditionals: Instead of `if Hardware::CPU.arm?`, use `on_arm do`. url 'https://brew.sh/linux-1.0.tgz' else url 'https://brew.sh/linux-1.0.tgz' @@ -178,7 +178,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::OnSystemConditionals do class Foo < Formula desc "foo" if Hardware::CPU.intel? - ^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/OnSystemConditionals: Don't use `if Hardware::CPU.intel?`, use `on_intel do` instead. + ^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/OnSystemConditionals: Instead of `if Hardware::CPU.intel?`, use `on_intel do`. url 'https://brew.sh/mac-1.0.tgz' else url 'https://brew.sh/linux-1.0.tgz' @@ -207,7 +207,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::OnSystemConditionals do def install on_intel do - ^^^^^^^^ FormulaAudit/OnSystemConditionals: Don't use `on_intel` in `def install`, use `if Hardware::CPU.intel?` instead. + ^^^^^^^^ FormulaAudit/OnSystemConditionals: Instead of using `on_intel` in `def install`, use `if Hardware::CPU.intel?`. true end end @@ -236,7 +236,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::OnSystemConditionals do def install on_arm do - ^^^^^^ FormulaAudit/OnSystemConditionals: Don't use `on_arm` in `def install`, use `if Hardware::CPU.arm?` instead. + ^^^^^^ FormulaAudit/OnSystemConditionals: Instead of using `on_arm` in `def install`, use `if Hardware::CPU.arm?`. true end end @@ -265,7 +265,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::OnSystemConditionals do test do on_intel do - ^^^^^^^^ FormulaAudit/OnSystemConditionals: Don't use `on_intel` in `test do`, use `if Hardware::CPU.intel?` instead. + ^^^^^^^^ FormulaAudit/OnSystemConditionals: Instead of using `on_intel` in `test do`, use `if Hardware::CPU.intel?`. true end end @@ -293,7 +293,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::OnSystemConditionals do class Foo < Formula desc "foo" if MacOS.version == :monterey - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/OnSystemConditionals: Don't use `if MacOS.version == :monterey`, use `on_monterey do` instead. + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/OnSystemConditionals: Instead of `if MacOS.version == :monterey`, use `on_monterey do`. url 'https://brew.sh/linux-1.0.tgz' end end @@ -314,7 +314,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::OnSystemConditionals do class Foo < Formula desc "foo" if MacOS.version <= :monterey - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/OnSystemConditionals: Don't use `if MacOS.version <= :monterey`, use `on_system :linux, macos: :monterey_or_older do` instead. + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/OnSystemConditionals: Instead of `if MacOS.version <= :monterey`, use `on_system :linux, macos: :monterey_or_older do`. url 'https://brew.sh/mac-1.0.tgz' end end @@ -335,7 +335,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::OnSystemConditionals do class Foo < Formula desc "foo" if MacOS.version < :monterey - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/OnSystemConditionals: Don't use `if MacOS.version < :monterey`, use `on_system do` instead. + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/OnSystemConditionals: Instead of `if MacOS.version < :monterey`, use `on_system do`. url 'https://brew.sh/mac-1.0.tgz' end end @@ -347,7 +347,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::OnSystemConditionals do class Foo < Formula desc "foo" if MacOS.version >= :monterey - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/OnSystemConditionals: Don't use `if MacOS.version >= :monterey`, use `on_monterey :or_newer do` instead. + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/OnSystemConditionals: Instead of `if MacOS.version >= :monterey`, use `on_monterey :or_newer do`. url 'https://brew.sh/mac-1.0.tgz' else url 'https://brew.sh/linux-1.0.tgz' @@ -361,7 +361,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::OnSystemConditionals do class Foo < Formula desc "foo" if MacOS.version > :monterey - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/OnSystemConditionals: Don't use `if MacOS.version > :monterey`, use `on_monterey do` instead. + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/OnSystemConditionals: Instead of `if MacOS.version > :monterey`, use `on_monterey do`. url 'https://brew.sh/mac-1.0.tgz' end end @@ -376,7 +376,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::OnSystemConditionals do def install on_monterey do - ^^^^^^^^^^^ FormulaAudit/OnSystemConditionals: Don't use `on_monterey` in `def install`, use `if MacOS.version == :monterey` instead. + ^^^^^^^^^^^ FormulaAudit/OnSystemConditionals: Instead of using `on_monterey` in `def install`, use `if MacOS.version == :monterey`. true end end @@ -405,7 +405,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::OnSystemConditionals do def install on_monterey :or_older do - ^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/OnSystemConditionals: Don't use `on_monterey :or_older` in `def install`, use `if MacOS.version <= :monterey` instead. + ^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/OnSystemConditionals: Instead of using `on_monterey :or_older` in `def install`, use `if MacOS.version <= :monterey`. true end end @@ -434,7 +434,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::OnSystemConditionals do def install on_monterey :or_newer do - ^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/OnSystemConditionals: Don't use `on_monterey :or_newer` in `def install`, use `if MacOS.version >= :monterey` instead. + ^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/OnSystemConditionals: Instead of using `on_monterey :or_newer` in `def install`, use `if MacOS.version >= :monterey`. true end end @@ -463,7 +463,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::OnSystemConditionals do def install on_system :linux, macos: :monterey_or_newer do - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/OnSystemConditionals: Don't use `on_system :linux, macos: :monterey_or_newer` in `def install`, use `if OS.linux? || MacOS.version >= :monterey` instead. + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/OnSystemConditionals: Instead of using `on_system :linux, macos: :monterey_or_newer` in `def install`, use `if OS.linux? || MacOS.version >= :monterey`. true end end @@ -492,7 +492,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::OnSystemConditionals do test do on_monterey do - ^^^^^^^^^^^ FormulaAudit/OnSystemConditionals: Don't use `on_monterey` in `test do`, use `if MacOS.version == :monterey` instead. + ^^^^^^^^^^^ FormulaAudit/OnSystemConditionals: Instead of using `on_monterey` in `test do`, use `if MacOS.version == :monterey`. true end end @@ -521,7 +521,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::OnSystemConditionals do test do on_system :linux, macos: :monterey do - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/OnSystemConditionals: Don't use `on_system :linux, macos: :monterey` in `test do`, use `if OS.linux? || MacOS.version == :monterey` instead. + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/OnSystemConditionals: Instead of using `on_system :linux, macos: :monterey` in `test do`, use `if OS.linux? || MacOS.version == :monterey`. true end end diff --git a/Library/Homebrew/test/rubocops/text/option_declarations_spec.rb b/Library/Homebrew/test/rubocops/text/option_declarations_spec.rb index b14e6daafd..34f4b668a7 100644 --- a/Library/Homebrew/test/rubocops/text/option_declarations_spec.rb +++ b/Library/Homebrew/test/rubocops/text/option_declarations_spec.rb @@ -57,7 +57,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::OptionDeclarations do url 'https://brew.sh/foo-1.0.tgz' def post_install return unless build.without? "bar" - ^^^^^^^^^^^^^^^^^^^^ FormulaAudit/OptionDeclarations: Use if build.with? "bar" instead of unless build.without? "bar" + ^^^^^^^^^^^^^^^^^^^^ FormulaAudit/OptionDeclarations: Use `if build.with? "bar"` instead of `unless build.without? "bar"` end end RUBY @@ -70,7 +70,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::OptionDeclarations do url 'https://brew.sh/foo-1.0.tgz' def post_install return unless build.with? "bar" - ^^^^^^^^^^^^^^^^^ FormulaAudit/OptionDeclarations: Use if build.without? "bar" instead of unless build.with? "bar" + ^^^^^^^^^^^^^^^^^ FormulaAudit/OptionDeclarations: Use `if build.without? "bar"` instead of `unless build.with? "bar"` end end RUBY @@ -83,7 +83,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::OptionDeclarations do url 'https://brew.sh/foo-1.0.tgz' def post_install return if !build.with? "bar" - ^^^^^^^^^^^^^^^^^^ FormulaAudit/OptionDeclarations: Don't negate 'build.with?': use 'build.without?' + ^^^^^^^^^^^^^^^^^^ FormulaAudit/OptionDeclarations: Instead of negating `build.with?`, use `build.without?` end end RUBY @@ -96,7 +96,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::OptionDeclarations do url 'https://brew.sh/foo-1.0.tgz' def post_install return if !build.without? "bar" - ^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/OptionDeclarations: Don't negate 'build.without?': use 'build.with?' + ^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/OptionDeclarations: Instead of negating `build.without?`, use `build.with?` end end RUBY @@ -109,7 +109,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::OptionDeclarations do url 'https://brew.sh/foo-1.0.tgz' def post_install return if build.without? "--without-bar" - ^^^^^^^^^^^^^^^ FormulaAudit/OptionDeclarations: Don't duplicate 'without': Use `build.without? "bar"` to check for "--without-bar" + ^^^^^^^^^^^^^^^ FormulaAudit/OptionDeclarations: Instead of duplicating `without`, use `build.without? "bar"` to check for "--without-bar" end end RUBY @@ -122,7 +122,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::OptionDeclarations do url 'https://brew.sh/foo-1.0.tgz' def post_install return if build.with? "--with-bar" - ^^^^^^^^^^^^ FormulaAudit/OptionDeclarations: Don't duplicate 'with': Use `build.with? "bar"` to check for "--with-bar" + ^^^^^^^^^^^^ FormulaAudit/OptionDeclarations: Instead of duplicating `with`, use `build.with? "bar"` to check for '--with-bar' end end RUBY diff --git a/Library/Homebrew/test/rubocops/text/shell_variables_spec.rb b/Library/Homebrew/test/rubocops/text/shell_variables_spec.rb index ddf39dc3cc..aa7c7b9100 100644 --- a/Library/Homebrew/test/rubocops/text/shell_variables_spec.rb +++ b/Library/Homebrew/test/rubocops/text/shell_variables_spec.rb @@ -64,19 +64,19 @@ RSpec.describe RuboCop::Cop::FormulaAudit::ShellVariables do end it "reports and corrects unexpanded shell variables while preserving string interpolation" do - expect_offense(<<~RUBY) + expect_offense(<<~'RUBY') class Foo < Formula def install - Utils.popen "SHELL=bash \#{bin}/foo" - ^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/ShellVariables: Use `Utils.popen({ "SHELL" => "bash" }, "\#{bin}/foo")` instead of `Utils.popen "SHELL=bash \#{bin}/foo"` + Utils.popen "SHELL=bash #{bin}/foo" + ^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/ShellVariables: Use `Utils.popen({ "SHELL" => "bash" }, "#{bin}/foo")` instead of `Utils.popen "SHELL=bash #{bin}/foo"` end end RUBY - expect_correction(<<~RUBY) + expect_correction(<<~'RUBY') class Foo < Formula def install - Utils.popen({ "SHELL" => "bash" }, "\#{bin}/foo") + Utils.popen({ "SHELL" => "bash" }, "#{bin}/foo") end end RUBY diff --git a/Library/Homebrew/test/rubocops/text/std_npm_args_spec.rb b/Library/Homebrew/test/rubocops/text/std_npm_args_spec.rb index c0bb9e97ed..2c5ea62337 100644 --- a/Library/Homebrew/test/rubocops/text/std_npm_args_spec.rb +++ b/Library/Homebrew/test/rubocops/text/std_npm_args_spec.rb @@ -22,7 +22,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::StdNpmArgs do class Foo < Formula def install system "npm", "install", *Language::Node.local_npm_install_args, "--production" - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/StdNpmArgs: Use 'std_npm_args' instead of 'local_npm_install_args'. + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/StdNpmArgs: Use `std_npm_args` instead of `local_npm_install_args`. end end RUBY @@ -41,7 +41,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::StdNpmArgs do class Foo < Formula def install system "npm", "install", *Language::Node.std_npm_install_args(libexec), "--production" - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/StdNpmArgs: Use 'std_npm_args' instead of 'std_npm_install_args'. + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/StdNpmArgs: Use `std_npm_args` instead of `std_npm_install_args`. end end RUBY @@ -60,7 +60,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::StdNpmArgs do class Foo < Formula def install system "npm", "install", *Language::Node.std_npm_install_args(buildpath), "--production" - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/StdNpmArgs: Use 'std_npm_args' instead of 'std_npm_install_args'. + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/StdNpmArgs: Use `std_npm_args` instead of `std_npm_install_args`. end end RUBY diff --git a/Library/Homebrew/test/rubocops/text/strict_spec.rb b/Library/Homebrew/test/rubocops/text/strict_spec.rb index dde8271967..b57143c46b 100644 --- a/Library/Homebrew/test/rubocops/text/strict_spec.rb +++ b/Library/Homebrew/test/rubocops/text/strict_spec.rb @@ -29,29 +29,29 @@ RSpec.describe RuboCop::Cop::FormulaAuditStrict::Text do end it %Q(reports an offense if "\#{share}/" is present) do - expect_offense(<<~RUBY, "/homebrew-core/Formula/foo.rb") + expect_offense(<<~'RUBY', "/homebrew-core/Formula/foo.rb") class Foo < Formula def install - ohai "\#{share}/foo" - ^^^^^^^^^^^^^^ FormulaAuditStrict/Text: Use `\#{pkgshare}` instead of `\#{share}/foo` + ohai "#{share}/foo" + ^^^^^^^^^^^^^^ FormulaAuditStrict/Text: Use `#{pkgshare}` instead of `#{share}/foo` end end RUBY - expect_offense(<<~RUBY, "/homebrew-core/Formula/foo.rb") + expect_offense(<<~'RUBY', "/homebrew-core/Formula/foo.rb") class Foo < Formula def install - ohai "\#{share}/foo/bar" - ^^^^^^^^^^^^^^^^^^ FormulaAuditStrict/Text: Use `\#{pkgshare}` instead of `\#{share}/foo` + ohai "#{share}/foo/bar" + ^^^^^^^^^^^^^^^^^^ FormulaAuditStrict/Text: Use `#{pkgshare}` instead of `#{share}/foo` end end RUBY - expect_offense(<<~RUBY, "/homebrew-core/Formula/foolibc++.rb") + expect_offense(<<~'RUBY', "/homebrew-core/Formula/foolibc++.rb") class Foolibcxx < Formula def install - ohai "\#{share}/foolibc++" - ^^^^^^^^^^^^^^^^^^^^ FormulaAuditStrict/Text: Use `\#{pkgshare}` instead of `\#{share}/foolibc++` + ohai "#{share}/foolibc++" + ^^^^^^^^^^^^^^^^^^^^ FormulaAuditStrict/Text: Use `#{pkgshare}` instead of `#{share}/foolibc++` end end RUBY @@ -87,10 +87,10 @@ RSpec.describe RuboCop::Cop::FormulaAuditStrict::Text do end it %Q(reports no offenses if "\#{share}/" doesn't match formula name) do - expect_no_offenses(<<~RUBY, "/homebrew-core/Formula/foo.rb") + expect_no_offenses(<<~'RUBY', "/homebrew-core/Formula/foo.rb") class Foo < Formula def install - ohai "\#{share}/foo-bar" + ohai "#{share}/foo-bar" end end RUBY @@ -123,10 +123,10 @@ RSpec.describe RuboCop::Cop::FormulaAuditStrict::Text do end it %Q(reports no offenses if formula name appears after "\#{share}/") do - expect_no_offenses(<<~RUBY, "/homebrew-core/Formula/foo.rb") + expect_no_offenses(<<~'RUBY', "/homebrew-core/Formula/foo.rb") class Foo < Formula def install - ohai "\#{share}/bar/foo" + ohai "#{share}/bar/foo" end end RUBY @@ -134,13 +134,13 @@ RSpec.describe RuboCop::Cop::FormulaAuditStrict::Text do context "for interpolated bin paths" do it 'reports an offense & autocorrects if "\#{bin}/" or other dashed binaries too are present' do - expect_offense(<<~RUBY, "/homebrew-core/Formula/foo.rb") + expect_offense(<<~'RUBY', "/homebrew-core/Formula/foo.rb") class Foo < Formula test do - system "\#{bin}/foo", "-v" - ^^^^^^^^^^^^ FormulaAuditStrict/Text: Use `bin/"foo"` instead of `"\#{bin}/foo"` - system "\#{bin}/foo-bar", "-v" - ^^^^^^^^^^^^^^^^ FormulaAuditStrict/Text: Use `bin/"foo-bar"` instead of `"\#{bin}/foo-bar"` + system "#{bin}/foo", "-v" + ^^^^^^^^^^^^ FormulaAuditStrict/Text: Use `bin/"foo"` instead of `"#{bin}/foo"` + system "#{bin}/foo-bar", "-v" + ^^^^^^^^^^^^^^^^ FormulaAuditStrict/Text: Use `bin/"foo-bar"` instead of `"#{bin}/foo-bar"` end end RUBY @@ -156,12 +156,12 @@ RSpec.describe RuboCop::Cop::FormulaAuditStrict::Text do end it 'does not report an offense if \#{bin}/foo and then a space and more text' do - expect_no_offenses(<<~RUBY, "/homebrew-core/Formula/foo.rb") + expect_no_offenses(<<~'RUBY', "/homebrew-core/Formula/foo.rb") class Foo < Formula test do - shell_output("\#{bin}/foo --version") - assert_match "help", shell_output("\#{bin}/foo-something --help 2>&1") - assert_match "OK", shell_output("\#{bin}/foo-something_else --check 2>&1") + shell_output("#{bin}/foo --version") + assert_match "help", shell_output("#{bin}/foo-something --help 2>&1") + assert_match "OK", shell_output("#{bin}/foo-something_else --check 2>&1") end end RUBY @@ -169,11 +169,11 @@ RSpec.describe RuboCop::Cop::FormulaAuditStrict::Text do end it 'does not report an offense if "\#{bin}/foo" is in a word array' do - expect_no_offenses(<<~RUBY, "/homebrew-core/Formula/foo.rb") + expect_no_offenses(<<~'RUBY', "/homebrew-core/Formula/foo.rb") class Foo < Formula test do cmd = %W[ - \#{bin}/foo + #{bin}/foo version ] assert_match version.to_s, shell_output(cmd) diff --git a/Library/Homebrew/test/rubocops/text_spec.rb b/Library/Homebrew/test/rubocops/text_spec.rb index df7dc19b4b..f45b917da5 100644 --- a/Library/Homebrew/test/rubocops/text_spec.rb +++ b/Library/Homebrew/test/rubocops/text_spec.rb @@ -30,7 +30,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::Text do url "https://brew.sh/foo-1.0.tgz" homepage "https://brew.sh" revision 0 - ^^^^^^^^^^ FormulaAudit/Text: "revision 0" is unnecessary + ^^^^^^^^^^ FormulaAudit/Text: `revision 0` is unnecessary end RUBY end @@ -103,7 +103,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::Text do def install system "xcodebuild", "foo", "bar" - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/Text: use "xcodebuild *args" instead of "system 'xcodebuild', *args" + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/Text: Use `xcodebuild *args` instead of `system 'xcodebuild', *args` end end RUBY @@ -117,7 +117,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::Text do def install system "xcodebuild", "foo", "bar" - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/Text: use "xcodebuild *args" instead of "system 'xcodebuild', *args" + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/Text: Use `xcodebuild *args` instead of `system 'xcodebuild', *args` end def plist @@ -140,7 +140,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::Text do it 'reports an offense if `require "language/go"` is present' do expect_offense(<<~RUBY) require "language/go" - ^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/Text: require "language/go" is no longer necessary or correct + ^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/Text: `require "language/go"` is no longer necessary or correct class Foo < Formula url "https://brew.sh/foo-1.0.tgz" @@ -162,7 +162,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::Text do def install Formula.factory(name) - ^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/Text: "Formula.factory(name)" is deprecated in favor of "Formula[name]" + ^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/Text: `Formula.factory(name)` is deprecated in favour of `Formula[name]` end end RUBY @@ -176,7 +176,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::Text do def install system "dep", "ensure" - ^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/Text: use "dep", "ensure", "-vendor-only" + ^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/Text: Use `"dep", "ensure", "-vendor-only"` end end RUBY @@ -190,7 +190,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::Text do def install system "cargo", "build" - ^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/Text: use "cargo", "install", *std_cargo_args + ^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/Text: Use `"cargo", "install", *std_cargo_args` end end RUBY @@ -221,10 +221,10 @@ RSpec.describe RuboCop::Cop::FormulaAudit::Text do end it "reports an offense if paths are concatenated in string interpolation" do - expect_offense(<<~RUBY) + expect_offense(<<~'RUBY') class Foo < Formula def install - ohai "foo \#{bar + "baz"}" + ohai "foo #{bar + "baz"}" ^^^^^^^^^^^^^^ FormulaAudit/Text: Do not concatenate paths in string interpolation end end diff --git a/Library/Homebrew/test/rubocops/urls/git_spec.rb b/Library/Homebrew/test/rubocops/urls/git_spec.rb index c95deae3e2..329b3b8d86 100644 --- a/Library/Homebrew/test/rubocops/urls/git_spec.rb +++ b/Library/Homebrew/test/rubocops/urls/git_spec.rb @@ -55,7 +55,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::GitUrls do class Foo < Formula desc "foo" url "https://github.com/foo/bar.git", - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/GitUrls: Formulae in homebrew/core should specify a revision for git URLs + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/GitUrls: Formulae in homebrew/core should specify a revision for Git URLs tag: "v1.0.0" end RUBY @@ -66,7 +66,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::GitUrls do class Foo < Formula desc "foo" url "https://github.com/foo/bar.git", - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/GitUrls: Formulae in homebrew/core should specify a revision for git URLs + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/GitUrls: Formulae in homebrew/core should specify a revision for Git URLs shallow: false, tag: "v1.0.0" end diff --git a/Library/Homebrew/test/rubocops/urls/git_strict_spec.rb b/Library/Homebrew/test/rubocops/urls/git_strict_spec.rb index 1e511173d1..5015133cda 100644 --- a/Library/Homebrew/test/rubocops/urls/git_strict_spec.rb +++ b/Library/Homebrew/test/rubocops/urls/git_strict_spec.rb @@ -46,7 +46,7 @@ RSpec.describe RuboCop::Cop::FormulaAuditStrict::GitUrls do class Foo < Formula desc "foo" url "https://github.com/foo/bar.git", - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAuditStrict/GitUrls: Formulae in homebrew/core should specify a tag for git URLs + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAuditStrict/GitUrls: Formulae in homebrew/core should specify a tag for Git URLs revision: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" end RUBY @@ -57,7 +57,7 @@ RSpec.describe RuboCop::Cop::FormulaAuditStrict::GitUrls do class Foo < Formula desc "foo" url "https://github.com/foo/bar.git", - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAuditStrict/GitUrls: Formulae in homebrew/core should specify a tag for git URLs + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAuditStrict/GitUrls: Formulae in homebrew/core should specify a tag for Git URLs revision: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", shallow: false end diff --git a/Library/Homebrew/test/rubocops/urls/pypi_spec.rb b/Library/Homebrew/test/rubocops/urls/pypi_spec.rb index f4d1186ead..a7f35253f9 100644 --- a/Library/Homebrew/test/rubocops/urls/pypi_spec.rb +++ b/Library/Homebrew/test/rubocops/urls/pypi_spec.rb @@ -11,7 +11,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::PyPiUrls do class Foo < Formula desc "foo" url "https://pypi.python.org/packages/source/foo/foo-0.1.tar.gz" - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/PyPiUrls: use the `Source` url found on PyPI downloads page (`https://pypi.org/project/foo/#files`) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/PyPiUrls: Use the "Source" URL found on the PyPI downloads page (https://pypi.org/project/foo/#files) end RUBY end @@ -21,7 +21,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::PyPiUrls do class Foo < Formula desc "foo" url "https://files.pythonhosted.org/packages/source/f/foo/foo-0.1.tar.gz" - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/PyPiUrls: use the `Source` url found on PyPI downloads page (`https://pypi.org/project/foo/#files`) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/PyPiUrls: Use the "Source" URL found on the PyPI downloads page (https://pypi.org/project/foo/#files) end RUBY end diff --git a/Library/Homebrew/test/rubocops/urls_spec.rb b/Library/Homebrew/test/rubocops/urls_spec.rb index fab6d84ada..393d52a6b4 100644 --- a/Library/Homebrew/test/rubocops/urls_spec.rb +++ b/Library/Homebrew/test/rubocops/urls_spec.rb @@ -8,11 +8,12 @@ RSpec.describe RuboCop::Cop::FormulaAudit::Urls do let(:offense_list) do [{ "url" => "https://ftpmirror.gnu.org/lightning/lightning-2.1.0.tar.gz", - "msg" => 'Please use "https://ftp.gnu.org/gnu/lightning/lightning-2.1.0.tar.gz" instead of https://ftpmirror.gnu.org/lightning/lightning-2.1.0.tar.gz.', + "msg" => "https://ftpmirror.gnu.org/lightning/lightning-2.1.0.tar.gz should be: " \ + "https://ftp.gnu.org/gnu/lightning/lightning-2.1.0.tar.gz", "col" => 2, }, { "url" => "https://fossies.org/linux/privat/monit-5.23.0.tar.gz", - "msg" => "Please don't use fossies.org in the url (using as a mirror is fine)", + "msg" => "Please don't use \"fossies.org\" in the `url` (using as a mirror is fine)", "col" => 2, }, { "url" => "http://tools.ietf.org/tools/rfcmarkup/rfcmarkup-1.119.tgz", @@ -20,23 +21,23 @@ RSpec.describe RuboCop::Cop::FormulaAudit::Urls do "col" => 2, }, { "url" => "https://apache.org/dyn/closer.cgi?path=/apr/apr-1.7.0.tar.bz2", - "msg" => "https://apache.org/dyn/closer.cgi?path=/apr/apr-1.7.0.tar.bz2 should be " \ - "`https://www.apache.org/dyn/closer.lua?path=apr/apr-1.7.0.tar.bz2`", + "msg" => "https://apache.org/dyn/closer.cgi?path=/apr/apr-1.7.0.tar.bz2 should be: " \ + "https://www.apache.org/dyn/closer.lua?path=apr/apr-1.7.0.tar.bz2", "col" => 2, }, { "url" => "http://search.mcpan.org/CPAN/authors/id/Z/ZE/ZEFRAM/Perl4-CoreLibs-0.003.tar.gz", - "msg" => "http://search.mcpan.org/CPAN/authors/id/Z/ZE/ZEFRAM/Perl4-CoreLibs-0.003.tar.gz should be " \ - "`https://cpan.metacpan.org/authors/id/Z/ZE/ZEFRAM/Perl4-CoreLibs-0.003.tar.gz`", + "msg" => "http://search.mcpan.org/CPAN/authors/id/Z/ZE/ZEFRAM/Perl4-CoreLibs-0.003.tar.gz should be: " \ + "https://cpan.metacpan.org/authors/id/Z/ZE/ZEFRAM/Perl4-CoreLibs-0.003.tar.gz", "col" => 2, }, { "url" => "http://ftp.gnome.org/pub/GNOME/binaries/mac/banshee/banshee-2.macosx.intel.dmg", - "msg" => "http://ftp.gnome.org/pub/GNOME/binaries/mac/banshee/banshee-2.macosx.intel.dmg should be " \ - "`https://download.gnome.org/binaries/mac/banshee/banshee-2.macosx.intel.dmg`", + "msg" => "http://ftp.gnome.org/pub/GNOME/binaries/mac/banshee/banshee-2.macosx.intel.dmg should be: " \ + "https://download.gnome.org/binaries/mac/banshee/banshee-2.macosx.intel.dmg", "col" => 2, }, { "url" => "git://anonscm.debian.org/users/foo/foostrap.git", - "msg" => "git://anonscm.debian.org/users/foo/foostrap.git should be " \ - "`https://anonscm.debian.org/git/users/foo/foostrap.git`", + "msg" => "git://anonscm.debian.org/users/foo/foostrap.git should be: " \ + "https://anonscm.debian.org/git/users/foo/foostrap.git", "col" => 2, }, { "url" => "ftp://ftp.mirrorservice.org/foo-1.tar.gz", @@ -44,31 +45,31 @@ RSpec.describe RuboCop::Cop::FormulaAudit::Urls do "col" => 2, }, { "url" => "ftp://ftp.cpan.org/pub/CPAN/foo-1.tar.gz", - "msg" => "ftp://ftp.cpan.org/pub/CPAN/foo-1.tar.gz should be `http://search.cpan.org/CPAN/foo-1.tar.gz`", + "msg" => "ftp://ftp.cpan.org/pub/CPAN/foo-1.tar.gz should be: http://search.cpan.org/CPAN/foo-1.tar.gz", "col" => 2, }, { "url" => "http://sourceforge.net/projects/something/files/Something-1.2.3.dmg", - "msg" => "Use https://downloads.sourceforge.net to get geolocation (url is " \ + "msg" => "Use \"https://downloads.sourceforge.net\" to get geolocation (`url` is " \ "http://sourceforge.net/projects/something/files/Something-1.2.3.dmg).", "col" => 2, }, { "url" => "https://downloads.sourceforge.net/project/foo/download", - "msg" => "Don't use /download in SourceForge urls (url is " \ + "msg" => "Don't use \"/download\" in SourceForge URLs (`url` is " \ "https://downloads.sourceforge.net/project/foo/download).", "col" => 2, }, { "url" => "https://sourceforge.net/project/foo", - "msg" => "Use https://downloads.sourceforge.net to get geolocation " \ - "(url is https://sourceforge.net/project/foo).", + "msg" => "Use \"https://downloads.sourceforge.net\" to get geolocation (`url` is " \ + "https://sourceforge.net/project/foo).", "col" => 2, }, { "url" => "http://prdownloads.sourceforge.net/foo/foo-1.tar.gz", - "msg" => "Don't use prdownloads in SourceForge urls " \ - "(url is http://prdownloads.sourceforge.net/foo/foo-1.tar.gz).", + "msg" => "Don't use \"prdownloads\" in SourceForge URLs (`url` is " \ + "http://prdownloads.sourceforge.net/foo/foo-1.tar.gz).", "col" => 2, }, { "url" => "http://foo.dl.sourceforge.net/sourceforge/foozip/foozip_1.0.tar.bz2", - "msg" => "Don't use specific dl mirrors in SourceForge urls (url is " \ + "msg" => "Don't use specific \"dl\" mirrors in SourceForge URLs (`url` is " \ "http://foo.dl.sourceforge.net/sourceforge/foozip/foozip_1.0.tar.bz2).", "col" => 2, }, { @@ -129,7 +130,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::Urls do "col" => 2, }, { "url" => "https://github.com/foo/bar/tarball/v1.2.3", - "msg" => "Use /archive/ URLs for GitHub tarballs (url is https://github.com/foo/bar/tarball/v1.2.3).", + "msg" => "Use /archive/ URLs for GitHub tarballs (`url` is https://github.com/foo/bar/tarball/v1.2.3).", "col" => 2, }, { "url" => "https://codeload.github.com/foo/bar/tar.gz/v0.1.1", @@ -142,8 +143,8 @@ RSpec.describe RuboCop::Cop::FormulaAudit::Urls do "col" => 2, }, { "url" => "https://central.maven.org/maven2/com/bar/foo/1.1/foo-1.1.jar", - "msg" => "https://central.maven.org/maven2/com/bar/foo/1.1/foo-1.1.jar should be " \ - "`https://search.maven.org/remotecontent?filepath=com/bar/foo/1.1/foo-1.1.jar`", + "msg" => "https://central.maven.org/maven2/com/bar/foo/1.1/foo-1.1.jar should be: " \ + "https://search.maven.org/remotecontent?filepath=com/bar/foo/1.1/foo-1.1.jar", "col" => 2, }, { "url" => "https://brew.sh/example-darwin.x86_64.tar.gz", @@ -159,31 +160,31 @@ RSpec.describe RuboCop::Cop::FormulaAudit::Urls do "formula_tap" => "homebrew-core", }, { "url" => "cvs://brew.sh/foo/bar", - "msg" => "Use of the cvs:// scheme is deprecated, pass `:using => :cvs` instead", + "msg" => "Use of the \"cvs://\" scheme is deprecated, pass `using: :cvs` instead", "col" => 2, }, { "url" => "bzr://brew.sh/foo/bar", - "msg" => "Use of the bzr:// scheme is deprecated, pass `:using => :bzr` instead", + "msg" => "Use of the \"bzr://\" scheme is deprecated, pass `using: :bzr` instead", "col" => 2, }, { "url" => "hg://brew.sh/foo/bar", - "msg" => "Use of the hg:// scheme is deprecated, pass `:using => :hg` instead", + "msg" => "Use of the \"hg://\" scheme is deprecated, pass `using: :hg` instead", "col" => 2, }, { "url" => "fossil://brew.sh/foo/bar", - "msg" => "Use of the fossil:// scheme is deprecated, pass `:using => :fossil` instead", + "msg" => "Use of the \"fossil://\" scheme is deprecated, pass `using: :fossil` instead", "col" => 2, }, { "url" => "svn+http://brew.sh/foo/bar", - "msg" => "Use of the svn+http:// scheme is deprecated, pass `:using => :svn` instead", + "msg" => "Use of the \"svn+http://\" scheme is deprecated, pass `using: :svn` instead", "col" => 2, }, { "url" => "https://🫠.sh/foo/bar", - "msg" => "Please use the ASCII (Punycode encoded host, URL-encoded path and query) version of https://🫠.sh/foo/bar.", + "msg" => "Please use the ASCII (Punycode-encoded host, URL-encoded path and query) version of https://🫠.sh/foo/bar.", "col" => 2, }, { "url" => "https://ßrew.sh/foo/bar", - "msg" => "Please use the ASCII (Punycode encoded host, URL-encoded path and query) version of https://ßrew.sh/foo/bar.", + "msg" => "Please use the ASCII (Punycode-encoded host, URL-encoded path and query) version of https://ßrew.sh/foo/bar.", "col" => 2, }] end diff --git a/Library/Homebrew/test/rubocops/uses_from_macos_spec.rb b/Library/Homebrew/test/rubocops/uses_from_macos_spec.rb index 5d00eb4f7c..7bd5e15349 100644 --- a/Library/Homebrew/test/rubocops/uses_from_macos_spec.rb +++ b/Library/Homebrew/test/rubocops/uses_from_macos_spec.rb @@ -13,7 +13,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::UsesFromMacos do homepage "https://brew.sh" uses_from_macos "postgresql" - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/UsesFromMacos: `uses_from_macos` should only be used for macOS dependencies, not postgresql. + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/UsesFromMacos: `uses_from_macos` should only be used for macOS dependencies, not 'postgresql'. end RUBY end @@ -25,10 +25,10 @@ RSpec.describe RuboCop::Cop::FormulaAudit::UsesFromMacos do homepage "https://brew.sh" uses_from_macos "boost" - ^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/UsesFromMacos: `uses_from_macos` should only be used for macOS dependencies, not boost. + ^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/UsesFromMacos: `uses_from_macos` should only be used for macOS dependencies, not 'boost'. uses_from_macos "bzip2" uses_from_macos "postgresql" - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/UsesFromMacos: `uses_from_macos` should only be used for macOS dependencies, not postgresql. + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FormulaAudit/UsesFromMacos: `uses_from_macos` should only be used for macOS dependencies, not 'postgresql'. uses_from_macos "zlib" end RUBY diff --git a/Library/Homebrew/test/rubocops/version_spec.rb b/Library/Homebrew/test/rubocops/version_spec.rb index c4c9dfef1e..1f8329db49 100644 --- a/Library/Homebrew/test/rubocops/version_spec.rb +++ b/Library/Homebrew/test/rubocops/version_spec.rb @@ -11,7 +11,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::Version do class Foo < Formula url 'https://brew.sh/foo-1.0.tgz' version "" - ^^^^^^^^^^ FormulaAudit/Version: version is set to an empty string + ^^^^^^^^^^ FormulaAudit/Version: Version is set to an empty string end RUBY end @@ -21,7 +21,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::Version do class Foo < Formula url 'https://brew.sh/foo-1.0.tgz' version "v1.0" - ^^^^^^^^^^^^^^ FormulaAudit/Version: version v1.0 should not have a leading 'v' + ^^^^^^^^^^^^^^ FormulaAudit/Version: Version v1.0 should not have a leading 'v' end RUBY end @@ -31,7 +31,7 @@ RSpec.describe RuboCop::Cop::FormulaAudit::Version do class Foo < Formula url 'https://brew.sh/foo-1.0.tgz' version "1_0" - ^^^^^^^^^^^^^ FormulaAudit/Version: version 1_0 should not end with an underline and a number + ^^^^^^^^^^^^^ FormulaAudit/Version: Version 1_0 should not end with an underline and a number end RUBY end From 7c5affa824b7a4444f03f84d0c597818e0f7d3b5 Mon Sep 17 00:00:00 2001 From: Mike McQuaid Date: Mon, 2 Jun 2025 15:09:27 +0100 Subject: [PATCH 02/34] brew.sh: move sudo reset timestamp. Let's move this from `bin/brew` to make things like e.g. `brew --prefix` or `brew shellenv` not reset the sudo timestamp. This is still in a place that ensures that e.g. no untrusted formula or tap code has been run yet so should have no security implications but provide mild usability improvements. --- Library/Homebrew/brew.sh | 16 ++++++++++++++++ bin/brew | 16 ---------------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/Library/Homebrew/brew.sh b/Library/Homebrew/brew.sh index beaaa1a3a8..38a4058b34 100644 --- a/Library/Homebrew/brew.sh +++ b/Library/Homebrew/brew.sh @@ -1078,6 +1078,22 @@ else export HOMEBREW_GITHUB_PACKAGES_AUTH="Bearer QQ==" fi +# Avoid picking up any random `sudo` in `PATH`. +if [[ -x /usr/bin/sudo ]] +then + SUDO=/usr/bin/sudo +else + # Do this after ensuring we're using default Bash builtins. + SUDO="$(command -v sudo 2>/dev/null)" +fi + +# Reset sudo timestamp to avoid running unauthorized sudo commands +if [[ -n "${SUDO}" ]] +then + "${SUDO}" --reset-timestamp 2>/dev/null || true +fi +unset SUDO + if [[ -n "${HOMEBREW_BASH_COMMAND}" ]] then # source rather than executing directly to ensure the entire file is read into diff --git a/bin/brew b/bin/brew index 3ccf7f68a2..f0b0e5adc3 100755 --- a/bin/brew +++ b/bin/brew @@ -57,22 +57,6 @@ do done unset cmd -# Avoid picking up any random `sudo` in `PATH`. -if [[ -x /usr/bin/sudo ]] -then - SUDO=/usr/bin/sudo -else - # Do this after ensuring we're using default Bash builtins. - SUDO="$(command -v sudo 2>/dev/null)" -fi - -# Reset sudo timestamp to avoid running unauthorized sudo commands -if [[ -n "${SUDO}" ]] -then - "${SUDO}" --reset-timestamp 2>/dev/null || true -fi -unset SUDO - # Take the HOMEBREW_PATH if we are running brew within brew, otherwise we would lose the original path. if [[ -n "${HOMEBREW_BREW_FILE:-}" && -n "${HOMEBREW_PATH:-}" ]] then From 0f03757e8fa1fc515012c20083f682e7118fbdae Mon Sep 17 00:00:00 2001 From: Rylan Polster Date: Mon, 2 Jun 2025 22:15:28 -0400 Subject: [PATCH 03/34] Shard JSON API by OS/Arch combination --- Library/Homebrew/api.rb | 11 +-- Library/Homebrew/dev-cmd/generate-cask-api.rb | 19 ++++- .../Homebrew/dev-cmd/generate-formula-api.rb | 19 ++++- Library/Homebrew/test/api_spec.rb | 80 +++++++++++++++++++ 4 files changed, 120 insertions(+), 9 deletions(-) diff --git a/Library/Homebrew/api.rb b/Library/Homebrew/api.rb index 2a4a920c21..abe6ff94c8 100644 --- a/Library/Homebrew/api.rb +++ b/Library/Homebrew/api.rb @@ -122,14 +122,15 @@ module Homebrew end end - sig { params(json: Hash).returns(Hash) } - def self.merge_variations(json) + sig { params(json: Hash, bottle_tag: T.nilable(::Utils::Bottles::Tag)).returns(Hash) } + def self.merge_variations(json, bottle_tag: nil) return json unless json.key?("variations") - bottle_tag = ::Utils::Bottles::Tag.new(system: Homebrew::SimulateSystem.current_os, - arch: Homebrew::SimulateSystem.current_arch) + bottle_tag ||= ::Utils::Bottles::Tag.new(system: Homebrew::SimulateSystem.current_os, + arch: Homebrew::SimulateSystem.current_arch) - if (variation = json.dig("variations", bottle_tag.to_s).presence) + if (variation = json.dig("variations", bottle_tag.to_s).presence) || + (variation = json.dig("variations", bottle_tag.to_sym).presence) json = json.merge(variation) end diff --git a/Library/Homebrew/dev-cmd/generate-cask-api.rb b/Library/Homebrew/dev-cmd/generate-cask-api.rb index 40b3a1c7da..d80a9bf9a8 100644 --- a/Library/Homebrew/dev-cmd/generate-cask-api.rb +++ b/Library/Homebrew/dev-cmd/generate-cask-api.rb @@ -33,7 +33,7 @@ module Homebrew raise TapUnavailableError, tap.name unless tap.installed? unless args.dry_run? - directories = ["_data/cask", "api/cask", "api/cask-source", "cask", "api/internal/v3"].freeze + directories = ["_data/cask", "api/cask", "api/cask-source", "cask", "api/internal"].freeze FileUtils.rm_rf directories FileUtils.mkdir_p directories end @@ -44,12 +44,14 @@ module Homebrew Cask::Cask.generating_hash! + all_casks = {} latest_macos = MacOSVersion.new((HOMEBREW_MACOS_NEWEST_UNSUPPORTED.to_i - 1).to_s).to_sym Homebrew::SimulateSystem.with(os: latest_macos, arch: :arm) do tap.cask_files.each do |path| cask = Cask::CaskLoader.load(path) name = cask.token - json = JSON.pretty_generate(cask.to_hash_with_variations) + all_casks[name] = cask.to_hash_with_variations + json = JSON.pretty_generate(all_casks[name]) cask_source = path.read html_template_name = html_template(name) @@ -67,6 +69,19 @@ module Homebrew canonical_json = JSON.pretty_generate(tap.cask_renames) File.write("_data/cask_canonical.json", "#{canonical_json}\n") unless args.dry_run? + + OnSystem::ALL_OS_ARCH_COMBINATIONS.filter_map do |os, arch| + bottle_tag = Utils::Bottles::Tag.new(system: os, arch:) + next unless bottle_tag.valid_combination? + + variation_casks = all_casks.transform_values do |cask| + Homebrew::API.merge_variations(cask, bottle_tag:) + end + + unless args.dry_run? + File.write("api/internal/cask.#{bottle_tag}.json", JSON.pretty_generate(variation_casks)) + end + end end end diff --git a/Library/Homebrew/dev-cmd/generate-formula-api.rb b/Library/Homebrew/dev-cmd/generate-formula-api.rb index ac8d5dd63b..0a2cf0c61d 100644 --- a/Library/Homebrew/dev-cmd/generate-formula-api.rb +++ b/Library/Homebrew/dev-cmd/generate-formula-api.rb @@ -32,7 +32,7 @@ module Homebrew raise TapUnavailableError, tap.name unless tap.installed? unless args.dry_run? - directories = ["_data/formula", "api/formula", "formula", "api/internal/v3"] + directories = ["_data/formula", "api/formula", "formula", "api/internal"] FileUtils.rm_rf directories + ["_data/formula_canonical.json"] FileUtils.mkdir_p directories end @@ -44,12 +44,14 @@ module Homebrew Formulary.enable_factory_cache! Formula.generating_hash! + all_formulae = {} latest_macos = MacOSVersion.new((HOMEBREW_MACOS_NEWEST_UNSUPPORTED.to_i - 1).to_s).to_sym Homebrew::SimulateSystem.with(os: latest_macos, arch: :arm) do tap.formula_names.each do |name| formula = Formulary.factory(name) name = formula.name - json = JSON.pretty_generate(formula.to_hash_with_variations) + all_formulae[name] = formula.to_hash_with_variations + json = JSON.pretty_generate(all_formulae[name]) html_template_name = html_template(name) unless args.dry_run? @@ -65,6 +67,19 @@ module Homebrew canonical_json = JSON.pretty_generate(tap.formula_renames.merge(tap.alias_table)) File.write("_data/formula_canonical.json", "#{canonical_json}\n") unless args.dry_run? + + OnSystem::ALL_OS_ARCH_COMBINATIONS.filter_map do |os, arch| + bottle_tag = Utils::Bottles::Tag.new(system: os, arch:) + next unless bottle_tag.valid_combination? + + variation_formulae = all_formulae.transform_values do |formula| + Homebrew::API.merge_variations(formula, bottle_tag:) + end + + unless args.dry_run? + File.write("api/internal/formula.#{bottle_tag}.json", JSON.pretty_generate(variation_formulae)) + end + end end end diff --git a/Library/Homebrew/test/api_spec.rb b/Library/Homebrew/test/api_spec.rb index 9186fc625c..dbf590f73d 100644 --- a/Library/Homebrew/test/api_spec.rb +++ b/Library/Homebrew/test/api_spec.rb @@ -90,4 +90,84 @@ RSpec.describe Homebrew::API do end end end + + describe "::merge_variations" do + let(:arm64_sequoia_tag) { Utils::Bottles::Tag.new(system: :sequoia, arch: :arm) } + let(:sonoma_tag) { Utils::Bottles::Tag.new(system: :sonoma, arch: :intel) } + let(:x86_64_linux_tag) { Utils::Bottles::Tag.new(system: :linux, arch: :intel) } + + let(:json) do + { + "name" => "foo", + "foo" => "bar", + "baz" => ["test1", "test2"], + "variations" => { + "arm64_sequoia" => { "foo" => "new" }, + :sonoma => { "baz" => ["new1", "new2", "new3"] }, + }, + } + end + + let(:arm64_sequoia_result) do + { + "name" => "foo", + "foo" => "new", + "baz" => ["test1", "test2"], + } + end + + let(:sonoma_result) do + { + "name" => "foo", + "foo" => "bar", + "baz" => ["new1", "new2", "new3"], + } + end + + it "returns the original JSON if no variations are found" do + result = described_class.merge_variations(arm64_sequoia_result, bottle_tag: arm64_sequoia_tag) + expect(result).to eq arm64_sequoia_result + end + + it "returns the original JSON if no variations are found for the current system" do + result = described_class.merge_variations(arm64_sequoia_result) + expect(result).to eq arm64_sequoia_result + end + + it "returns the original JSON without the variations if no matching variation is found" do + result = described_class.merge_variations(json, bottle_tag: x86_64_linux_tag) + expect(result).to eq json.except("variations") + end + + it "returns the original JSON without the variations if no matching variation is found for the current system" do + Homebrew::SimulateSystem.with(os: :linux, arch: :intel) do + result = described_class.merge_variations(json) + expect(result).to eq json.except("variations") + end + end + + it "returns the JSON with the matching variation applied from a string key" do + result = described_class.merge_variations(json, bottle_tag: arm64_sequoia_tag) + expect(result).to eq arm64_sequoia_result + end + + it "returns the JSON with the matching variation applied from a string key for the current system" do + Homebrew::SimulateSystem.with(os: :sequoia, arch: :arm) do + result = described_class.merge_variations(json) + expect(result).to eq arm64_sequoia_result + end + end + + it "returns the JSON with the matching variation applied from a symbol key" do + result = described_class.merge_variations(json, bottle_tag: sonoma_tag) + expect(result).to eq sonoma_result + end + + it "returns the JSON with the matching variation applied from a symbol key for the current system" do + Homebrew::SimulateSystem.with(os: :sonoma, arch: :intel) do + result = described_class.merge_variations(json) + expect(result).to eq sonoma_result + end + end + end end From 175eb6507304f9cd9a2dfe921f51e4e54b4f4f3d Mon Sep 17 00:00:00 2001 From: BrewTestBot <1589480+BrewTestBot@users.noreply.github.com> Date: Tue, 3 Jun 2025 08:05:26 +0000 Subject: [PATCH 04/34] dependabot.yml: update to match main configuration --- .github/dependabot.yml | 128 +++++++++++++---------------------------- 1 file changed, 41 insertions(+), 87 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index e28c5eb3df..a5b222935f 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,90 +1,44 @@ +# This file is synced from the `.github` repository, do not modify it directly. +--- version: 2 - updates: - - package-ecosystem: github-actions - directory: / - schedule: - interval: weekly - day: "friday" - time: "08:00" - timezone: "Etc/UTC" - allow: - - dependency-type: all - groups: - github-actions: - patterns: - - "*" +- package-ecosystem: github-actions + directory: "/" + schedule: + interval: weekly + day: friday + time: '08:00' + timezone: Etc/UTC + allow: + - dependency-type: all + groups: + github-actions: + patterns: + - "*" +- package-ecosystem: docker + directory: "/" + schedule: + interval: weekly + day: friday + time: '08:00' + timezone: Etc/UTC + allow: + - dependency-type: all + groups: + docker: + patterns: + - "*" +- package-ecosystem: devcontainers + directory: "/" + schedule: + interval: weekly + day: friday + time: '08:00' + timezone: Etc/UTC + allow: + - dependency-type: all + groups: + devcontainers: + patterns: + - "*" - - package-ecosystem: bundler - directories: - - / - - /Library/Homebrew - schedule: - interval: weekly - day: "friday" - time: "08:00" - timezone: "Etc/UTC" - allow: - - dependency-type: all - groups: - bundler: - patterns: - - "*" - - - package-ecosystem: npm - directory: / - schedule: - interval: weekly - day: "friday" - time: "08:00" - timezone: "Etc/UTC" - allow: - - dependency-type: all - groups: - npm: - patterns: - - "*" - - - package-ecosystem: docker - directory: / - schedule: - interval: weekly - day: "friday" - time: "08:00" - timezone: "Etc/UTC" - allow: - - dependency-type: all - groups: - docker: - patterns: - - "*" - - - package-ecosystem: devcontainers - directory: / - schedule: - interval: weekly - day: "friday" - time: "08:00" - timezone: "Etc/UTC" - allow: - - dependency-type: all - groups: - devcontainers: - patterns: - - "*" - - - package-ecosystem: pip - directories: - - / - - /Library/Homebrew/formula-analytics/ - schedule: - interval: weekly - day: "friday" - time: "08:00" - timezone: "Etc/UTC" - allow: - - dependency-type: all - groups: - pip: - patterns: - - "*" From f9471f9591d82edd8531b02ff956ed340c8f855a Mon Sep 17 00:00:00 2001 From: Mike McQuaid Date: Tue, 3 Jun 2025 15:22:33 +0100 Subject: [PATCH 05/34] Add `brew mcp-server`: a MCP server for Homebrew. Add a new `brew mcp-server` command for a Model Context Protocol (MCP) server for Homebrew. This integrates with AI/LLM tools like Claude, Claude Code and Cursor. It currently supports the calls needed/used by the MCP Inspector and Cursor (where I've tested it). It provides as `tools` the subcommands output by `brew help` but should be fairly straightforward to add more in future. It is implemented in a slightly strange way (a standalone Ruby command called from a shell command) as MCP servers need a faster startup time than a normal Homebrew Ruby command allows and fail if they don't get it. There are a few Ruby libraries available but, given how relatively simplistic the implementation is, it didn't feel worthwhile to use and vendor them. --- Library/Homebrew/brew.sh | 5 + Library/Homebrew/cmd/mcp-server.rb | 23 ++ Library/Homebrew/cmd/mcp-server.sh | 14 + Library/Homebrew/mcp_server.rb | 272 +++++++++++++++++++ Library/Homebrew/test/cmd/mcp-server_spec.rb | 13 + Library/Homebrew/test/mcp_server_spec.rb | 249 +++++++++++++++++ completions/bash/brew | 17 ++ completions/fish/brew.fish | 7 + completions/internal_commands_list.txt | 1 + completions/zsh/_brew | 10 + docs/Manpage.md | 8 + manpages/brew.1 | 7 +- 12 files changed, 625 insertions(+), 1 deletion(-) create mode 100644 Library/Homebrew/cmd/mcp-server.rb create mode 100644 Library/Homebrew/cmd/mcp-server.sh create mode 100644 Library/Homebrew/mcp_server.rb create mode 100644 Library/Homebrew/test/cmd/mcp-server_spec.rb create mode 100644 Library/Homebrew/test/mcp_server_spec.rb diff --git a/Library/Homebrew/brew.sh b/Library/Homebrew/brew.sh index 38a4058b34..537ee55a4e 100644 --- a/Library/Homebrew/brew.sh +++ b/Library/Homebrew/brew.sh @@ -600,6 +600,11 @@ case "$1" in homebrew-version exit 0 ;; + mcp-server) + source "${HOMEBREW_LIBRARY}/Homebrew/cmd/mcp-server.sh" + homebrew-mcp-server "$@" + exit 0 + ;; esac # TODO: bump version when new macOS is released or announced and update references in: diff --git a/Library/Homebrew/cmd/mcp-server.rb b/Library/Homebrew/cmd/mcp-server.rb new file mode 100644 index 0000000000..9a31e2a3e4 --- /dev/null +++ b/Library/Homebrew/cmd/mcp-server.rb @@ -0,0 +1,23 @@ +# typed: strong +# frozen_string_literal: true + +require "abstract_command" +require "shell_command" + +module Homebrew + module Cmd + class McpServerCmd < AbstractCommand + # This is a shell command as MCP servers need a faster startup time + # than a normal Homebrew Ruby command allows. + include ShellCommand + + cmd_args do + description <<~EOS + Starts the Homebrew MCP (Model Context Protocol) server. + EOS + switch "-d", "--debug", description: "Enable debug logging to stderr." + switch "--ping", description: "Start the server, act as if receiving a ping and then exit.", hidden: true + end + end + end +end diff --git a/Library/Homebrew/cmd/mcp-server.sh b/Library/Homebrew/cmd/mcp-server.sh new file mode 100644 index 0000000000..692eec5ed4 --- /dev/null +++ b/Library/Homebrew/cmd/mcp-server.sh @@ -0,0 +1,14 @@ +# Documentation defined in Library/Homebrew/cmd/mcp-server.rb + +# This is a shell command as MCP servers need a faster startup time +# than a normal Homebrew Ruby command allows. + +# HOMEBREW_LIBRARY is set by brew.sh +# HOMEBREW_BREW_FILE is set by extend/ENV/super.rb +# shellcheck disable=SC2154 +homebrew-mcp-server() { + source "${HOMEBREW_LIBRARY}/Homebrew/utils/ruby.sh" + setup-ruby-path + export HOMEBREW_VERSION + "${HOMEBREW_RUBY_PATH}" "-r${HOMEBREW_LIBRARY}/Homebrew/mcp_server.rb" -e "Homebrew::McpServer.new.run" "$@" +} diff --git a/Library/Homebrew/mcp_server.rb b/Library/Homebrew/mcp_server.rb new file mode 100644 index 0000000000..2ce1c89e11 --- /dev/null +++ b/Library/Homebrew/mcp_server.rb @@ -0,0 +1,272 @@ +# typed: strict +# frozen_string_literal: true + +# This is a standalone Ruby script as MCP servers need a faster startup time +# than a normal Homebrew Ruby command allows. +require_relative "standalone" +require "json" +require "stringio" + +module Homebrew + # Provides a Model Context Protocol (MCP) server for Homebrew. + # See https://modelcontextprotocol.io/introduction for more information. + # + # https://modelcontextprotocol.io/docs/tools/inspector is useful for testing. + class McpServer + HOMEBREW_BREW_FILE = T.let(ENV.fetch("HOMEBREW_BREW_FILE").freeze, String) + HOMEBREW_VERSION = T.let(ENV.fetch("HOMEBREW_VERSION").freeze, String) + JSON_RPC_VERSION = T.let("2.0", String) + MCP_PROTOCOL_VERSION = T.let("2025-03-26", String) + ERROR_CODE = T.let(-32601, Integer) + + SERVER_INFO = T.let({ + name: "brew-mcp-server", + version: HOMEBREW_VERSION, + }.freeze, T::Hash[Symbol, String]) + + FORMULA_OR_CASK_PROPERTIES = T.let({ + formula_or_cask: { + type: "string", + description: "Formula or cask name", + }, + }.freeze, T::Hash[Symbol, T.anything]) + + # NOTE: Cursor (as of June 2025) will only query/use a maximum of 40 tools. + TOOLS = T.let({ + search: { + name: "search", + description: "Perform a substring search of cask tokens and formula names for . " \ + "If is flanked by slashes, it is interpreted as a regular expression.", + command: "brew search", + inputSchema: { + type: "object", + properties: { + text_or_regex: { + type: "string", + description: "Text or regex to search for", + }, + }, + }, + required: ["text_or_regex"], + }, + info: { + name: "info", + description: "Display brief statistics for your Homebrew installation. " \ + "If a or is provided, show summary of information about it.", + command: "brew info", + inputSchema: { type: "object", properties: FORMULA_OR_CASK_PROPERTIES }, + }, + install: { + name: "install", + description: "Install a or .", + command: "brew install", + inputSchema: { type: "object", properties: FORMULA_OR_CASK_PROPERTIES }, + required: ["formula_or_cask"], + }, + update: { + name: "update", + description: "Fetch the newest version of Homebrew and all formulae from GitHub using `git` and " \ + "perform any necessary migrations.", + command: "brew update", + inputSchema: { type: "object", properties: {} }, + }, + upgrade: { + name: "upgrade", + description: "Upgrade outdated casks and outdated, unpinned formulae using the same options they were " \ + "originally installed with, plus any appended brew formula options. If or " \ + "are specified, upgrade only the given or kegs (unless they are pinned).", + command: "brew upgrade", + inputSchema: { type: "object", properties: FORMULA_OR_CASK_PROPERTIES }, + }, + uninstall: { + name: "uninstall", + description: "Uninstall a or .", + command: "brew uninstall", + inputSchema: { type: "object", properties: FORMULA_OR_CASK_PROPERTIES }, + required: ["formula_or_cask"], + }, + list: { + name: "list", + description: "List all installed formulae and casks. " \ + "If is provided, summarise the paths within its current keg. " \ + "If is provided, list its artifacts.", + command: "brew list", + inputSchema: { type: "object", properties: FORMULA_OR_CASK_PROPERTIES }, + }, + config: { + name: "config", + description: "Show Homebrew and system configuration info useful for debugging. " \ + "If you file a bug report, you will be required to provide this information.", + command: "brew config", + inputSchema: { type: "object", properties: {} }, + }, + doctor: { + name: "doctor", + description: "Check your system for potential problems. Will exit with a non-zero status " \ + "if any potential problems are found. " \ + "Please note that these warnings are just used to help the Homebrew maintainers " \ + "with debugging if you file an issue. If everything you use Homebrew for " \ + "is working fine: please don't worry or file an issue; just ignore this.", + command: "brew doctor", + inputSchema: { type: "object", properties: {} }, + }, + commands: { + name: "commands", + description: "Show lists of built-in and external commands.", + command: "brew commands", + inputSchema: { type: "object", properties: {} }, + }, + help: { + name: "help", + description: "Outputs the usage instructions for `brew` .", + command: "brew help", + inputSchema: { + type: "object", + properties: { + command: { + type: "string", + description: "Command to get help for", + }, + }, + }, + }, + }.freeze, T::Hash[Symbol, T::Hash[Symbol, T.anything]]) + + sig { params(stdin: T.any(IO, StringIO), stdout: T.any(IO, StringIO), stderr: T.any(IO, StringIO)).void } + def initialize(stdin: $stdin, stdout: $stdout, stderr: $stderr) + @debug_logging = T.let(ARGV.include?("--debug") || ARGV.include?("-d"), T::Boolean) + @ping_switch = T.let(ARGV.include?("--ping"), T::Boolean) + @stdin = T.let(stdin, T.any(IO, StringIO)) + @stdout = T.let(stdout, T.any(IO, StringIO)) + @stderr = T.let(stderr, T.any(IO, StringIO)) + end + + sig { returns(T::Boolean) } + def debug_logging? = @debug_logging + + sig { returns(T::Boolean) } + def ping_switch? = @ping_switch + + sig { void } + def run + @stderr.puts "==> Started Homebrew MCP server..." + + loop do + input = if ping_switch? + { jsonrpc: JSON_RPC_VERSION, id: 1, method: "ping" }.to_json + else + @stdin.gets + end + next if input.nil? || input.strip.empty? + + request = JSON.parse(input) + debug("Request: #{JSON.pretty_generate(request)}") + + response = handle_request(request) + if response.nil? + debug("Response: nil") + next + end + + debug("Response: #{JSON.pretty_generate(response)}") + output = JSON.dump(response).strip + @stdout.puts(output) + @stdout.flush + + break if ping_switch? + end + rescue Interrupt + exit 0 + rescue => e + log("Error: #{e.message}") + exit 1 + end + + sig { params(text: String).void } + def debug(text) + return unless debug_logging? + + log(text) + end + + sig { params(text: String).void } + def log(text) + @stderr.puts(text) + @stderr.flush + end + + sig { params(request: T::Hash[String, T.untyped]).returns(T.nilable(T::Hash[Symbol, T.anything])) } + def handle_request(request) + id = request["id"] + return if id.nil? + + case request["method"] + when "initialize" + respond_result(id, { + protocolVersion: MCP_PROTOCOL_VERSION, + capabilities: { + tools: { listChanged: false }, + prompts: {}, + resources: {}, + logging: {}, + roots: {}, + }, + serverInfo: SERVER_INFO, + }) + when "resources/list" + respond_result(id, { resources: [] }) + when "resources/templates/list" + respond_result(id, { resourceTemplates: [] }) + when "prompts/list" + respond_result(id, { prompts: [] }) + when "ping" + respond_result(id) + when "get_server_info" + respond_result(id, SERVER_INFO) + when "logging/setLevel" + @debug_logging = request["params"]["level"] == "debug" + respond_result(id) + when "notifications/initialized", "notifications/cancelled" + respond_result + when "tools/list" + respond_result(id, { tools: TOOLS.values }) + when "tools/call" + if (tool = TOOLS.fetch(request["params"]["name"].to_sym, nil)) + require "shellwords" + + arguments = request["params"]["arguments"] + argument = arguments.fetch("formula_or_cask", "") + argument = arguments.fetch("text_or_regex", "") if argument.strip.empty? + argument = arguments.fetch("command", "") if argument.strip.empty? + argument = nil if argument.strip.empty? + brew_command = T.cast(tool.fetch(:command), String) + .delete_prefix("brew ") + full_command = [HOMEBREW_BREW_FILE, brew_command, argument].compact + .map { |arg| Shellwords.escape(arg) } + .join(" ") + output = `#{full_command} 2>&1`.strip + respond_result(id, { content: [{ type: "text", text: output }] }) + else + respond_error(id, "Unknown tool") + end + else + respond_error(id, "Method not found") + end + end + + sig { + params(id: T.nilable(Integer), + result: T::Hash[Symbol, T.anything]).returns(T.nilable(T::Hash[Symbol, T.anything])) + } + def respond_result(id = nil, result = {}) + return if id.nil? + + { jsonrpc: JSON_RPC_VERSION, id:, result: } + end + + sig { params(id: T.nilable(Integer), message: String).returns(T::Hash[Symbol, T.anything]) } + def respond_error(id, message) + { jsonrpc: JSON_RPC_VERSION, id:, error: { code: ERROR_CODE, message: } } + end + end +end diff --git a/Library/Homebrew/test/cmd/mcp-server_spec.rb b/Library/Homebrew/test/cmd/mcp-server_spec.rb new file mode 100644 index 0000000000..9a4ef1116f --- /dev/null +++ b/Library/Homebrew/test/cmd/mcp-server_spec.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +RSpec.describe "brew mcp-server", type: :system do + it "starts the MCP server", :integration_test do + # This is the easiest way to handle a newline here. + # rubocop:disable Style/StringConcatenation + expect { brew_sh "mcp-server", "--ping" } + .to output("==> Started Homebrew MCP server...\n").to_stderr + .and output('{"jsonrpc":"2.0","id":1,"result":{}}' + "\n").to_stdout + .and be_a_success + # rubocop:enable Style/StringConcatenation + end +end diff --git a/Library/Homebrew/test/mcp_server_spec.rb b/Library/Homebrew/test/mcp_server_spec.rb new file mode 100644 index 0000000000..98f31469cf --- /dev/null +++ b/Library/Homebrew/test/mcp_server_spec.rb @@ -0,0 +1,249 @@ +# frozen_string_literal: true + +require "mcp_server" +require "stringio" +require "timeout" + +RSpec.describe Homebrew::McpServer do + let(:stdin) { StringIO.new } + let(:stdout) { StringIO.new } + let(:stderr) { StringIO.new } + let(:server) { described_class.new(stdin:, stdout:, stderr:) } + let(:jsonrpc) { Homebrew::McpServer::JSON_RPC_VERSION } + let(:id) { Random.rand(1000) } + let(:code) { Homebrew::McpServer::ERROR_CODE } + + describe "#initialize" do + it "sets debug_logging to false by default" do + expect(server.debug_logging?).to be(false) + end + + it "sets debug_logging to true if --debug is in ARGV" do + stub_const("ARGV", ["--debug"]) + expect(server.debug_logging?).to be(true) + end + + it "sets debug_logging to true if -d is in ARGV" do + stub_const("ARGV", ["-d"]) + expect(server.debug_logging?).to be(true) + end + end + + describe "#debug and #log" do + it "logs debug output when debug_logging is true" do + stub_const("ARGV", ["--debug"]) + server.debug("foo") + expect(stderr.string).to include("foo") + end + + it "does not log debug output when debug_logging is false" do + server.debug("foo") + expect(stderr.string).to eq("") + end + + it "logs to stderr" do + server.log("bar") + expect(stderr.string).to include("bar") + end + end + + describe "#handle_request" do + it "responds to initialize method" do + request = { "id" => id, "method" => "initialize" } + result = server.handle_request(request) + expect(result).to eq({ + jsonrpc:, + id:, + result: { + protocolVersion: Homebrew::McpServer::MCP_PROTOCOL_VERSION, + capabilities: { + tools: { listChanged: false }, + prompts: {}, + resources: {}, + logging: {}, + roots: {}, + }, + serverInfo: Homebrew::McpServer::SERVER_INFO, + }, + }) + end + + it "responds to resources/list" do + request = { "id" => id, "method" => "resources/list" } + result = server.handle_request(request) + expect(result).to eq({ jsonrpc:, id:, result: { resources: [] } }) + end + + it "responds to resources/templates/list" do + request = { "id" => id, "method" => "resources/templates/list" } + result = server.handle_request(request) + expect(result).to eq({ jsonrpc:, id:, result: { resourceTemplates: [] } }) + end + + it "responds to prompts/list" do + request = { "id" => id, "method" => "prompts/list" } + result = server.handle_request(request) + expect(result).to eq({ jsonrpc:, id:, result: { prompts: [] } }) + end + + it "responds to ping" do + request = { "id" => id, "method" => "ping" } + result = server.handle_request(request) + expect(result).to eq({ jsonrpc:, id:, result: {} }) + end + + it "responds to get_server_info" do + request = { "id" => id, "method" => "get_server_info" } + result = server.handle_request(request) + expect(result).to eq({ jsonrpc:, id:, result: Homebrew::McpServer::SERVER_INFO }) + end + + it "responds to logging/setLevel with debug" do + request = { "id" => id, "method" => "logging/setLevel", "params" => { "level" => "debug" } } + result = server.handle_request(request) + expect(server.debug_logging?).to be(true) + expect(result).to eq({ jsonrpc:, id:, result: {} }) + end + + it "responds to logging/setLevel with non-debug" do + request = { "id" => id, "method" => "logging/setLevel", "params" => { "level" => "info" } } + result = server.handle_request(request) + expect(server.debug_logging?).to be(false) + expect(result).to eq({ jsonrpc:, id:, result: {} }) + end + + it "responds to notifications/initialized" do + request = { "id" => id, "method" => "notifications/initialized" } + expect(server.handle_request(request)).to be_nil + end + + it "responds to notifications/cancelled" do + request = { "id" => id, "method" => "notifications/cancelled" } + expect(server.handle_request(request)).to be_nil + end + + it "responds to tools/list" do + request = { "id" => id, "method" => "tools/list" } + result = server.handle_request(request) + expect(result[:result][:tools]).to match_array(Homebrew::McpServer::TOOLS.values) + end + + Homebrew::McpServer::TOOLS.each do |tool_name, tool_definition| + it "responds to tools/call for #{tool_name}" do + allow(server).to receive(:`).and_return("output for #{tool_name}") + arguments = {} + Array(tool_definition[:required]).each do |required_key| + arguments[required_key] = "dummy" + end + request = { + "id" => id, + "method" => "tools/call", + "params" => { + "name" => tool_name.to_s, + "arguments" => arguments, + }, + } + result = server.handle_request(request) + expect(result).to eq({ + jsonrpc: jsonrpc, + id: id, + result: { content: [{ type: "text", text: "output for #{tool_name}" }] }, + }) + end + end + + it "responds to tools/call for unknown tool" do + request = { "id" => id, "method" => "tools/call", "params" => { "name" => "not_a_tool", "arguments" => {} } } + result = server.handle_request(request) + expect(result).to eq({ jsonrpc:, id:, error: { message: "Unknown tool", code: } }) + end + + it "responds with error for unknown method" do + request = { "id" => id, "method" => "not_a_method" } + result = server.handle_request(request) + expect(result).to eq({ jsonrpc:, id:, error: { message: "Method not found", code: } }) + end + + it "returns nil if id is nil" do + request = { "method" => "initialize" } + expect(server.handle_request(request)).to be_nil + end + end + + describe "#respond_result" do + it "returns nil if id is nil" do + expect(server.send(:respond_result, nil, {})).to be_nil + end + + it "returns a result hash if id is present" do + result = server.respond_result(id, { foo: "bar" }) + expect(result).to eq({ jsonrpc:, id:, result: { foo: "bar" } }) + end + end + + describe "#respond_error" do + it "returns an error hash" do + result = server.respond_error(id, "fail") + expect(result).to eq({ jsonrpc:, id:, error: { message: "fail", code: } }) + end + end + + describe "#run" do + let(:sleep_time) { 0.001 } + + it "runs the loop and exits cleanly on interrupt" do + stub_const("ARGV", ["--debug"]) + stdin.puts({ id:, method: "ping" }.to_json) + stdin.rewind + server_thread = Thread.new do + server.run + rescue SystemExit + # expected, do nothing + end + + response_hash_string = "Response: {" + sleep(sleep_time) + server_thread.raise(Interrupt) + server_thread.join + + expect(stderr.string).to include(response_hash_string) + end + + it "runs the loop and logs 'Response: nil' when handle_request returns nil" do + stub_const("ARGV", ["--debug"]) + stdin.puts({ id:, method: "notifications/initialized" }.to_json) + stdin.rewind + server_thread = Thread.new do + server.run + rescue SystemExit + # expected, do nothing + end + + response_nil_string = "Response: nil" + sleep(sleep_time) + server_thread.raise(Interrupt) + server_thread.join + + expect(stderr.string).to include(response_nil_string) + end + + it "exits on Interrupt" do + allow(stdin).to receive(:gets).and_raise(Interrupt) + expect do + server.run + rescue + SystemExit + end.to raise_error(SystemExit) + end + + it "exits on error" do + allow(stdin).to receive(:gets).and_raise(StandardError, "fail") + expect do + server.run + rescue + SystemExit + end.to raise_error(SystemExit) + expect(stderr.string).to match(/Error: fail/) + end + end +end diff --git a/completions/bash/brew b/completions/bash/brew index 7e00bdfa81..b85bd4746c 100644 --- a/completions/bash/brew +++ b/completions/bash/brew @@ -1797,6 +1797,22 @@ _brew_ls() { __brew_complete_installed_casks } +_brew_mcp_server() { + local cur="${COMP_WORDS[COMP_CWORD]}" + case "${cur}" in + -*) + __brewcomp " + --debug + --help + --quiet + --verbose + " + return + ;; + *) ;; + esac +} + _brew_migrate() { local cur="${COMP_WORDS[COMP_CWORD]}" case "${cur}" in @@ -3191,6 +3207,7 @@ _brew() { ln) _brew_ln ;; log) _brew_log ;; ls) _brew_ls ;; + mcp-server) _brew_mcp_server ;; migrate) _brew_migrate ;; missing) _brew_missing ;; nodenv-sync) _brew_nodenv_sync ;; diff --git a/completions/fish/brew.fish b/completions/fish/brew.fish index 0457b6dd6a..be001f007b 100644 --- a/completions/fish/brew.fish +++ b/completions/fish/brew.fish @@ -1226,6 +1226,13 @@ __fish_brew_complete_arg 'ls; and not __fish_seen_argument -l cask -l casks' -a __fish_brew_complete_arg 'ls; and not __fish_seen_argument -l formula -l formulae' -a '(__fish_brew_suggest_casks_installed)' +__fish_brew_complete_cmd 'mcp-server' 'Starts the Homebrew MCP (Model Context Protocol) server' +__fish_brew_complete_arg 'mcp-server' -l debug -d 'Enable debug logging to stderr' +__fish_brew_complete_arg 'mcp-server' -l help -d 'Show this message' +__fish_brew_complete_arg 'mcp-server' -l quiet -d 'Make some output more quiet' +__fish_brew_complete_arg 'mcp-server' -l verbose -d 'Make some output more verbose' + + __fish_brew_complete_cmd 'migrate' 'Migrate renamed packages to new names, where formula are old names of packages' __fish_brew_complete_arg 'migrate' -l cask -d 'Only migrate casks' __fish_brew_complete_arg 'migrate' -l debug -d 'Display any debugging information' diff --git a/completions/internal_commands_list.txt b/completions/internal_commands_list.txt index b0e7542097..dbdc755da3 100644 --- a/completions/internal_commands_list.txt +++ b/completions/internal_commands_list.txt @@ -68,6 +68,7 @@ livecheck ln log ls +mcp-server migrate missing nodenv-sync diff --git a/completions/zsh/_brew b/completions/zsh/_brew index 8d1d4e3da9..977501c4dd 100644 --- a/completions/zsh/_brew +++ b/completions/zsh/_brew @@ -191,6 +191,7 @@ __brew_internal_commands() { 'list:List all installed formulae and casks' 'livecheck:Check for newer versions of formulae and/or casks from upstream' 'log:Show the `git log` for formula or cask, or show the log for the Homebrew repository if no formula or cask is provided' + 'mcp-server:Starts the Homebrew MCP (Model Context Protocol) server' 'migrate:Migrate renamed packages to new names, where formula are old names of packages' 'missing:Check the given formula kegs for missing dependencies' 'nodenv-sync:Create symlinks for Homebrew'\''s installed NodeJS versions in `~/.nodenv/versions`' @@ -1511,6 +1512,15 @@ _brew_ls() { '*:installed_cask:__brew_installed_casks' } +# brew mcp-server +_brew_mcp_server() { + _arguments \ + '--debug[Enable debug logging to stderr]' \ + '--help[Show this message]' \ + '--quiet[Make some output more quiet]' \ + '--verbose[Make some output more verbose]' +} + # brew migrate _brew_migrate() { _arguments \ diff --git a/docs/Manpage.md b/docs/Manpage.md index 861f6d0e92..da7ddfc8d6 100644 --- a/docs/Manpage.md +++ b/docs/Manpage.md @@ -1046,6 +1046,14 @@ repository if no formula or cask is provided. : Treat all named arguments as casks. +### `mcp-server` \[`--debug`\] + +Starts the Homebrew MCP (Model Context Protocol) server. + +`-d`, `--debug` + +: Enable debug logging to stderr. + ### `migrate` \[*`options`*\] *`installed_formula`*\|*`installed_cask`* \[...\] Migrate renamed packages to new names, where *`formula`* are old names of diff --git a/manpages/brew.1 b/manpages/brew.1 index 1d84a042df..a67133433c 100644 --- a/manpages/brew.1 +++ b/manpages/brew.1 @@ -1,5 +1,5 @@ .\" generated by kramdown -.TH "BREW" "1" "May 2025" "Homebrew" +.TH "BREW" "1" "June 2025" "Homebrew" .SH NAME brew \- The Missing Package Manager for macOS (or Linux) .SH "SYNOPSIS" @@ -656,6 +656,11 @@ Treat all named arguments as formulae\. .TP \fB\-\-cask\fP Treat all named arguments as casks\. +.SS "\fBmcp\-server\fP \fR[\fB\-\-debug\fP]" +Starts the Homebrew MCP (Model Context Protocol) server\. +.TP +\fB\-d\fP, \fB\-\-debug\fP +Enable debug logging to stderr\. .SS "\fBmigrate\fP \fR[\fIoptions\fP] \fIinstalled_formula\fP|\fIinstalled_cask\fP \fR[\.\.\.]" Migrate renamed packages to new names, where \fIformula\fP are old names of packages\. .TP From 76c4eb60ee757e540957f8b9432db801e19bcef7 Mon Sep 17 00:00:00 2001 From: Mike McQuaid Date: Tue, 3 Jun 2025 11:51:47 +0100 Subject: [PATCH 06/34] test/cmd: add more shell tests. This should help ensure that these don't regress. --- Library/Homebrew/test/cmd/casks_spec.rb | 9 +++++++++ Library/Homebrew/test/cmd/formulae_spec.rb | 9 +++++++++ Library/Homebrew/test/cmd/list_spec.rb | 8 ++++++-- Library/Homebrew/test/cmd/setup-ruby_spec.rb | 10 ++++++++++ Library/Homebrew/test/cmd/shellenv_spec.rb | 10 ++++++++++ 5 files changed, 44 insertions(+), 2 deletions(-) create mode 100644 Library/Homebrew/test/cmd/casks_spec.rb create mode 100644 Library/Homebrew/test/cmd/formulae_spec.rb create mode 100644 Library/Homebrew/test/cmd/setup-ruby_spec.rb create mode 100644 Library/Homebrew/test/cmd/shellenv_spec.rb diff --git a/Library/Homebrew/test/cmd/casks_spec.rb b/Library/Homebrew/test/cmd/casks_spec.rb new file mode 100644 index 0000000000..d70b5daf34 --- /dev/null +++ b/Library/Homebrew/test/cmd/casks_spec.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +RSpec.describe "brew casks", type: :system do + it "prints all installed Casks", :integration_test do + expect { brew_sh "casks" } + .to be_a_success + .and not_to_output.to_stderr + end +end diff --git a/Library/Homebrew/test/cmd/formulae_spec.rb b/Library/Homebrew/test/cmd/formulae_spec.rb new file mode 100644 index 0000000000..714238aefa --- /dev/null +++ b/Library/Homebrew/test/cmd/formulae_spec.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +RSpec.describe "brew formulae", type: :system do + it "prints all installed Formulae", :integration_test do + expect { brew_sh "formulae" } + .to be_a_success + .and not_to_output.to_stderr + end +end diff --git a/Library/Homebrew/test/cmd/list_spec.rb b/Library/Homebrew/test/cmd/list_spec.rb index 97a6f1466a..62ff3c8004 100644 --- a/Library/Homebrew/test/cmd/list_spec.rb +++ b/Library/Homebrew/test/cmd/list_spec.rb @@ -8,7 +8,7 @@ RSpec.describe Homebrew::Cmd::List do it_behaves_like "parseable arguments" - it "prints all installed Formulae", :integration_test do + it "prints all installed formulae", :integration_test do formulae.each do |f| (HOMEBREW_CELLAR/f/"1.0/somedir").mkpath end @@ -19,5 +19,9 @@ RSpec.describe Homebrew::Cmd::List do .and be_a_success end - # TODO: add a test for the shell fast-path (`brew_sh`) + it "prints all installed formulae and casks", :integration_test do + expect { brew_sh "list" } + .to be_a_success + .and not_to_output.to_stderr + end end diff --git a/Library/Homebrew/test/cmd/setup-ruby_spec.rb b/Library/Homebrew/test/cmd/setup-ruby_spec.rb new file mode 100644 index 0000000000..7bff28754e --- /dev/null +++ b/Library/Homebrew/test/cmd/setup-ruby_spec.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +RSpec.describe "brew setup-ruby", type: :system do + it "installs and configures Homebrew's Ruby", :integration_test do + expect { brew_sh "setup-ruby" } + .to output("").to_stdout + .and not_to_output.to_stderr + .and be_a_success + end +end diff --git a/Library/Homebrew/test/cmd/shellenv_spec.rb b/Library/Homebrew/test/cmd/shellenv_spec.rb new file mode 100644 index 0000000000..2a241b2270 --- /dev/null +++ b/Library/Homebrew/test/cmd/shellenv_spec.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +RSpec.describe "brew shellenv", type: :system do + it "prints export statements", :integration_test do + expect { brew_sh "shellenv" } + .to output(/.*/).to_stdout + .and not_to_output.to_stderr + .and be_a_success + end +end From c03f70f1dc6eb1e527516dcf34c1aeb2215ceee8 Mon Sep 17 00:00:00 2001 From: Rylan Polster Date: Tue, 3 Jun 2025 11:57:17 -0400 Subject: [PATCH 07/34] Refactor `OnSystem` and `SimulateSystem` bottle tag handling --- Library/Homebrew/api.rb | 3 +-- Library/Homebrew/cask/cask.rb | 6 ++---- Library/Homebrew/dev-cmd/generate-cask-api.rb | 5 +---- .../Homebrew/dev-cmd/generate-formula-api.rb | 5 +---- Library/Homebrew/extend/on_system.rb | 7 +++++++ Library/Homebrew/formula.rb | 7 ++----- Library/Homebrew/simulate_system.rb | 21 +++++++++++++++++++ Library/Homebrew/test/formula_spec.rb | 8 ++++++- 8 files changed, 42 insertions(+), 20 deletions(-) diff --git a/Library/Homebrew/api.rb b/Library/Homebrew/api.rb index abe6ff94c8..3948bcde3d 100644 --- a/Library/Homebrew/api.rb +++ b/Library/Homebrew/api.rb @@ -126,8 +126,7 @@ module Homebrew def self.merge_variations(json, bottle_tag: nil) return json unless json.key?("variations") - bottle_tag ||= ::Utils::Bottles::Tag.new(system: Homebrew::SimulateSystem.current_os, - arch: Homebrew::SimulateSystem.current_arch) + bottle_tag ||= Homebrew::SimulateSystem.current_tag if (variation = json.dig("variations", bottle_tag.to_s).presence) || (variation = json.dig("variations", bottle_tag.to_sym).presence) diff --git a/Library/Homebrew/cask/cask.rb b/Library/Homebrew/cask/cask.rb index 4ce56d4011..ec26010e90 100644 --- a/Library/Homebrew/cask/cask.rb +++ b/Library/Homebrew/cask/cask.rb @@ -416,16 +416,14 @@ module Cask if @dsl.on_system_blocks_exist? begin - OnSystem::ALL_OS_ARCH_COMBINATIONS.each do |os, arch| - bottle_tag = ::Utils::Bottles::Tag.new(system: os, arch:) - next unless bottle_tag.valid_combination? + OnSystem::VALID_OS_ARCH_TAGS.each do |bottle_tag| next if bottle_tag.linux? && @dsl.os.nil? next if bottle_tag.macos? && depends_on.macos && !@dsl.depends_on_set_in_block? && !depends_on.macos.allows?(bottle_tag.to_macos_version) - Homebrew::SimulateSystem.with(os:, arch:) do + Homebrew::SimulateSystem.with_tag(bottle_tag) do refresh to_h.each do |key, value| diff --git a/Library/Homebrew/dev-cmd/generate-cask-api.rb b/Library/Homebrew/dev-cmd/generate-cask-api.rb index d80a9bf9a8..5102d863b6 100644 --- a/Library/Homebrew/dev-cmd/generate-cask-api.rb +++ b/Library/Homebrew/dev-cmd/generate-cask-api.rb @@ -70,10 +70,7 @@ module Homebrew canonical_json = JSON.pretty_generate(tap.cask_renames) File.write("_data/cask_canonical.json", "#{canonical_json}\n") unless args.dry_run? - OnSystem::ALL_OS_ARCH_COMBINATIONS.filter_map do |os, arch| - bottle_tag = Utils::Bottles::Tag.new(system: os, arch:) - next unless bottle_tag.valid_combination? - + OnSystem::VALID_OS_ARCH_TAGS.each do |bottle_tag| variation_casks = all_casks.transform_values do |cask| Homebrew::API.merge_variations(cask, bottle_tag:) end diff --git a/Library/Homebrew/dev-cmd/generate-formula-api.rb b/Library/Homebrew/dev-cmd/generate-formula-api.rb index 0a2cf0c61d..5d161ad89d 100644 --- a/Library/Homebrew/dev-cmd/generate-formula-api.rb +++ b/Library/Homebrew/dev-cmd/generate-formula-api.rb @@ -68,10 +68,7 @@ module Homebrew canonical_json = JSON.pretty_generate(tap.formula_renames.merge(tap.alias_table)) File.write("_data/formula_canonical.json", "#{canonical_json}\n") unless args.dry_run? - OnSystem::ALL_OS_ARCH_COMBINATIONS.filter_map do |os, arch| - bottle_tag = Utils::Bottles::Tag.new(system: os, arch:) - next unless bottle_tag.valid_combination? - + OnSystem::VALID_OS_ARCH_TAGS.each do |bottle_tag| variation_formulae = all_formulae.transform_values do |formula| Homebrew::API.merge_variations(formula, bottle_tag:) end diff --git a/Library/Homebrew/extend/on_system.rb b/Library/Homebrew/extend/on_system.rb index 3d6b97b95f..4e1854ad19 100644 --- a/Library/Homebrew/extend/on_system.rb +++ b/Library/Homebrew/extend/on_system.rb @@ -9,6 +9,13 @@ module OnSystem ALL_OS_OPTIONS = [*MacOSVersion::SYMBOLS.keys, :linux].freeze ALL_OS_ARCH_COMBINATIONS = ALL_OS_OPTIONS.product(ARCH_OPTIONS).freeze + VALID_OS_ARCH_TAGS = ALL_OS_ARCH_COMBINATIONS.filter_map do |os, arch| + tag = Utils::Bottles::Tag.new(system: os, arch:) + next unless tag.valid_combination? + + tag + end.freeze + sig { params(arch: Symbol).returns(T::Boolean) } def self.arch_condition_met?(arch) raise ArgumentError, "Invalid arch condition: #{arch.inspect}" if ARCH_OPTIONS.exclude?(arch) diff --git a/Library/Homebrew/formula.rb b/Library/Homebrew/formula.rb index c07a6f6292..740e258a32 100644 --- a/Library/Homebrew/formula.rb +++ b/Library/Homebrew/formula.rb @@ -2593,11 +2593,8 @@ class Formula if path.exist? && on_system_blocks_exist? formula_contents = path.read - OnSystem::ALL_OS_ARCH_COMBINATIONS.each do |os, arch| - bottle_tag = Utils::Bottles::Tag.new(system: os, arch:) - next unless bottle_tag.valid_combination? - - Homebrew::SimulateSystem.with(os:, arch:) do + OnSystem::VALID_OS_ARCH_TAGS.each do |bottle_tag| + Homebrew::SimulateSystem.with_tag(bottle_tag) do variations_namespace = Formulary.class_s("Variations#{bottle_tag.to_sym.capitalize}") variations_formula_class = Formulary.load_formula(name, path, formula_contents, variations_namespace, flags: self.class.build_flags, ignore_errors: true) diff --git a/Library/Homebrew/simulate_system.rb b/Library/Homebrew/simulate_system.rb index e1b80b8415..e40d891581 100644 --- a/Library/Homebrew/simulate_system.rb +++ b/Library/Homebrew/simulate_system.rb @@ -2,6 +2,7 @@ # frozen_string_literal: true require "macos_version" +require "utils/bottles" module Homebrew # Helper module for simulating different system configurations. @@ -33,6 +34,18 @@ module Homebrew end end + sig { + type_parameters(:U).params( + tag: Utils::Bottles::Tag, + block: T.proc.returns(T.type_parameter(:U)), + ).returns(T.type_parameter(:U)) + } + def with_tag(tag, &block) + raise ArgumentError, "Invalid tag: #{tag}" unless tag.valid_combination? + + with(os: tag.system, arch: tag.arch, &block) + end + sig { params(new_os: Symbol).void } def os=(new_os) os_options = [:macos, :linux, *MacOSVersion::SYMBOLS.keys] @@ -72,6 +85,14 @@ module Homebrew def current_os os || :generic end + + sig { returns(Utils::Bottles::Tag) } + def current_tag + Utils::Bottles::Tag.new( + system: current_os, + arch: current_arch, + ) + end end end end diff --git a/Library/Homebrew/test/formula_spec.rb b/Library/Homebrew/test/formula_spec.rb index 045b27b3a0..ada1618966 100644 --- a/Library/Homebrew/test/formula_spec.rb +++ b/Library/Homebrew/test/formula_spec.rb @@ -1046,7 +1046,13 @@ RSpec.describe Formula do before do # Use a more limited os list to shorten the variations hash os_list = [:monterey, :big_sur, :catalina, :mojave, :linux] - stub_const("OnSystem::ALL_OS_ARCH_COMBINATIONS", os_list.product(OnSystem::ARCH_OPTIONS)) + valid_tags = os_list.product(OnSystem::ARCH_OPTIONS).filter_map do |os, arch| + tag = Utils::Bottles::Tag.new(system: os, arch:) + next unless tag.valid_combination? + + tag + end + stub_const("OnSystem::VALID_OS_ARCH_TAGS", valid_tags) # For consistency, always run on Monterey and ARM allow(MacOS).to receive(:version).and_return(MacOSVersion.new("12")) From 3dc9e88542aaed8738296b2f8c71625e7b1089c9 Mon Sep 17 00:00:00 2001 From: Eric Knibbe Date: Tue, 3 Jun 2025 11:06:35 -0400 Subject: [PATCH 08/34] parser: show related env var in switch description --- Library/Homebrew/cli/parser.rb | 8 +- Library/Homebrew/cmd/bundle.rb | 26 ++--- Library/Homebrew/cmd/install.rb | 8 +- Library/Homebrew/cmd/outdated.rb | 6 +- Library/Homebrew/cmd/reinstall.rb | 6 +- Library/Homebrew/cmd/shellenv.rb | 6 +- Library/Homebrew/cmd/upgrade.rb | 6 +- Library/Homebrew/dev-cmd/audit.rb | 2 +- Library/Homebrew/dev-cmd/bump.rb | 2 +- .../dev-cmd/determine-test-runners.rb | 3 +- Library/Homebrew/dev-cmd/edit.rb | 3 +- Library/Homebrew/dev-cmd/irb.rb | 4 +- Library/Homebrew/dev-cmd/linkage.rb | 2 +- Library/Homebrew/dev-cmd/livecheck.rb | 2 +- Library/Homebrew/dev-cmd/sh.rb | 4 +- Library/Homebrew/dev-cmd/unbottled.rb | 8 +- Library/Homebrew/dev-cmd/update-test.rb | 2 +- Library/Homebrew/env_config.rb | 2 +- Library/Homebrew/manpages/brew.1.md.erb | 4 +- completions/fish/brew.fish | 90 +++++++-------- completions/zsh/_brew | 90 +++++++-------- docs/Manpage.md | 109 ++++++++++-------- manpages/brew.1 | 74 ++++++------ 23 files changed, 241 insertions(+), 226 deletions(-) diff --git a/Library/Homebrew/cli/parser.rb b/Library/Homebrew/cli/parser.rb index eda01f6274..9d6e4b3314 100644 --- a/Library/Homebrew/cli/parser.rb +++ b/Library/Homebrew/cli/parser.rb @@ -208,11 +208,15 @@ module Homebrew return if global_switch description = option_description(description, *names, hidden:) - process_option(*names, description, type: :switch, hidden:) unless disable - + env, counterpart = env + if env && @non_global_processed_options.any? + affix = counterpart ? " and `#{counterpart}` is passed." : "." + description += " Enabled by default if `$HOMEBREW_#{env.upcase}` is set#{affix}" + end if replacement || disable description += " (#{disable ? "disabled" : "deprecated"}#{"; replaced by #{replacement}" if replacement})" end + process_option(*names, description, type: :switch, hidden:) unless disable @parser.public_send(method, *names, *wrap_option_desc(description)) do |value| # This odeprecated should stick around indefinitely. diff --git a/Library/Homebrew/cmd/bundle.rb b/Library/Homebrew/cmd/bundle.rb index 4dfb7a60f0..122341a741 100755 --- a/Library/Homebrew/cmd/bundle.rb +++ b/Library/Homebrew/cmd/bundle.rb @@ -73,11 +73,10 @@ module Homebrew description: "`install` prints output from commands as they are run. " \ "`check` lists all missing dependencies." switch "--no-upgrade", - env: :bundle_no_upgrade, description: "`install` does not run `brew upgrade` on outdated dependencies. " \ "`check` does not check for outdated dependencies. " \ - "Note they may still be upgraded by `brew install` if needed. " \ - "This is enabled by default if `$HOMEBREW_BUNDLE_NO_UPGRADE` is set." + "Note they may still be upgraded by `brew install` if needed.", + env: :bundle_no_upgrade switch "--upgrade", description: "`install` runs `brew upgrade` on outdated dependencies, " \ "even if `$HOMEBREW_BUNDLE_NO_UPGRADE` is set." @@ -87,18 +86,15 @@ module Homebrew switch "--install", description: "Run `install` before continuing to other operations e.g. `exec`." switch "--services", - env: :bundle_services, - description: "Temporarily start services while running the `exec` or `sh` command. " \ - "This is enabled by default if `$HOMEBREW_BUNDLE_SERVICES` is set." + description: "Temporarily start services while running the `exec` or `sh` command.", + env: :bundle_services switch "-f", "--force", description: "`install` runs with `--force`/`--overwrite`. " \ "`dump` overwrites an existing `Brewfile`. " \ "`cleanup` actually performs its cleanup operations." switch "--cleanup", - env: :bundle_install_cleanup, - description: "`install` performs cleanup operation, same as running `cleanup --force`. " \ - "This is enabled by default if `$HOMEBREW_BUNDLE_INSTALL_CLEANUP` is set and " \ - "`--global` is passed." + description: "`install` performs cleanup operation, same as running `cleanup --force`.", + env: [:bundle_install_cleanup, "--global"] switch "--all", description: "`list` all dependencies." switch "--formula", "--brews", @@ -114,14 +110,12 @@ module Homebrew switch "--vscode", description: "`list`, `dump` or `cleanup` VSCode (and forks/variants) extensions." switch "--no-vscode", - env: :bundle_dump_no_vscode, - description: "`dump` without VSCode (and forks/variants) extensions. " \ - "This is enabled by default if `$HOMEBREW_BUNDLE_DUMP_NO_VSCODE` is set." + description: "`dump` without VSCode (and forks/variants) extensions.", + env: :bundle_dump_no_vscode switch "--describe", - env: :bundle_dump_describe, description: "`dump` adds a description comment above each line, unless the " \ - "dependency does not have a description. " \ - "This is enabled by default if `$HOMEBREW_BUNDLE_DUMP_DESCRIBE` is set." + "dependency does not have a description.", + env: :bundle_dump_describe switch "--no-restart", description: "`dump` does not add `restart_service` to formula lines." switch "--zap", diff --git a/Library/Homebrew/cmd/install.rb b/Library/Homebrew/cmd/install.rb index 517414f9fe..ee695c1b43 100644 --- a/Library/Homebrew/cmd/install.rb +++ b/Library/Homebrew/cmd/install.rb @@ -33,8 +33,8 @@ module Homebrew description: "If brewing fails, open an interactive debugging session with access to IRB " \ "or a shell inside the temporary build directory." switch "--display-times", - env: :display_install_times, - description: "Print install times for each package at the end of the run." + description: "Print install times for each package at the end of the run.", + env: :display_install_times switch "-f", "--force", description: "Install formulae without checking for previously installed keg-only or " \ "non-migrated versions. When installing casks, overwrite existing files " \ @@ -44,9 +44,9 @@ module Homebrew switch "-n", "--dry-run", description: "Show what would be installed, but do not actually install anything." switch "--ask", - env: :ask, description: "Ask for confirmation before downloading and installing formulae. " \ - "Print bottles and dependencies download size and install size." + "Print download and install sizes of bottles and dependencies.", + env: :ask [ [:switch, "--formula", "--formulae", { description: "Treat all named arguments as formulae.", diff --git a/Library/Homebrew/cmd/outdated.rb b/Library/Homebrew/cmd/outdated.rb index 3acc2fcf84..6b4d81f179 100644 --- a/Library/Homebrew/cmd/outdated.rb +++ b/Library/Homebrew/cmd/outdated.rb @@ -32,12 +32,10 @@ module Homebrew "formula is outdated. Otherwise, the repository's HEAD will only be checked for " \ "updates when a new stable or development version has been released." switch "-g", "--greedy", - env: :upgrade_greedy, - description: "Also include outdated casks with `auto_updates true` or `version :latest`." - + description: "Also include outdated casks with `auto_updates true` or `version :latest`.", + env: :upgrade_greedy switch "--greedy-latest", description: "Also include outdated casks including those with `version :latest`." - switch "--greedy-auto-updates", description: "Also include outdated casks including those with `auto_updates true`." diff --git a/Library/Homebrew/cmd/reinstall.rb b/Library/Homebrew/cmd/reinstall.rb index 2c1208e54a..f6361ec689 100644 --- a/Library/Homebrew/cmd/reinstall.rb +++ b/Library/Homebrew/cmd/reinstall.rb @@ -32,8 +32,8 @@ module Homebrew description: "If brewing fails, open an interactive debugging session with access to IRB " \ "or a shell inside the temporary build directory." switch "--display-times", - env: :display_install_times, - description: "Print install times for each package at the end of the run." + description: "Print install times for each package at the end of the run.", + env: :display_install_times switch "-f", "--force", description: "Install without checking for previously installed keg-only or " \ "non-migrated versions." @@ -41,7 +41,7 @@ module Homebrew description: "Print the verification and post-install steps." switch "--ask", description: "Ask for confirmation before downloading and upgrading formulae. " \ - "Print bottles and dependencies download size, install and net install size.", + "Print download, install and net install sizes of bottles and dependencies.", env: :ask [ [:switch, "--formula", "--formulae", { description: "Treat all named arguments as formulae." }], diff --git a/Library/Homebrew/cmd/shellenv.rb b/Library/Homebrew/cmd/shellenv.rb index 03c530f502..6e5c959046 100644 --- a/Library/Homebrew/cmd/shellenv.rb +++ b/Library/Homebrew/cmd/shellenv.rb @@ -13,18 +13,20 @@ module Homebrew description <<~EOS Valid shells: bash|csh|fish|pwsh|sh|tcsh|zsh - Print export statements. When run in a shell, this installation of Homebrew will be added to your `PATH`, `MANPATH`, and `INFOPATH`. + Print export statements. When run in a shell, this installation of Homebrew will be added to your + `$PATH`, `$MANPATH`, and `$INFOPATH`. The variables `$HOMEBREW_PREFIX`, `$HOMEBREW_CELLAR` and `$HOMEBREW_REPOSITORY` are also exported to avoid querying them multiple times. To help guarantee idempotence, this command produces no output when Homebrew's `bin` and `sbin` directories - are first and second respectively in your `PATH`. Consider adding evaluation of this command's output to + are first and second respectively in your `$PATH`. Consider adding evaluation of this command's output to your dotfiles (e.g. `~/.bash_profile` or ~/.zprofile` on macOS and ~/.bashrc` or ~/.zshrc` on Linux) with: `eval "$(brew shellenv)"` The shell can be specified explicitly with a supported shell name parameter. Unknown shells will output POSIX exports. EOS + named_args :shell end end diff --git a/Library/Homebrew/cmd/upgrade.rb b/Library/Homebrew/cmd/upgrade.rb index 9895706138..d1880ea4bd 100644 --- a/Library/Homebrew/cmd/upgrade.rb +++ b/Library/Homebrew/cmd/upgrade.rb @@ -29,8 +29,8 @@ module Homebrew description: "If brewing fails, open an interactive debugging session with access to IRB " \ "or a shell inside the temporary build directory." switch "--display-times", - env: :display_install_times, - description: "Print install times for each package at the end of the run." + description: "Print install times for each package at the end of the run.", + env: :display_install_times switch "-f", "--force", description: "Install formulae without checking for previously installed keg-only or " \ "non-migrated versions. When installing casks, overwrite existing files " \ @@ -41,7 +41,7 @@ module Homebrew description: "Show what would be upgraded, but do not actually upgrade anything." switch "--ask", description: "Ask for confirmation before downloading and upgrading formulae. " \ - "Print bottles and dependencies download size, install and net install size.", + "Print download, install and net install sizes of bottles and dependencies.", env: :ask [ [:switch, "--formula", "--formulae", { diff --git a/Library/Homebrew/dev-cmd/audit.rb b/Library/Homebrew/dev-cmd/audit.rb index 24e69cb463..7b20891797 100644 --- a/Library/Homebrew/dev-cmd/audit.rb +++ b/Library/Homebrew/dev-cmd/audit.rb @@ -43,7 +43,7 @@ module Homebrew description: "Only check formulae and casks that are currently installed." switch "--eval-all", description: "Evaluate all available formulae and casks, whether installed or not, to audit them. " \ - "Implied if `HOMEBREW_EVAL_ALL` is set." + "Implied if `$HOMEBREW_EVAL_ALL` is set." switch "--new", description: "Run various additional style checks to determine if a new formula or cask is eligible " \ "for Homebrew. This should be used when creating new formulae or casks and implies " \ diff --git a/Library/Homebrew/dev-cmd/bump.rb b/Library/Homebrew/dev-cmd/bump.rb index e9422d9e56..1d510088fa 100644 --- a/Library/Homebrew/dev-cmd/bump.rb +++ b/Library/Homebrew/dev-cmd/bump.rb @@ -118,7 +118,7 @@ module Homebrew else raise UsageError, "`brew bump` without named arguments needs `--installed` or `--eval-all` passed or " \ - "`HOMEBREW_EVAL_ALL` set!" + "`$HOMEBREW_EVAL_ALL` set!" end if args.start_with diff --git a/Library/Homebrew/dev-cmd/determine-test-runners.rb b/Library/Homebrew/dev-cmd/determine-test-runners.rb index 39449ea83f..52757b3f8d 100644 --- a/Library/Homebrew/dev-cmd/determine-test-runners.rb +++ b/Library/Homebrew/dev-cmd/determine-test-runners.rb @@ -21,7 +21,8 @@ module Homebrew "dependents.", env: :eval_all switch "--dependents", - description: "Determine runners for testing dependents. Requires `--eval-all` or `HOMEBREW_EVAL_ALL`.", + description: "Determine runners for testing dependents. " \ + "Requires `--eval-all` or `$HOMEBREW_EVAL_ALL` to be set.", depends_on: "--eval-all" named_args max: 2 diff --git a/Library/Homebrew/dev-cmd/edit.rb b/Library/Homebrew/dev-cmd/edit.rb index d88d603735..bee0caf795 100644 --- a/Library/Homebrew/dev-cmd/edit.rb +++ b/Library/Homebrew/dev-cmd/edit.rb @@ -9,10 +9,9 @@ module Homebrew class Edit < AbstractCommand cmd_args do description <<~EOS - Open a , or in the editor set by `EDITOR` or `HOMEBREW_EDITOR`, + Open a , or in the editor set by `$EDITOR` or `$HOMEBREW_EDITOR`, or open the Homebrew repository for editing if no argument is provided. EOS - switch "--formula", "--formulae", description: "Treat all named arguments as formulae." switch "--cask", "--casks", diff --git a/Library/Homebrew/dev-cmd/irb.rb b/Library/Homebrew/dev-cmd/irb.rb index 31cf968bcc..55107b78c1 100644 --- a/Library/Homebrew/dev-cmd/irb.rb +++ b/Library/Homebrew/dev-cmd/irb.rb @@ -44,8 +44,8 @@ module Homebrew switch "--examples", description: "Show several examples." switch "--pry", - env: :pry, - description: "Use Pry instead of IRB. Implied if `HOMEBREW_PRY` is set." + description: "Use Pry instead of IRB.", + env: :pry end # work around IRB modifying ARGV. diff --git a/Library/Homebrew/dev-cmd/linkage.rb b/Library/Homebrew/dev-cmd/linkage.rb index 23462cc98a..73ce789aed 100644 --- a/Library/Homebrew/dev-cmd/linkage.rb +++ b/Library/Homebrew/dev-cmd/linkage.rb @@ -23,7 +23,7 @@ module Homebrew description: "For every library that a keg references, print its dylib path followed by the " \ "binaries that link to it." switch "--cached", - description: "Print the cached linkage values stored in `HOMEBREW_CACHE`, set by a previous " \ + description: "Print the cached linkage values stored in `$HOMEBREW_CACHE`, set by a previous " \ "`brew linkage` run." named_args :installed_formula diff --git a/Library/Homebrew/dev-cmd/livecheck.rb b/Library/Homebrew/dev-cmd/livecheck.rb index dee478de47..af56300ab9 100644 --- a/Library/Homebrew/dev-cmd/livecheck.rb +++ b/Library/Homebrew/dev-cmd/livecheck.rb @@ -13,7 +13,7 @@ module Homebrew description <<~EOS Check for newer versions of formulae and/or casks from upstream. If no formula or cask argument is passed, the list of formulae and - casks to check is taken from `HOMEBREW_LIVECHECK_WATCHLIST` or + casks to check is taken from `$HOMEBREW_LIVECHECK_WATCHLIST` or `~/.homebrew/livecheck_watchlist.txt`. EOS switch "--full-name", diff --git a/Library/Homebrew/dev-cmd/sh.rb b/Library/Homebrew/dev-cmd/sh.rb index c6161dd1ad..2ba18a56e9 100644 --- a/Library/Homebrew/dev-cmd/sh.rb +++ b/Library/Homebrew/dev-cmd/sh.rb @@ -13,11 +13,11 @@ module Homebrew Enter an interactive shell for Homebrew's build environment. Use years-battle-hardened build logic to help your `./configure && make && make install` and even your `gem install` succeed. Especially handy if you run Homebrew - in an Xcode-only configuration since it adds tools like `make` to your `PATH` + in an Xcode-only configuration since it adds tools like `make` to your `$PATH` which build systems would not find otherwise. EOS flag "--env=", - description: "Use the standard `PATH` instead of superenv's when `std` is passed." + description: "Use the standard `$PATH` instead of superenv's when `std` is passed." flag "-c=", "--cmd=", description: "Execute commands in a non-interactive shell." diff --git a/Library/Homebrew/dev-cmd/unbottled.rb b/Library/Homebrew/dev-cmd/unbottled.rb index 3fb1880093..d439868d22 100644 --- a/Library/Homebrew/dev-cmd/unbottled.rb +++ b/Library/Homebrew/dev-cmd/unbottled.rb @@ -23,7 +23,7 @@ module Homebrew description: "Print the `homebrew/core` commits where bottles were lost in the last week." switch "--eval-all", description: "Evaluate all available formulae and casks, whether installed or not, to check them. " \ - "Implied if `HOMEBREW_EVAL_ALL` is set." + "Implied if `$HOMEBREW_EVAL_ALL` is set." conflicts "--dependents", "--total", "--lost" @@ -68,7 +68,7 @@ module Homebrew all = args.eval_all? if args.total? if !all && !Homebrew::EnvConfig.eval_all? - raise UsageError, "`brew unbottled --total` needs `--eval-all` passed or `HOMEBREW_EVAL_ALL` set!" + raise UsageError, "`brew unbottled --total` needs `--eval-all` passed or `$HOMEBREW_EVAL_ALL` set!" end all = true @@ -119,7 +119,7 @@ module Homebrew elsif args.dependents? if !args.eval_all? && !Homebrew::EnvConfig.eval_all? raise UsageError, - "`brew unbottled --dependents` needs `--eval-all` passed or `HOMEBREW_EVAL_ALL` set!" + "`brew unbottled --dependents` needs `--eval-all` passed or `$HOMEBREW_EVAL_ALL` set!" end formulae = all_formulae = Formula.all(eval_all: args.eval_all?) @@ -136,7 +136,7 @@ module Homebrew if analytics.blank? raise UsageError, "default sort by analytics data requires " \ - "`HOMEBREW_NO_GITHUB_API` and `HOMEBREW_NO_ANALYTICS` to be unset" + "`$HOMEBREW_NO_GITHUB_API` and `$HOMEBREW_NO_ANALYTICS` to be unset." end formulae = analytics["items"].filter_map do |i| diff --git a/Library/Homebrew/dev-cmd/update-test.rb b/Library/Homebrew/dev-cmd/update-test.rb index eb975b73fd..45a0257797 100644 --- a/Library/Homebrew/dev-cmd/update-test.rb +++ b/Library/Homebrew/dev-cmd/update-test.rb @@ -15,7 +15,7 @@ module Homebrew If no options are passed, use `origin/master` as the start commit. EOS switch "--to-tag", - description: "Set `HOMEBREW_UPDATE_TO_TAG` to test updating between tags." + description: "Set `$HOMEBREW_UPDATE_TO_TAG` to test updating between tags." switch "--keep-tmp", description: "Retain the temporary directory containing the new repository clone." flag "--commit=", diff --git a/Library/Homebrew/env_config.rb b/Library/Homebrew/env_config.rb index 7fc446340d..1af588add6 100644 --- a/Library/Homebrew/env_config.rb +++ b/Library/Homebrew/env_config.rb @@ -463,7 +463,7 @@ module Homebrew default_text: "`~/.ssh/config`", }, HOMEBREW_SUDO_THROUGH_SUDO_USER: { - description: "If set, Homebrew will use the `SUDO_USER` environment variable to define the user to " \ + description: "If set, Homebrew will use the `$SUDO_USER` environment variable to define the user to " \ "`sudo`(8) through when running `sudo`(8).", boolean: true, }, diff --git a/Library/Homebrew/manpages/brew.1.md.erb b/Library/Homebrew/manpages/brew.1.md.erb index d3b0173d8a..13461256a3 100644 --- a/Library/Homebrew/manpages/brew.1.md.erb +++ b/Library/Homebrew/manpages/brew.1.md.erb @@ -133,7 +133,7 @@ If no search term is provided, all locally available formulae are listed. ## CUSTOM EXTERNAL COMMANDS Homebrew, like `git`(1), supports external commands. These are executable -scripts that reside somewhere in the `PATH`, named `brew-` or +scripts that reside somewhere in the `$PATH`, named `brew-` or `brew-``.rb`, which can be invoked like `brew` . This allows you to create your own commands without modifying Homebrew's internals. @@ -184,7 +184,7 @@ files: User-specific environment files take precedence over prefix-specific files and prefix-specific files take precedence over system-wide files (unless -`HOMEBREW_SYSTEM_ENV_TAKES_PRIORITY` is set, see below). +`$HOMEBREW_SYSTEM_ENV_TAKES_PRIORITY` is set, see below). Note that these files do not support shell variable expansion e.g. `$HOME` or command execution e.g. `$(cat file)`. diff --git a/completions/fish/brew.fish b/completions/fish/brew.fish index 0457b6dd6a..8a0face365 100644 --- a/completions/fish/brew.fish +++ b/completions/fish/brew.fish @@ -344,7 +344,7 @@ __fish_brew_complete_arg 'audit' -l audit-debug -d 'Enable debugging and profili __fish_brew_complete_arg 'audit' -l cask -d 'Treat all named arguments as casks' __fish_brew_complete_arg 'audit' -l debug -d 'Display any debugging information' __fish_brew_complete_arg 'audit' -l display-filename -d 'Prefix every line of output with the file or formula name being audited, to make output easy to grep' -__fish_brew_complete_arg 'audit' -l eval-all -d 'Evaluate all available formulae and casks, whether installed or not, to audit them. Implied if `HOMEBREW_EVAL_ALL` is set' +__fish_brew_complete_arg 'audit' -l eval-all -d 'Evaluate all available formulae and casks, whether installed or not, to audit them. Implied if `$HOMEBREW_EVAL_ALL` is set' __fish_brew_complete_arg 'audit' -l except -d 'Specify a comma-separated method list to skip running the methods named `audit_`method' __fish_brew_complete_arg 'audit' -l except-cops -d 'Specify a comma-separated cops list to skip checking for violations of the listed RuboCop cops' __fish_brew_complete_arg 'audit' -l fix -d 'Fix style violations automatically using RuboCop\'s auto-correct feature' @@ -508,9 +508,9 @@ __fish_brew_complete_sub_cmd 'bundle' 'edit' __fish_brew_complete_arg 'bundle' -l all -d '`list` all dependencies' __fish_brew_complete_arg 'bundle' -l cask -d '`list`, `dump` or `cleanup` Homebrew cask dependencies' __fish_brew_complete_arg 'bundle' -l check -d 'Check that all dependencies in the Brewfile are installed before running `exec`, `sh`, or `env`' -__fish_brew_complete_arg 'bundle' -l cleanup -d '`install` performs cleanup operation, same as running `cleanup --force`. This is enabled by default if `$HOMEBREW_BUNDLE_INSTALL_CLEANUP` is set and `--global` is passed' +__fish_brew_complete_arg 'bundle' -l cleanup -d '`install` performs cleanup operation, same as running `cleanup --force`. Enabled by default if `$HOMEBREW_BUNDLE_INSTALL_CLEANUP` is set and `--global` is passed' __fish_brew_complete_arg 'bundle' -l debug -d 'Display any debugging information' -__fish_brew_complete_arg 'bundle' -l describe -d '`dump` adds a description comment above each line, unless the dependency does not have a description. This is enabled by default if `$HOMEBREW_BUNDLE_DUMP_DESCRIBE` is set' +__fish_brew_complete_arg 'bundle' -l describe -d '`dump` adds a description comment above each line, unless the dependency does not have a description. Enabled by default if `$HOMEBREW_BUNDLE_DUMP_DESCRIBE` is set' __fish_brew_complete_arg 'bundle' -l file -d 'Read from or write to the `Brewfile` from this location. Use `--file=-` to pipe to stdin/stdout' __fish_brew_complete_arg 'bundle' -l force -d '`install` runs with `--force`/`--overwrite`. `dump` overwrites an existing `Brewfile`. `cleanup` actually performs its cleanup operations' __fish_brew_complete_arg 'bundle' -l formula -d '`list`, `dump` or `cleanup` Homebrew formula dependencies' @@ -519,10 +519,10 @@ __fish_brew_complete_arg 'bundle' -l help -d 'Show this message' __fish_brew_complete_arg 'bundle' -l install -d 'Run `install` before continuing to other operations e.g. `exec`' __fish_brew_complete_arg 'bundle' -l mas -d '`list` or `dump` Mac App Store dependencies' __fish_brew_complete_arg 'bundle' -l no-restart -d '`dump` does not add `restart_service` to formula lines' -__fish_brew_complete_arg 'bundle' -l no-upgrade -d '`install` does not run `brew upgrade` on outdated dependencies. `check` does not check for outdated dependencies. Note they may still be upgraded by `brew install` if needed. This is enabled by default if `$HOMEBREW_BUNDLE_NO_UPGRADE` is set' -__fish_brew_complete_arg 'bundle' -l no-vscode -d '`dump` without VSCode (and forks/variants) extensions. This is enabled by default if `$HOMEBREW_BUNDLE_DUMP_NO_VSCODE` is set' +__fish_brew_complete_arg 'bundle' -l no-upgrade -d '`install` does not run `brew upgrade` on outdated dependencies. `check` does not check for outdated dependencies. Note they may still be upgraded by `brew install` if needed. Enabled by default if `$HOMEBREW_BUNDLE_NO_UPGRADE` is set' +__fish_brew_complete_arg 'bundle' -l no-vscode -d '`dump` without VSCode (and forks/variants) extensions. Enabled by default if `$HOMEBREW_BUNDLE_DUMP_NO_VSCODE` is set' __fish_brew_complete_arg 'bundle' -l quiet -d 'Make some output more quiet' -__fish_brew_complete_arg 'bundle' -l services -d 'Temporarily start services while running the `exec` or `sh` command. This is enabled by default if `$HOMEBREW_BUNDLE_SERVICES` is set' +__fish_brew_complete_arg 'bundle' -l services -d 'Temporarily start services while running the `exec` or `sh` command. Enabled by default if `$HOMEBREW_BUNDLE_SERVICES` is set' __fish_brew_complete_arg 'bundle' -l tap -d '`list`, `dump` or `cleanup` Homebrew tap dependencies' __fish_brew_complete_arg 'bundle' -l upgrade -d '`install` runs `brew upgrade` on outdated dependencies, even if `$HOMEBREW_BUNDLE_NO_UPGRADE` is set' __fish_brew_complete_arg 'bundle' -l upgrade-formulae -d '`install` runs `brew upgrade` on any of these comma-separated formulae, even if `$HOMEBREW_BUNDLE_NO_UPGRADE` is set' @@ -694,8 +694,8 @@ __fish_brew_complete_arg 'desc; and not __fish_seen_argument -l formula -l formu __fish_brew_complete_cmd 'determine-test-runners' 'Determines the runners used to test formulae or their dependents' __fish_brew_complete_arg 'determine-test-runners' -l all-supported -d 'Instead of selecting runners based on the chosen formula, return all supported runners' __fish_brew_complete_arg 'determine-test-runners' -l debug -d 'Display any debugging information' -__fish_brew_complete_arg 'determine-test-runners' -l dependents -d 'Determine runners for testing dependents. Requires `--eval-all` or `HOMEBREW_EVAL_ALL`' -__fish_brew_complete_arg 'determine-test-runners' -l eval-all -d 'Evaluate all available formulae, whether installed or not, to determine testing dependents' +__fish_brew_complete_arg 'determine-test-runners' -l dependents -d 'Determine runners for testing dependents. Requires `--eval-all` or `$HOMEBREW_EVAL_ALL` to be set' +__fish_brew_complete_arg 'determine-test-runners' -l eval-all -d 'Evaluate all available formulae, whether installed or not, to determine testing dependents. Enabled by default if `$HOMEBREW_EVAL_ALL` is set' __fish_brew_complete_arg 'determine-test-runners' -l help -d 'Show this message' __fish_brew_complete_arg 'determine-test-runners' -l quiet -d 'Make some output more quiet' __fish_brew_complete_arg 'determine-test-runners' -l verbose -d 'Make some output more verbose' @@ -756,7 +756,7 @@ __fish_brew_complete_arg 'dr' -l verbose -d 'Make some output more verbose' __fish_brew_complete_arg 'dr' -a '(__fish_brew_suggest_diagnostic_checks)' -__fish_brew_complete_cmd 'edit' 'Open a formula, cask or tap in the editor set by `EDITOR` or `HOMEBREW_EDITOR`, or open the Homebrew repository for editing if no argument is provided' +__fish_brew_complete_cmd 'edit' 'Open a formula, cask or tap in the editor set by `$EDITOR` or `$HOMEBREW_EDITOR`, or open the Homebrew repository for editing if no argument is provided' __fish_brew_complete_arg 'edit' -l cask -d 'Treat all named arguments as casks' __fish_brew_complete_arg 'edit' -l debug -d 'Display any debugging information' __fish_brew_complete_arg 'edit' -l formula -d 'Treat all named arguments as formulae' @@ -804,9 +804,9 @@ __fish_brew_complete_arg 'fetch' -l force -d 'Remove a previously cached version __fish_brew_complete_arg 'fetch' -l force-bottle -d 'Download a bottle if it exists for the current or newest version of macOS, even if it would not be used during installation' __fish_brew_complete_arg 'fetch' -l formula -d 'Treat all named arguments as formulae' __fish_brew_complete_arg 'fetch' -l help -d 'Show this message' -__fish_brew_complete_arg 'fetch' -l no-quarantine -d 'Disable/enable quarantining of downloads (default: enabled)' +__fish_brew_complete_arg 'fetch' -l no-quarantine -d 'Disable/enable quarantining of downloads (default: enabled). Enabled by default if `$HOMEBREW_CASK_OPTS_QUARANTINE` is set' __fish_brew_complete_arg 'fetch' -l os -d 'Download for the given operating system. (Pass `all` to download for all operating systems.)' -__fish_brew_complete_arg 'fetch' -l quarantine -d 'Disable/enable quarantining of downloads (default: enabled)' +__fish_brew_complete_arg 'fetch' -l quarantine -d 'Disable/enable quarantining of downloads (default: enabled). Enabled by default if `$HOMEBREW_CASK_OPTS_QUARANTINE` is set' __fish_brew_complete_arg 'fetch' -l quiet -d 'Make some output more quiet' __fish_brew_complete_arg 'fetch' -l retry -d 'Retry if downloading fails or re-download if the checksum of a previously cached version no longer matches. Tries at most 5 times with exponential backoff' __fish_brew_complete_arg 'fetch' -l verbose -d 'Do a verbose VCS checkout, if the URL represents a VCS. This is useful for seeing if an existing VCS cache has been updated' @@ -952,9 +952,9 @@ __fish_brew_complete_arg 'instal' -l HEAD -d 'If formula defines it, install the __fish_brew_complete_arg 'instal' -l adopt -d 'Adopt existing artifacts in the destination that are identical to those being installed. Cannot be combined with `--force`' __fish_brew_complete_arg 'instal' -l appdir -d 'Target location for Applications (default: `/Applications`)' __fish_brew_complete_arg 'instal' -l as-dependency -d 'Install but mark as installed as a dependency and not installed on request' -__fish_brew_complete_arg 'instal' -l ask -d 'Ask for confirmation before downloading and installing formulae. Print bottles and dependencies download size and install size' +__fish_brew_complete_arg 'instal' -l ask -d 'Ask for confirmation before downloading and installing formulae. Print download and install sizes of bottles and dependencies. Enabled by default if `$HOMEBREW_ASK` is set' __fish_brew_complete_arg 'instal' -l audio-unit-plugindir -d 'Target location for Audio Unit Plugins (default: `~/Library/Audio/Plug-Ins/Components`)' -__fish_brew_complete_arg 'instal' -l binaries -d 'Disable/enable linking of helper executables (default: enabled)' +__fish_brew_complete_arg 'instal' -l binaries -d 'Disable/enable linking of helper executables (default: enabled). Enabled by default if `$HOMEBREW_CASK_OPTS_BINARIES` is set' __fish_brew_complete_arg 'instal' -l bottle-arch -d 'Optimise bottles for the specified architecture rather than the oldest architecture supported by the version of macOS the bottles are built on' __fish_brew_complete_arg 'instal' -l build-bottle -d 'Prepare the formula for eventual bottling during installation, skipping any post-install steps' __fish_brew_complete_arg 'instal' -l build-from-source -d 'Compile formula from source even if a bottle is provided. Dependencies will still be installed from bottles if they are available' @@ -964,7 +964,7 @@ __fish_brew_complete_arg 'instal' -l colorpickerdir -d 'Target location for Colo __fish_brew_complete_arg 'instal' -l debug -d 'If brewing fails, open an interactive debugging session with access to IRB or a shell inside the temporary build directory' __fish_brew_complete_arg 'instal' -l debug-symbols -d 'Generate debug symbols on build. Source will be retained in a cache directory' __fish_brew_complete_arg 'instal' -l dictionarydir -d 'Target location for Dictionaries (default: `~/Library/Dictionaries`)' -__fish_brew_complete_arg 'instal' -l display-times -d 'Print install times for each package at the end of the run' +__fish_brew_complete_arg 'instal' -l display-times -d 'Print install times for each package at the end of the run. Enabled by default if `$HOMEBREW_DISPLAY_INSTALL_TIMES` is set' __fish_brew_complete_arg 'instal' -l dry-run -d 'Show what would be installed, but do not actually install anything' __fish_brew_complete_arg 'instal' -l fetch-HEAD -d 'Fetch the upstream repository to detect if the HEAD installation of the formula is outdated. Otherwise, the repository\'s HEAD will only be checked for updates when a new stable or development version has been released' __fish_brew_complete_arg 'instal' -l fontdir -d 'Target location for Fonts (default: `~/Library/Fonts`)' @@ -982,15 +982,15 @@ __fish_brew_complete_arg 'instal' -l keep-tmp -d 'Retain the temporary files cre __fish_brew_complete_arg 'instal' -l keyboard-layoutdir -d 'Target location for Keyboard Layouts (default: `/Library/Keyboard Layouts`)' __fish_brew_complete_arg 'instal' -l language -d 'Comma-separated list of language codes to prefer for cask installation. The first matching language is used, otherwise it reverts to the cask\'s default language. The default value is the language of your system' __fish_brew_complete_arg 'instal' -l mdimporterdir -d 'Target location for Spotlight Plugins (default: `~/Library/Spotlight`)' -__fish_brew_complete_arg 'instal' -l no-binaries -d 'Disable/enable linking of helper executables (default: enabled)' -__fish_brew_complete_arg 'instal' -l no-quarantine -d 'Disable/enable quarantining of downloads (default: enabled)' +__fish_brew_complete_arg 'instal' -l no-binaries -d 'Disable/enable linking of helper executables (default: enabled). Enabled by default if `$HOMEBREW_CASK_OPTS_BINARIES` is set' +__fish_brew_complete_arg 'instal' -l no-quarantine -d 'Disable/enable quarantining of downloads (default: enabled). Enabled by default if `$HOMEBREW_CASK_OPTS_QUARANTINE` is set' __fish_brew_complete_arg 'instal' -l only-dependencies -d 'Install the dependencies with specified options but do not install the formula itself' __fish_brew_complete_arg 'instal' -l overwrite -d 'Delete files that already exist in the prefix while linking' __fish_brew_complete_arg 'instal' -l prefpanedir -d 'Target location for Preference Panes (default: `~/Library/PreferencePanes`)' __fish_brew_complete_arg 'instal' -l qlplugindir -d 'Target location for Quick Look Plugins (default: `~/Library/QuickLook`)' -__fish_brew_complete_arg 'instal' -l quarantine -d 'Disable/enable quarantining of downloads (default: enabled)' +__fish_brew_complete_arg 'instal' -l quarantine -d 'Disable/enable quarantining of downloads (default: enabled). Enabled by default if `$HOMEBREW_CASK_OPTS_QUARANTINE` is set' __fish_brew_complete_arg 'instal' -l quiet -d 'Make some output more quiet' -__fish_brew_complete_arg 'instal' -l require-sha -d 'Require all casks to have a checksum' +__fish_brew_complete_arg 'instal' -l require-sha -d 'Require all casks to have a checksum. Enabled by default if `$HOMEBREW_CASK_OPTS_REQUIRE_SHA` is set' __fish_brew_complete_arg 'instal' -l screen-saverdir -d 'Target location for Screen Savers (default: `~/Library/Screen Savers`)' __fish_brew_complete_arg 'instal' -l servicedir -d 'Target location for Services (default: `~/Library/Services`)' __fish_brew_complete_arg 'instal' -l skip-cask-deps -d 'Skip installing cask dependencies' @@ -1009,9 +1009,9 @@ __fish_brew_complete_arg 'install' -l HEAD -d 'If formula defines it, install th __fish_brew_complete_arg 'install' -l adopt -d 'Adopt existing artifacts in the destination that are identical to those being installed. Cannot be combined with `--force`' __fish_brew_complete_arg 'install' -l appdir -d 'Target location for Applications (default: `/Applications`)' __fish_brew_complete_arg 'install' -l as-dependency -d 'Install but mark as installed as a dependency and not installed on request' -__fish_brew_complete_arg 'install' -l ask -d 'Ask for confirmation before downloading and installing formulae. Print bottles and dependencies download size and install size' +__fish_brew_complete_arg 'install' -l ask -d 'Ask for confirmation before downloading and installing formulae. Print download and install sizes of bottles and dependencies. Enabled by default if `$HOMEBREW_ASK` is set' __fish_brew_complete_arg 'install' -l audio-unit-plugindir -d 'Target location for Audio Unit Plugins (default: `~/Library/Audio/Plug-Ins/Components`)' -__fish_brew_complete_arg 'install' -l binaries -d 'Disable/enable linking of helper executables (default: enabled)' +__fish_brew_complete_arg 'install' -l binaries -d 'Disable/enable linking of helper executables (default: enabled). Enabled by default if `$HOMEBREW_CASK_OPTS_BINARIES` is set' __fish_brew_complete_arg 'install' -l bottle-arch -d 'Optimise bottles for the specified architecture rather than the oldest architecture supported by the version of macOS the bottles are built on' __fish_brew_complete_arg 'install' -l build-bottle -d 'Prepare the formula for eventual bottling during installation, skipping any post-install steps' __fish_brew_complete_arg 'install' -l build-from-source -d 'Compile formula from source even if a bottle is provided. Dependencies will still be installed from bottles if they are available' @@ -1021,7 +1021,7 @@ __fish_brew_complete_arg 'install' -l colorpickerdir -d 'Target location for Col __fish_brew_complete_arg 'install' -l debug -d 'If brewing fails, open an interactive debugging session with access to IRB or a shell inside the temporary build directory' __fish_brew_complete_arg 'install' -l debug-symbols -d 'Generate debug symbols on build. Source will be retained in a cache directory' __fish_brew_complete_arg 'install' -l dictionarydir -d 'Target location for Dictionaries (default: `~/Library/Dictionaries`)' -__fish_brew_complete_arg 'install' -l display-times -d 'Print install times for each package at the end of the run' +__fish_brew_complete_arg 'install' -l display-times -d 'Print install times for each package at the end of the run. Enabled by default if `$HOMEBREW_DISPLAY_INSTALL_TIMES` is set' __fish_brew_complete_arg 'install' -l dry-run -d 'Show what would be installed, but do not actually install anything' __fish_brew_complete_arg 'install' -l fetch-HEAD -d 'Fetch the upstream repository to detect if the HEAD installation of the formula is outdated. Otherwise, the repository\'s HEAD will only be checked for updates when a new stable or development version has been released' __fish_brew_complete_arg 'install' -l fontdir -d 'Target location for Fonts (default: `~/Library/Fonts`)' @@ -1039,15 +1039,15 @@ __fish_brew_complete_arg 'install' -l keep-tmp -d 'Retain the temporary files cr __fish_brew_complete_arg 'install' -l keyboard-layoutdir -d 'Target location for Keyboard Layouts (default: `/Library/Keyboard Layouts`)' __fish_brew_complete_arg 'install' -l language -d 'Comma-separated list of language codes to prefer for cask installation. The first matching language is used, otherwise it reverts to the cask\'s default language. The default value is the language of your system' __fish_brew_complete_arg 'install' -l mdimporterdir -d 'Target location for Spotlight Plugins (default: `~/Library/Spotlight`)' -__fish_brew_complete_arg 'install' -l no-binaries -d 'Disable/enable linking of helper executables (default: enabled)' -__fish_brew_complete_arg 'install' -l no-quarantine -d 'Disable/enable quarantining of downloads (default: enabled)' +__fish_brew_complete_arg 'install' -l no-binaries -d 'Disable/enable linking of helper executables (default: enabled). Enabled by default if `$HOMEBREW_CASK_OPTS_BINARIES` is set' +__fish_brew_complete_arg 'install' -l no-quarantine -d 'Disable/enable quarantining of downloads (default: enabled). Enabled by default if `$HOMEBREW_CASK_OPTS_QUARANTINE` is set' __fish_brew_complete_arg 'install' -l only-dependencies -d 'Install the dependencies with specified options but do not install the formula itself' __fish_brew_complete_arg 'install' -l overwrite -d 'Delete files that already exist in the prefix while linking' __fish_brew_complete_arg 'install' -l prefpanedir -d 'Target location for Preference Panes (default: `~/Library/PreferencePanes`)' __fish_brew_complete_arg 'install' -l qlplugindir -d 'Target location for Quick Look Plugins (default: `~/Library/QuickLook`)' -__fish_brew_complete_arg 'install' -l quarantine -d 'Disable/enable quarantining of downloads (default: enabled)' +__fish_brew_complete_arg 'install' -l quarantine -d 'Disable/enable quarantining of downloads (default: enabled). Enabled by default if `$HOMEBREW_CASK_OPTS_QUARANTINE` is set' __fish_brew_complete_arg 'install' -l quiet -d 'Make some output more quiet' -__fish_brew_complete_arg 'install' -l require-sha -d 'Require all casks to have a checksum' +__fish_brew_complete_arg 'install' -l require-sha -d 'Require all casks to have a checksum. Enabled by default if `$HOMEBREW_CASK_OPTS_REQUIRE_SHA` is set' __fish_brew_complete_arg 'install' -l screen-saverdir -d 'Target location for Screen Savers (default: `~/Library/Screen Savers`)' __fish_brew_complete_arg 'install' -l servicedir -d 'Target location for Services (default: `~/Library/Services`)' __fish_brew_complete_arg 'install' -l skip-cask-deps -d 'Skip installing cask dependencies' @@ -1074,7 +1074,7 @@ __fish_brew_complete_cmd 'irb' 'Enter the interactive Homebrew Ruby shell' __fish_brew_complete_arg 'irb' -l debug -d 'Display any debugging information' __fish_brew_complete_arg 'irb' -l examples -d 'Show several examples' __fish_brew_complete_arg 'irb' -l help -d 'Show this message' -__fish_brew_complete_arg 'irb' -l pry -d 'Use Pry instead of IRB. Implied if `HOMEBREW_PRY` is set' +__fish_brew_complete_arg 'irb' -l pry -d 'Use Pry instead of IRB. Enabled by default if `$HOMEBREW_PRY` is set' __fish_brew_complete_arg 'irb' -l quiet -d 'Make some output more quiet' __fish_brew_complete_arg 'irb' -l verbose -d 'Make some output more verbose' @@ -1121,7 +1121,7 @@ __fish_brew_complete_arg 'link' -a '(__fish_brew_suggest_formulae_installed)' __fish_brew_complete_cmd 'linkage' 'Check the library links from the given formula kegs' -__fish_brew_complete_arg 'linkage' -l cached -d 'Print the cached linkage values stored in `HOMEBREW_CACHE`, set by a previous `brew linkage` run' +__fish_brew_complete_arg 'linkage' -l cached -d 'Print the cached linkage values stored in `$HOMEBREW_CACHE`, set by a previous `brew linkage` run' __fish_brew_complete_arg 'linkage' -l debug -d 'Display any debugging information' __fish_brew_complete_arg 'linkage' -l help -d 'Show this message' __fish_brew_complete_arg 'linkage' -l quiet -d 'Make some output more quiet' @@ -1272,7 +1272,7 @@ __fish_brew_complete_arg 'outdated' -l cask -d 'List only outdated casks' __fish_brew_complete_arg 'outdated' -l debug -d 'Display any debugging information' __fish_brew_complete_arg 'outdated' -l fetch-HEAD -d 'Fetch the upstream repository to detect if the HEAD installation of the formula is outdated. Otherwise, the repository\'s HEAD will only be checked for updates when a new stable or development version has been released' __fish_brew_complete_arg 'outdated' -l formula -d 'List only outdated formulae' -__fish_brew_complete_arg 'outdated' -l greedy -d 'Also include outdated casks with `auto_updates true` or `version :latest`' +__fish_brew_complete_arg 'outdated' -l greedy -d 'Also include outdated casks with `auto_updates true` or `version :latest`. Enabled by default if `$HOMEBREW_UPGRADE_GREEDY` is set' __fish_brew_complete_arg 'outdated' -l greedy-auto-updates -d 'Also include outdated casks including those with `auto_updates true`' __fish_brew_complete_arg 'outdated' -l greedy-latest -d 'Also include outdated casks including those with `version :latest`' __fish_brew_complete_arg 'outdated' -l help -d 'Show this message' @@ -1417,16 +1417,16 @@ __fish_brew_complete_arg 'readall' -a '(__fish_brew_suggest_taps_installed)' __fish_brew_complete_cmd 'reinstall' 'Uninstall and then reinstall a formula or cask using the same options it was originally installed with, plus any appended options specific to a formula' __fish_brew_complete_arg 'reinstall' -l adopt -d 'Adopt existing artifacts in the destination that are identical to those being installed. Cannot be combined with `--force`' __fish_brew_complete_arg 'reinstall' -l appdir -d 'Target location for Applications (default: `/Applications`)' -__fish_brew_complete_arg 'reinstall' -l ask -d 'Ask for confirmation before downloading and upgrading formulae. Print bottles and dependencies download size, install and net install size' +__fish_brew_complete_arg 'reinstall' -l ask -d 'Ask for confirmation before downloading and upgrading formulae. Print download, install and net install sizes of bottles and dependencies. Enabled by default if `$HOMEBREW_ASK` is set' __fish_brew_complete_arg 'reinstall' -l audio-unit-plugindir -d 'Target location for Audio Unit Plugins (default: `~/Library/Audio/Plug-Ins/Components`)' -__fish_brew_complete_arg 'reinstall' -l binaries -d 'Disable/enable linking of helper executables (default: enabled)' +__fish_brew_complete_arg 'reinstall' -l binaries -d 'Disable/enable linking of helper executables (default: enabled). Enabled by default if `$HOMEBREW_CASK_OPTS_BINARIES` is set' __fish_brew_complete_arg 'reinstall' -l build-from-source -d 'Compile formula from source even if a bottle is available' __fish_brew_complete_arg 'reinstall' -l cask -d 'Treat all named arguments as casks' __fish_brew_complete_arg 'reinstall' -l colorpickerdir -d 'Target location for Color Pickers (default: `~/Library/ColorPickers`)' __fish_brew_complete_arg 'reinstall' -l debug -d 'If brewing fails, open an interactive debugging session with access to IRB or a shell inside the temporary build directory' __fish_brew_complete_arg 'reinstall' -l debug-symbols -d 'Generate debug symbols on build. Source will be retained in a cache directory' __fish_brew_complete_arg 'reinstall' -l dictionarydir -d 'Target location for Dictionaries (default: `~/Library/Dictionaries`)' -__fish_brew_complete_arg 'reinstall' -l display-times -d 'Print install times for each package at the end of the run' +__fish_brew_complete_arg 'reinstall' -l display-times -d 'Print install times for each package at the end of the run. Enabled by default if `$HOMEBREW_DISPLAY_INSTALL_TIMES` is set' __fish_brew_complete_arg 'reinstall' -l fontdir -d 'Target location for Fonts (default: `~/Library/Fonts`)' __fish_brew_complete_arg 'reinstall' -l force -d 'Install without checking for previously installed keg-only or non-migrated versions' __fish_brew_complete_arg 'reinstall' -l force-bottle -d 'Install from a bottle if it exists for the current or newest version of macOS, even if it would not normally be used for installation' @@ -1440,13 +1440,13 @@ __fish_brew_complete_arg 'reinstall' -l keep-tmp -d 'Retain the temporary files __fish_brew_complete_arg 'reinstall' -l keyboard-layoutdir -d 'Target location for Keyboard Layouts (default: `/Library/Keyboard Layouts`)' __fish_brew_complete_arg 'reinstall' -l language -d 'Comma-separated list of language codes to prefer for cask installation. The first matching language is used, otherwise it reverts to the cask\'s default language. The default value is the language of your system' __fish_brew_complete_arg 'reinstall' -l mdimporterdir -d 'Target location for Spotlight Plugins (default: `~/Library/Spotlight`)' -__fish_brew_complete_arg 'reinstall' -l no-binaries -d 'Disable/enable linking of helper executables (default: enabled)' -__fish_brew_complete_arg 'reinstall' -l no-quarantine -d 'Disable/enable quarantining of downloads (default: enabled)' +__fish_brew_complete_arg 'reinstall' -l no-binaries -d 'Disable/enable linking of helper executables (default: enabled). Enabled by default if `$HOMEBREW_CASK_OPTS_BINARIES` is set' +__fish_brew_complete_arg 'reinstall' -l no-quarantine -d 'Disable/enable quarantining of downloads (default: enabled). Enabled by default if `$HOMEBREW_CASK_OPTS_QUARANTINE` is set' __fish_brew_complete_arg 'reinstall' -l prefpanedir -d 'Target location for Preference Panes (default: `~/Library/PreferencePanes`)' __fish_brew_complete_arg 'reinstall' -l qlplugindir -d 'Target location for Quick Look Plugins (default: `~/Library/QuickLook`)' -__fish_brew_complete_arg 'reinstall' -l quarantine -d 'Disable/enable quarantining of downloads (default: enabled)' +__fish_brew_complete_arg 'reinstall' -l quarantine -d 'Disable/enable quarantining of downloads (default: enabled). Enabled by default if `$HOMEBREW_CASK_OPTS_QUARANTINE` is set' __fish_brew_complete_arg 'reinstall' -l quiet -d 'Make some output more quiet' -__fish_brew_complete_arg 'reinstall' -l require-sha -d 'Require all casks to have a checksum' +__fish_brew_complete_arg 'reinstall' -l require-sha -d 'Require all casks to have a checksum. Enabled by default if `$HOMEBREW_CASK_OPTS_REQUIRE_SHA` is set' __fish_brew_complete_arg 'reinstall' -l screen-saverdir -d 'Target location for Screen Savers (default: `~/Library/Screen Savers`)' __fish_brew_complete_arg 'reinstall' -l servicedir -d 'Target location for Services (default: `~/Library/Services`)' __fish_brew_complete_arg 'reinstall' -l skip-cask-deps -d 'Skip installing cask dependencies' @@ -1575,7 +1575,7 @@ __fish_brew_complete_arg 'setup-ruby' -a '(__fish_brew_suggest_commands)' __fish_brew_complete_cmd 'sh' 'Enter an interactive shell for Homebrew\'s build environment' __fish_brew_complete_arg 'sh' -l cmd -d 'Execute commands in a non-interactive shell' __fish_brew_complete_arg 'sh' -l debug -d 'Display any debugging information' -__fish_brew_complete_arg 'sh' -l env -d 'Use the standard `PATH` instead of superenv\'s when `std` is passed' +__fish_brew_complete_arg 'sh' -l env -d 'Use the standard `$PATH` instead of superenv\'s when `std` is passed' __fish_brew_complete_arg 'sh' -l help -d 'Show this message' __fish_brew_complete_arg 'sh' -l quiet -d 'Make some output more quiet' __fish_brew_complete_arg 'sh' -l verbose -d 'Make some output more verbose' @@ -1720,7 +1720,7 @@ __fish_brew_complete_arg 'unalias' -l verbose -d 'Make some output more verbose' __fish_brew_complete_cmd 'unbottled' 'Show the unbottled dependents of formulae' __fish_brew_complete_arg 'unbottled' -l debug -d 'Display any debugging information' __fish_brew_complete_arg 'unbottled' -l dependents -d 'Skip getting analytics data and sort by number of dependents instead' -__fish_brew_complete_arg 'unbottled' -l eval-all -d 'Evaluate all available formulae and casks, whether installed or not, to check them. Implied if `HOMEBREW_EVAL_ALL` is set' +__fish_brew_complete_arg 'unbottled' -l eval-all -d 'Evaluate all available formulae and casks, whether installed or not, to check them. Implied if `$HOMEBREW_EVAL_ALL` is set' __fish_brew_complete_arg 'unbottled' -l help -d 'Show this message' __fish_brew_complete_arg 'unbottled' -l lost -d 'Print the `homebrew/core` commits where bottles were lost in the last week' __fish_brew_complete_arg 'unbottled' -l quiet -d 'Make some output more quiet' @@ -1882,22 +1882,22 @@ __fish_brew_complete_arg 'update-test' -l debug -d 'Display any debugging inform __fish_brew_complete_arg 'update-test' -l help -d 'Show this message' __fish_brew_complete_arg 'update-test' -l keep-tmp -d 'Retain the temporary directory containing the new repository clone' __fish_brew_complete_arg 'update-test' -l quiet -d 'Make some output more quiet' -__fish_brew_complete_arg 'update-test' -l to-tag -d 'Set `HOMEBREW_UPDATE_TO_TAG` to test updating between tags' +__fish_brew_complete_arg 'update-test' -l to-tag -d 'Set `$HOMEBREW_UPDATE_TO_TAG` to test updating between tags' __fish_brew_complete_arg 'update-test' -l verbose -d 'Make some output more verbose' __fish_brew_complete_cmd 'upgrade' 'Upgrade outdated casks and outdated, unpinned formulae using the same options they were originally installed with, plus any appended brew formula options' __fish_brew_complete_arg 'upgrade' -l appdir -d 'Target location for Applications (default: `/Applications`)' -__fish_brew_complete_arg 'upgrade' -l ask -d 'Ask for confirmation before downloading and upgrading formulae. Print bottles and dependencies download size, install and net install size' +__fish_brew_complete_arg 'upgrade' -l ask -d 'Ask for confirmation before downloading and upgrading formulae. Print download, install and net install sizes of bottles and dependencies. Enabled by default if `$HOMEBREW_ASK` is set' __fish_brew_complete_arg 'upgrade' -l audio-unit-plugindir -d 'Target location for Audio Unit Plugins (default: `~/Library/Audio/Plug-Ins/Components`)' -__fish_brew_complete_arg 'upgrade' -l binaries -d 'Disable/enable linking of helper executables (default: enabled)' +__fish_brew_complete_arg 'upgrade' -l binaries -d 'Disable/enable linking of helper executables (default: enabled). Enabled by default if `$HOMEBREW_CASK_OPTS_BINARIES` is set' __fish_brew_complete_arg 'upgrade' -l build-from-source -d 'Compile formula from source even if a bottle is available' __fish_brew_complete_arg 'upgrade' -l cask -d 'Treat all named arguments as casks. If no named arguments are specified, upgrade only outdated casks' __fish_brew_complete_arg 'upgrade' -l colorpickerdir -d 'Target location for Color Pickers (default: `~/Library/ColorPickers`)' __fish_brew_complete_arg 'upgrade' -l debug -d 'If brewing fails, open an interactive debugging session with access to IRB or a shell inside the temporary build directory' __fish_brew_complete_arg 'upgrade' -l debug-symbols -d 'Generate debug symbols on build. Source will be retained in a cache directory' __fish_brew_complete_arg 'upgrade' -l dictionarydir -d 'Target location for Dictionaries (default: `~/Library/Dictionaries`)' -__fish_brew_complete_arg 'upgrade' -l display-times -d 'Print install times for each package at the end of the run' +__fish_brew_complete_arg 'upgrade' -l display-times -d 'Print install times for each package at the end of the run. Enabled by default if `$HOMEBREW_DISPLAY_INSTALL_TIMES` is set' __fish_brew_complete_arg 'upgrade' -l dry-run -d 'Show what would be upgraded, but do not actually upgrade anything' __fish_brew_complete_arg 'upgrade' -l fetch-HEAD -d 'Fetch the upstream repository to detect if the HEAD installation of the formula is outdated. Otherwise, the repository\'s HEAD will only be checked for updates when a new stable or development version has been released' __fish_brew_complete_arg 'upgrade' -l fontdir -d 'Target location for Fonts (default: `~/Library/Fonts`)' @@ -1915,14 +1915,14 @@ __fish_brew_complete_arg 'upgrade' -l keep-tmp -d 'Retain the temporary files cr __fish_brew_complete_arg 'upgrade' -l keyboard-layoutdir -d 'Target location for Keyboard Layouts (default: `/Library/Keyboard Layouts`)' __fish_brew_complete_arg 'upgrade' -l language -d 'Comma-separated list of language codes to prefer for cask installation. The first matching language is used, otherwise it reverts to the cask\'s default language. The default value is the language of your system' __fish_brew_complete_arg 'upgrade' -l mdimporterdir -d 'Target location for Spotlight Plugins (default: `~/Library/Spotlight`)' -__fish_brew_complete_arg 'upgrade' -l no-binaries -d 'Disable/enable linking of helper executables (default: enabled)' -__fish_brew_complete_arg 'upgrade' -l no-quarantine -d 'Disable/enable quarantining of downloads (default: enabled)' +__fish_brew_complete_arg 'upgrade' -l no-binaries -d 'Disable/enable linking of helper executables (default: enabled). Enabled by default if `$HOMEBREW_CASK_OPTS_BINARIES` is set' +__fish_brew_complete_arg 'upgrade' -l no-quarantine -d 'Disable/enable quarantining of downloads (default: enabled). Enabled by default if `$HOMEBREW_CASK_OPTS_QUARANTINE` is set' __fish_brew_complete_arg 'upgrade' -l overwrite -d 'Delete files that already exist in the prefix while linking' __fish_brew_complete_arg 'upgrade' -l prefpanedir -d 'Target location for Preference Panes (default: `~/Library/PreferencePanes`)' __fish_brew_complete_arg 'upgrade' -l qlplugindir -d 'Target location for Quick Look Plugins (default: `~/Library/QuickLook`)' -__fish_brew_complete_arg 'upgrade' -l quarantine -d 'Disable/enable quarantining of downloads (default: enabled)' +__fish_brew_complete_arg 'upgrade' -l quarantine -d 'Disable/enable quarantining of downloads (default: enabled). Enabled by default if `$HOMEBREW_CASK_OPTS_QUARANTINE` is set' __fish_brew_complete_arg 'upgrade' -l quiet -d 'Make some output more quiet' -__fish_brew_complete_arg 'upgrade' -l require-sha -d 'Require all casks to have a checksum' +__fish_brew_complete_arg 'upgrade' -l require-sha -d 'Require all casks to have a checksum. Enabled by default if `$HOMEBREW_CASK_OPTS_REQUIRE_SHA` is set' __fish_brew_complete_arg 'upgrade' -l screen-saverdir -d 'Target location for Screen Savers (default: `~/Library/Screen Savers`)' __fish_brew_complete_arg 'upgrade' -l servicedir -d 'Target location for Services (default: `~/Library/Services`)' __fish_brew_complete_arg 'upgrade' -l skip-cask-deps -d 'Skip installing cask dependencies' diff --git a/completions/zsh/_brew b/completions/zsh/_brew index 8d1d4e3da9..c1e48d5b19 100644 --- a/completions/zsh/_brew +++ b/completions/zsh/_brew @@ -167,7 +167,7 @@ __brew_internal_commands() { 'dispatch-build-bottle:Build bottles for these formulae with GitHub Actions' 'docs:Open Homebrew'\''s online documentation at https://docs.brew.sh in a browser' 'doctor:Check your system for potential problems' - 'edit:Open a formula, cask or tap in the editor set by `EDITOR` or `HOMEBREW_EDITOR`, or open the Homebrew repository for editing if no argument is provided' + 'edit:Open a formula, cask or tap in the editor set by `$EDITOR` or `$HOMEBREW_EDITOR`, or open the Homebrew repository for editing if no argument is provided' 'extract:Look through repository history to find the most recent version of formula and create a copy in tap' 'fetch:Download a bottle (if available) or source packages for formulae and binaries for casks' 'formula:Display the path where formula is located' @@ -467,7 +467,7 @@ _brew_audit() { '--audit-debug[Enable debugging and profiling of audit methods]' \ '--debug[Display any debugging information]' \ '--display-filename[Prefix every line of output with the file or formula name being audited, to make output easy to grep]' \ - '--eval-all[Evaluate all available formulae and casks, whether installed or not, to audit them. Implied if `HOMEBREW_EVAL_ALL` is set]' \ + '--eval-all[Evaluate all available formulae and casks, whether installed or not, to audit them. Implied if `$HOMEBREW_EVAL_ALL` is set]' \ '(--only)--except[Specify a comma-separated method list to skip running the methods named `audit_`method]' \ '(--only-cops --strict --only-cops --only)--except-cops[Specify a comma-separated cops list to skip checking for violations of the listed RuboCop cops]' \ '--fix[Fix style violations automatically using RuboCop'\''s auto-correct feature]' \ @@ -651,9 +651,9 @@ _brew_bundle() { '(--no-vscode)--all[`list` all dependencies]' \ '--cask[`list`, `dump` or `cleanup` Homebrew cask dependencies]' \ '--check[Check that all dependencies in the Brewfile are installed before running `exec`, `sh`, or `env`]' \ - '--cleanup[`install` performs cleanup operation, same as running `cleanup --force`. This is enabled by default if `$HOMEBREW_BUNDLE_INSTALL_CLEANUP` is set and `--global` is passed]' \ + '--cleanup[`install` performs cleanup operation, same as running `cleanup --force`. Enabled by default if `$HOMEBREW_BUNDLE_INSTALL_CLEANUP` is set and `--global` is passed]' \ '--debug[Display any debugging information]' \ - '--describe[`dump` adds a description comment above each line, unless the dependency does not have a description. This is enabled by default if `$HOMEBREW_BUNDLE_DUMP_DESCRIBE` is set]' \ + '--describe[`dump` adds a description comment above each line, unless the dependency does not have a description. Enabled by default if `$HOMEBREW_BUNDLE_DUMP_DESCRIBE` is set]' \ '--file[Read from or write to the `Brewfile` from this location. Use `--file=-` to pipe to stdin/stdout]' \ '--force[`install` runs with `--force`/`--overwrite`. `dump` overwrites an existing `Brewfile`. `cleanup` actually performs its cleanup operations]' \ '--formula[`list`, `dump` or `cleanup` Homebrew formula dependencies]' \ @@ -662,10 +662,10 @@ _brew_bundle() { '(--upgrade)--install[Run `install` before continuing to other operations e.g. `exec`]' \ '--mas[`list` or `dump` Mac App Store dependencies]' \ '--no-restart[`dump` does not add `restart_service` to formula lines]' \ - '--no-upgrade[`install` does not run `brew upgrade` on outdated dependencies. `check` does not check for outdated dependencies. Note they may still be upgraded by `brew install` if needed. This is enabled by default if `$HOMEBREW_BUNDLE_NO_UPGRADE` is set]' \ - '(--all --vscode)--no-vscode[`dump` without VSCode (and forks/variants) extensions. This is enabled by default if `$HOMEBREW_BUNDLE_DUMP_NO_VSCODE` is set]' \ + '--no-upgrade[`install` does not run `brew upgrade` on outdated dependencies. `check` does not check for outdated dependencies. Note they may still be upgraded by `brew install` if needed. Enabled by default if `$HOMEBREW_BUNDLE_NO_UPGRADE` is set]' \ + '(--all --vscode)--no-vscode[`dump` without VSCode (and forks/variants) extensions. Enabled by default if `$HOMEBREW_BUNDLE_DUMP_NO_VSCODE` is set]' \ '--quiet[Make some output more quiet]' \ - '--services[Temporarily start services while running the `exec` or `sh` command. This is enabled by default if `$HOMEBREW_BUNDLE_SERVICES` is set]' \ + '--services[Temporarily start services while running the `exec` or `sh` command. Enabled by default if `$HOMEBREW_BUNDLE_SERVICES` is set]' \ '--tap[`list`, `dump` or `cleanup` Homebrew tap dependencies]' \ '(--install)--upgrade[`install` runs `brew upgrade` on outdated dependencies, even if `$HOMEBREW_BUNDLE_NO_UPGRADE` is set]' \ '--upgrade-formulae[`install` runs `brew upgrade` on any of these comma-separated formulae, even if `$HOMEBREW_BUNDLE_NO_UPGRADE` is set]' \ @@ -874,8 +874,8 @@ _brew_determine_test_runners() { _arguments \ '(--dependents)--all-supported[Instead of selecting runners based on the chosen formula, return all supported runners]' \ '--debug[Display any debugging information]' \ - '(--all-supported)--dependents[Determine runners for testing dependents. Requires `--eval-all` or `HOMEBREW_EVAL_ALL`]' \ - '--eval-all[Evaluate all available formulae, whether installed or not, to determine testing dependents]' \ + '(--all-supported)--dependents[Determine runners for testing dependents. Requires `--eval-all` or `$HOMEBREW_EVAL_ALL` to be set]' \ + '--eval-all[Evaluate all available formulae, whether installed or not, to determine testing dependents. Enabled by default if `$HOMEBREW_EVAL_ALL` is set]' \ '--help[Show this message]' \ '--quiet[Make some output more quiet]' \ '--verbose[Make some output more verbose]' @@ -1008,9 +1008,9 @@ _brew_fetch() { '--force[Remove a previously cached version and re-fetch]' \ '(--build-from-source --build-bottle --bottle-tag --cask)--force-bottle[Download a bottle if it exists for the current or newest version of macOS, even if it would not be used during installation]' \ '--help[Show this message]' \ - '--no-quarantine[Disable/enable quarantining of downloads (default: enabled)]' \ + '--no-quarantine[Disable/enable quarantining of downloads (default: enabled). Enabled by default if `$HOMEBREW_CASK_OPTS_QUARANTINE` is set]' \ '(--bottle-tag)--os[Download for the given operating system. (Pass `all` to download for all operating systems.)]' \ - '--quarantine[Disable/enable quarantining of downloads (default: enabled)]' \ + '--quarantine[Disable/enable quarantining of downloads (default: enabled). Enabled by default if `$HOMEBREW_CASK_OPTS_QUARANTINE` is set]' \ '--quiet[Make some output more quiet]' \ '--retry[Retry if downloading fails or re-download if the checksum of a previously cached version no longer matches. Tries at most 5 times with exponential backoff]' \ '--verbose[Do a verbose VCS checkout, if the URL represents a VCS. This is useful for seeing if an existing VCS cache has been updated]' \ @@ -1196,9 +1196,9 @@ _brew_instal() { '(--formula --force)--adopt[Adopt existing artifacts in the destination that are identical to those being installed. Cannot be combined with `--force`]' \ '(--formula)--appdir[Target location for Applications (default: `/Applications`)]' \ '(--cask)--as-dependency[Install but mark as installed as a dependency and not installed on request]' \ - '--ask[Ask for confirmation before downloading and installing formulae. Print bottles and dependencies download size and install size]' \ + '--ask[Ask for confirmation before downloading and installing formulae. Print download and install sizes of bottles and dependencies. Enabled by default if `$HOMEBREW_ASK` is set]' \ '(--formula)--audio-unit-plugindir[Target location for Audio Unit Plugins (default: `~/Library/Audio/Plug-Ins/Components`)]' \ - '(--formula)--binaries[Disable/enable linking of helper executables (default: enabled)]' \ + '(--formula)--binaries[Disable/enable linking of helper executables (default: enabled). Enabled by default if `$HOMEBREW_CASK_OPTS_BINARIES` is set]' \ '(--cask)--bottle-arch[Optimise bottles for the specified architecture rather than the oldest architecture supported by the version of macOS the bottles are built on]' \ '(--cask --build-from-source --force-bottle)--build-bottle[Prepare the formula for eventual bottling during installation, skipping any post-install steps]' \ '(--cask --build-bottle --force-bottle)--build-from-source[Compile formula from source even if a bottle is provided. Dependencies will still be installed from bottles if they are available]' \ @@ -1207,7 +1207,7 @@ _brew_instal() { '--debug[If brewing fails, open an interactive debugging session with access to IRB or a shell inside the temporary build directory]' \ '(--cask)--debug-symbols[Generate debug symbols on build. Source will be retained in a cache directory]' \ '(--formula)--dictionarydir[Target location for Dictionaries (default: `~/Library/Dictionaries`)]' \ - '--display-times[Print install times for each package at the end of the run]' \ + '--display-times[Print install times for each package at the end of the run. Enabled by default if `$HOMEBREW_DISPLAY_INSTALL_TIMES` is set]' \ '--dry-run[Show what would be installed, but do not actually install anything]' \ '(--cask)--fetch-HEAD[Fetch the upstream repository to detect if the HEAD installation of the formula is outdated. Otherwise, the repository'\''s HEAD will only be checked for updates when a new stable or development version has been released]' \ '(--formula)--fontdir[Target location for Fonts (default: `~/Library/Fonts`)]' \ @@ -1224,15 +1224,15 @@ _brew_instal() { '(--formula)--keyboard-layoutdir[Target location for Keyboard Layouts (default: `/Library/Keyboard Layouts`)]' \ '(--formula)--language[Comma-separated list of language codes to prefer for cask installation. The first matching language is used, otherwise it reverts to the cask'\''s default language. The default value is the language of your system]' \ '(--formula)--mdimporterdir[Target location for Spotlight Plugins (default: `~/Library/Spotlight`)]' \ - '--no-binaries[Disable/enable linking of helper executables (default: enabled)]' \ - '--no-quarantine[Disable/enable quarantining of downloads (default: enabled)]' \ + '--no-binaries[Disable/enable linking of helper executables (default: enabled). Enabled by default if `$HOMEBREW_CASK_OPTS_BINARIES` is set]' \ + '--no-quarantine[Disable/enable quarantining of downloads (default: enabled). Enabled by default if `$HOMEBREW_CASK_OPTS_QUARANTINE` is set]' \ '(--cask --ignore-dependencies)--only-dependencies[Install the dependencies with specified options but do not install the formula itself]' \ '(--cask)--overwrite[Delete files that already exist in the prefix while linking]' \ '(--formula)--prefpanedir[Target location for Preference Panes (default: `~/Library/PreferencePanes`)]' \ '(--formula)--qlplugindir[Target location for Quick Look Plugins (default: `~/Library/QuickLook`)]' \ - '(--formula)--quarantine[Disable/enable quarantining of downloads (default: enabled)]' \ + '(--formula)--quarantine[Disable/enable quarantining of downloads (default: enabled). Enabled by default if `$HOMEBREW_CASK_OPTS_QUARANTINE` is set]' \ '--quiet[Make some output more quiet]' \ - '(--formula)--require-sha[Require all casks to have a checksum]' \ + '(--formula)--require-sha[Require all casks to have a checksum. Enabled by default if `$HOMEBREW_CASK_OPTS_REQUIRE_SHA` is set]' \ '(--formula)--screen-saverdir[Target location for Screen Savers (default: `~/Library/Screen Savers`)]' \ '(--formula)--servicedir[Target location for Services (default: `~/Library/Services`)]' \ '(--formula)--skip-cask-deps[Skip installing cask dependencies]' \ @@ -1257,9 +1257,9 @@ _brew_install() { '(--formula --force)--adopt[Adopt existing artifacts in the destination that are identical to those being installed. Cannot be combined with `--force`]' \ '(--formula)--appdir[Target location for Applications (default: `/Applications`)]' \ '(--cask)--as-dependency[Install but mark as installed as a dependency and not installed on request]' \ - '--ask[Ask for confirmation before downloading and installing formulae. Print bottles and dependencies download size and install size]' \ + '--ask[Ask for confirmation before downloading and installing formulae. Print download and install sizes of bottles and dependencies. Enabled by default if `$HOMEBREW_ASK` is set]' \ '(--formula)--audio-unit-plugindir[Target location for Audio Unit Plugins (default: `~/Library/Audio/Plug-Ins/Components`)]' \ - '(--formula)--binaries[Disable/enable linking of helper executables (default: enabled)]' \ + '(--formula)--binaries[Disable/enable linking of helper executables (default: enabled). Enabled by default if `$HOMEBREW_CASK_OPTS_BINARIES` is set]' \ '(--cask)--bottle-arch[Optimise bottles for the specified architecture rather than the oldest architecture supported by the version of macOS the bottles are built on]' \ '(--cask --build-from-source --force-bottle)--build-bottle[Prepare the formula for eventual bottling during installation, skipping any post-install steps]' \ '(--cask --build-bottle --force-bottle)--build-from-source[Compile formula from source even if a bottle is provided. Dependencies will still be installed from bottles if they are available]' \ @@ -1268,7 +1268,7 @@ _brew_install() { '--debug[If brewing fails, open an interactive debugging session with access to IRB or a shell inside the temporary build directory]' \ '(--cask)--debug-symbols[Generate debug symbols on build. Source will be retained in a cache directory]' \ '(--formula)--dictionarydir[Target location for Dictionaries (default: `~/Library/Dictionaries`)]' \ - '--display-times[Print install times for each package at the end of the run]' \ + '--display-times[Print install times for each package at the end of the run. Enabled by default if `$HOMEBREW_DISPLAY_INSTALL_TIMES` is set]' \ '--dry-run[Show what would be installed, but do not actually install anything]' \ '(--cask)--fetch-HEAD[Fetch the upstream repository to detect if the HEAD installation of the formula is outdated. Otherwise, the repository'\''s HEAD will only be checked for updates when a new stable or development version has been released]' \ '(--formula)--fontdir[Target location for Fonts (default: `~/Library/Fonts`)]' \ @@ -1285,15 +1285,15 @@ _brew_install() { '(--formula)--keyboard-layoutdir[Target location for Keyboard Layouts (default: `/Library/Keyboard Layouts`)]' \ '(--formula)--language[Comma-separated list of language codes to prefer for cask installation. The first matching language is used, otherwise it reverts to the cask'\''s default language. The default value is the language of your system]' \ '(--formula)--mdimporterdir[Target location for Spotlight Plugins (default: `~/Library/Spotlight`)]' \ - '--no-binaries[Disable/enable linking of helper executables (default: enabled)]' \ - '--no-quarantine[Disable/enable quarantining of downloads (default: enabled)]' \ + '--no-binaries[Disable/enable linking of helper executables (default: enabled). Enabled by default if `$HOMEBREW_CASK_OPTS_BINARIES` is set]' \ + '--no-quarantine[Disable/enable quarantining of downloads (default: enabled). Enabled by default if `$HOMEBREW_CASK_OPTS_QUARANTINE` is set]' \ '(--cask --ignore-dependencies)--only-dependencies[Install the dependencies with specified options but do not install the formula itself]' \ '(--cask)--overwrite[Delete files that already exist in the prefix while linking]' \ '(--formula)--prefpanedir[Target location for Preference Panes (default: `~/Library/PreferencePanes`)]' \ '(--formula)--qlplugindir[Target location for Quick Look Plugins (default: `~/Library/QuickLook`)]' \ - '(--formula)--quarantine[Disable/enable quarantining of downloads (default: enabled)]' \ + '(--formula)--quarantine[Disable/enable quarantining of downloads (default: enabled). Enabled by default if `$HOMEBREW_CASK_OPTS_QUARANTINE` is set]' \ '--quiet[Make some output more quiet]' \ - '(--formula)--require-sha[Require all casks to have a checksum]' \ + '(--formula)--require-sha[Require all casks to have a checksum. Enabled by default if `$HOMEBREW_CASK_OPTS_REQUIRE_SHA` is set]' \ '(--formula)--screen-saverdir[Target location for Screen Savers (default: `~/Library/Screen Savers`)]' \ '(--formula)--servicedir[Target location for Services (default: `~/Library/Services`)]' \ '(--formula)--skip-cask-deps[Skip installing cask dependencies]' \ @@ -1328,7 +1328,7 @@ _brew_irb() { '--debug[Display any debugging information]' \ '--examples[Show several examples]' \ '--help[Show this message]' \ - '--pry[Use Pry instead of IRB. Implied if `HOMEBREW_PRY` is set]' \ + '--pry[Use Pry instead of IRB. Enabled by default if `$HOMEBREW_PRY` is set]' \ '--quiet[Make some output more quiet]' \ '--verbose[Make some output more verbose]' } @@ -1386,7 +1386,7 @@ _brew_link() { # brew linkage _brew_linkage() { _arguments \ - '--cached[Print the cached linkage values stored in `HOMEBREW_CACHE`, set by a previous `brew linkage` run]' \ + '--cached[Print the cached linkage values stored in `$HOMEBREW_CACHE`, set by a previous `brew linkage` run]' \ '--debug[Display any debugging information]' \ '--help[Show this message]' \ '--quiet[Make some output more quiet]' \ @@ -1569,7 +1569,7 @@ _brew_outdated() { _arguments \ '--debug[Display any debugging information]' \ '--fetch-HEAD[Fetch the upstream repository to detect if the HEAD installation of the formula is outdated. Otherwise, the repository'\''s HEAD will only be checked for updates when a new stable or development version has been released]' \ - '--greedy[Also include outdated casks with `auto_updates true` or `version :latest`]' \ + '--greedy[Also include outdated casks with `auto_updates true` or `version :latest`. Enabled by default if `$HOMEBREW_UPGRADE_GREEDY` is set]' \ '--greedy-auto-updates[Also include outdated casks including those with `auto_updates true`]' \ '--greedy-latest[Also include outdated casks including those with `version :latest`]' \ '--help[Show this message]' \ @@ -1747,15 +1747,15 @@ _brew_reinstall() { _arguments \ '(--formula)--adopt[Adopt existing artifacts in the destination that are identical to those being installed. Cannot be combined with `--force`]' \ '(--formula)--appdir[Target location for Applications (default: `/Applications`)]' \ - '--ask[Ask for confirmation before downloading and upgrading formulae. Print bottles and dependencies download size, install and net install size]' \ + '--ask[Ask for confirmation before downloading and upgrading formulae. Print download, install and net install sizes of bottles and dependencies. Enabled by default if `$HOMEBREW_ASK` is set]' \ '(--formula)--audio-unit-plugindir[Target location for Audio Unit Plugins (default: `~/Library/Audio/Plug-Ins/Components`)]' \ - '(--formula)--binaries[Disable/enable linking of helper executables (default: enabled)]' \ + '(--formula)--binaries[Disable/enable linking of helper executables (default: enabled). Enabled by default if `$HOMEBREW_CASK_OPTS_BINARIES` is set]' \ '(--cask --force-bottle)--build-from-source[Compile formula from source even if a bottle is available]' \ '(--formula)--colorpickerdir[Target location for Color Pickers (default: `~/Library/ColorPickers`)]' \ '--debug[If brewing fails, open an interactive debugging session with access to IRB or a shell inside the temporary build directory]' \ '(--cask)--debug-symbols[Generate debug symbols on build. Source will be retained in a cache directory]' \ '(--formula)--dictionarydir[Target location for Dictionaries (default: `~/Library/Dictionaries`)]' \ - '--display-times[Print install times for each package at the end of the run]' \ + '--display-times[Print install times for each package at the end of the run. Enabled by default if `$HOMEBREW_DISPLAY_INSTALL_TIMES` is set]' \ '(--formula)--fontdir[Target location for Fonts (default: `~/Library/Fonts`)]' \ '--force[Install without checking for previously installed keg-only or non-migrated versions]' \ '(--cask --build-from-source)--force-bottle[Install from a bottle if it exists for the current or newest version of macOS, even if it would not normally be used for installation]' \ @@ -1768,13 +1768,13 @@ _brew_reinstall() { '(--formula)--keyboard-layoutdir[Target location for Keyboard Layouts (default: `/Library/Keyboard Layouts`)]' \ '(--formula)--language[Comma-separated list of language codes to prefer for cask installation. The first matching language is used, otherwise it reverts to the cask'\''s default language. The default value is the language of your system]' \ '(--formula)--mdimporterdir[Target location for Spotlight Plugins (default: `~/Library/Spotlight`)]' \ - '--no-binaries[Disable/enable linking of helper executables (default: enabled)]' \ - '--no-quarantine[Disable/enable quarantining of downloads (default: enabled)]' \ + '--no-binaries[Disable/enable linking of helper executables (default: enabled). Enabled by default if `$HOMEBREW_CASK_OPTS_BINARIES` is set]' \ + '--no-quarantine[Disable/enable quarantining of downloads (default: enabled). Enabled by default if `$HOMEBREW_CASK_OPTS_QUARANTINE` is set]' \ '(--formula)--prefpanedir[Target location for Preference Panes (default: `~/Library/PreferencePanes`)]' \ '(--formula)--qlplugindir[Target location for Quick Look Plugins (default: `~/Library/QuickLook`)]' \ - '(--formula)--quarantine[Disable/enable quarantining of downloads (default: enabled)]' \ + '(--formula)--quarantine[Disable/enable quarantining of downloads (default: enabled). Enabled by default if `$HOMEBREW_CASK_OPTS_QUARANTINE` is set]' \ '--quiet[Make some output more quiet]' \ - '(--formula)--require-sha[Require all casks to have a checksum]' \ + '(--formula)--require-sha[Require all casks to have a checksum. Enabled by default if `$HOMEBREW_CASK_OPTS_REQUIRE_SHA` is set]' \ '(--formula)--screen-saverdir[Target location for Screen Savers (default: `~/Library/Screen Savers`)]' \ '(--formula)--servicedir[Target location for Services (default: `~/Library/Services`)]' \ '(--formula)--skip-cask-deps[Skip installing cask dependencies]' \ @@ -1928,7 +1928,7 @@ _brew_sh() { _arguments \ '--cmd[Execute commands in a non-interactive shell]' \ '--debug[Display any debugging information]' \ - '--env[Use the standard `PATH` instead of superenv'\''s when `std` is passed]' \ + '--env[Use the standard `$PATH` instead of superenv'\''s when `std` is passed]' \ '--help[Show this message]' \ '--quiet[Make some output more quiet]' \ '--verbose[Make some output more verbose]' \ @@ -2112,7 +2112,7 @@ _brew_unbottled() { _arguments \ '--debug[Display any debugging information]' \ '(--total --lost)--dependents[Skip getting analytics data and sort by number of dependents instead]' \ - '--eval-all[Evaluate all available formulae and casks, whether installed or not, to check them. Implied if `HOMEBREW_EVAL_ALL` is set]' \ + '--eval-all[Evaluate all available formulae and casks, whether installed or not, to check them. Implied if `$HOMEBREW_EVAL_ALL` is set]' \ '--help[Show this message]' \ '(--dependents --total)--lost[Print the `homebrew/core` commits where bottles were lost in the last week]' \ '--quiet[Make some output more quiet]' \ @@ -2318,7 +2318,7 @@ _brew_update_test() { '--help[Show this message]' \ '--keep-tmp[Retain the temporary directory containing the new repository clone]' \ '--quiet[Make some output more quiet]' \ - '--to-tag[Set `HOMEBREW_UPDATE_TO_TAG` to test updating between tags]' \ + '--to-tag[Set `$HOMEBREW_UPDATE_TO_TAG` to test updating between tags]' \ '--verbose[Make some output more verbose]' } @@ -2326,15 +2326,15 @@ _brew_update_test() { _brew_upgrade() { _arguments \ '(--formula)--appdir[Target location for Applications (default: `/Applications`)]' \ - '--ask[Ask for confirmation before downloading and upgrading formulae. Print bottles and dependencies download size, install and net install size]' \ + '--ask[Ask for confirmation before downloading and upgrading formulae. Print download, install and net install sizes of bottles and dependencies. Enabled by default if `$HOMEBREW_ASK` is set]' \ '(--formula)--audio-unit-plugindir[Target location for Audio Unit Plugins (default: `~/Library/Audio/Plug-Ins/Components`)]' \ - '(--formula)--binaries[Disable/enable linking of helper executables (default: enabled)]' \ + '(--formula)--binaries[Disable/enable linking of helper executables (default: enabled). Enabled by default if `$HOMEBREW_CASK_OPTS_BINARIES` is set]' \ '(--cask --force-bottle)--build-from-source[Compile formula from source even if a bottle is available]' \ '(--formula)--colorpickerdir[Target location for Color Pickers (default: `~/Library/ColorPickers`)]' \ '--debug[If brewing fails, open an interactive debugging session with access to IRB or a shell inside the temporary build directory]' \ '(--cask)--debug-symbols[Generate debug symbols on build. Source will be retained in a cache directory]' \ '(--formula)--dictionarydir[Target location for Dictionaries (default: `~/Library/Dictionaries`)]' \ - '--display-times[Print install times for each package at the end of the run]' \ + '--display-times[Print install times for each package at the end of the run. Enabled by default if `$HOMEBREW_DISPLAY_INSTALL_TIMES` is set]' \ '--dry-run[Show what would be upgraded, but do not actually upgrade anything]' \ '(--cask)--fetch-HEAD[Fetch the upstream repository to detect if the HEAD installation of the formula is outdated. Otherwise, the repository'\''s HEAD will only be checked for updates when a new stable or development version has been released]' \ '(--formula)--fontdir[Target location for Fonts (default: `~/Library/Fonts`)]' \ @@ -2351,14 +2351,14 @@ _brew_upgrade() { '(--formula)--keyboard-layoutdir[Target location for Keyboard Layouts (default: `/Library/Keyboard Layouts`)]' \ '(--formula)--language[Comma-separated list of language codes to prefer for cask installation. The first matching language is used, otherwise it reverts to the cask'\''s default language. The default value is the language of your system]' \ '(--formula)--mdimporterdir[Target location for Spotlight Plugins (default: `~/Library/Spotlight`)]' \ - '--no-binaries[Disable/enable linking of helper executables (default: enabled)]' \ - '--no-quarantine[Disable/enable quarantining of downloads (default: enabled)]' \ + '--no-binaries[Disable/enable linking of helper executables (default: enabled). Enabled by default if `$HOMEBREW_CASK_OPTS_BINARIES` is set]' \ + '--no-quarantine[Disable/enable quarantining of downloads (default: enabled). Enabled by default if `$HOMEBREW_CASK_OPTS_QUARANTINE` is set]' \ '(--cask)--overwrite[Delete files that already exist in the prefix while linking]' \ '(--formula)--prefpanedir[Target location for Preference Panes (default: `~/Library/PreferencePanes`)]' \ '(--formula)--qlplugindir[Target location for Quick Look Plugins (default: `~/Library/QuickLook`)]' \ - '(--formula)--quarantine[Disable/enable quarantining of downloads (default: enabled)]' \ + '(--formula)--quarantine[Disable/enable quarantining of downloads (default: enabled). Enabled by default if `$HOMEBREW_CASK_OPTS_QUARANTINE` is set]' \ '--quiet[Make some output more quiet]' \ - '(--formula)--require-sha[Require all casks to have a checksum]' \ + '(--formula)--require-sha[Require all casks to have a checksum. Enabled by default if `$HOMEBREW_CASK_OPTS_REQUIRE_SHA` is set]' \ '(--formula)--screen-saverdir[Target location for Screen Savers (default: `~/Library/Screen Savers`)]' \ '(--formula)--servicedir[Target location for Services (default: `~/Library/Services`)]' \ '(--formula)--skip-cask-deps[Skip installing cask dependencies]' \ diff --git a/docs/Manpage.md b/docs/Manpage.md index 861f6d0e92..d5238f107c 100644 --- a/docs/Manpage.md +++ b/docs/Manpage.md @@ -239,8 +239,8 @@ flags which will help with finding keg-only dependencies like `openssl`, : `install` does not run `brew upgrade` on outdated dependencies. `check` does not check for outdated dependencies. Note they may still be upgraded by `brew - install` if needed. This is enabled by default if - `$HOMEBREW_BUNDLE_NO_UPGRADE` is set. + install` if needed. Enabled by default if `$HOMEBREW_BUNDLE_NO_UPGRADE` is + set. `--upgrade` @@ -258,8 +258,8 @@ flags which will help with finding keg-only dependencies like `openssl`, `--services` -: Temporarily start services while running the `exec` or `sh` command. This is - enabled by default if `$HOMEBREW_BUNDLE_SERVICES` is set. +: Temporarily start services while running the `exec` or `sh` command. Enabled + by default if `$HOMEBREW_BUNDLE_SERVICES` is set. `-f`, `--force` @@ -268,9 +268,9 @@ flags which will help with finding keg-only dependencies like `openssl`, `--cleanup` -: `install` performs cleanup operation, same as running `cleanup --force`. This - is enabled by default if `$HOMEBREW_BUNDLE_INSTALL_CLEANUP` is set and - `--global` is passed. +: `install` performs cleanup operation, same as running `cleanup --force`. + Enabled by default if `$HOMEBREW_BUNDLE_INSTALL_CLEANUP` is set and `--global` + is passed. `--all` @@ -302,14 +302,14 @@ flags which will help with finding keg-only dependencies like `openssl`, `--no-vscode` -: `dump` without VSCode (and forks/variants) extensions. This is enabled by - default if `$HOMEBREW_BUNDLE_DUMP_NO_VSCODE` is set. +: `dump` without VSCode (and forks/variants) extensions. Enabled by default if + `$HOMEBREW_BUNDLE_DUMP_NO_VSCODE` is set. `--describe` : `dump` adds a description comment above each line, unless the dependency does - not have a description. This is enabled by default if - `$HOMEBREW_BUNDLE_DUMP_DESCRIBE` is set. + not have a description. Enabled by default if `$HOMEBREW_BUNDLE_DUMP_DESCRIBE` + is set. `--no-restart` @@ -627,7 +627,8 @@ binaries for *`cask`*s. For files, also print SHA-256 checksums. `--[no-]quarantine` -: Disable/enable quarantining of downloads (default: enabled). +: Disable/enable quarantining of downloads (default: enabled). Enabled by + default if `$HOMEBREW_CASK_OPTS_QUARANTINE` is set. `--formula` @@ -763,7 +764,8 @@ upgrade *`formula`* if it is already installed but outdated. `--display-times` -: Print install times for each package at the end of the run. +: Print install times for each package at the end of the run. Enabled by default + if `$HOMEBREW_DISPLAY_INSTALL_TIMES` is set. `-f`, `--force` @@ -781,8 +783,9 @@ upgrade *`formula`* if it is already installed but outdated. `--ask` -: Ask for confirmation before downloading and installing formulae. Print bottles - and dependencies download size and install size. +: Ask for confirmation before downloading and installing formulae. Print + download and install sizes of bottles and dependencies. Enabled by default if + `$HOMEBREW_ASK` is set. `--formula` @@ -884,15 +887,18 @@ upgrade *`formula`* if it is already installed but outdated. `--[no-]binaries` -: Disable/enable linking of helper executables (default: enabled). +: Disable/enable linking of helper executables (default: enabled). Enabled by + default if `$HOMEBREW_CASK_OPTS_BINARIES` is set. `--require-sha` -: Require all casks to have a checksum. +: Require all casks to have a checksum. Enabled by default if + `$HOMEBREW_CASK_OPTS_REQUIRE_SHA` is set. `--[no-]quarantine` -: Disable/enable quarantining of downloads (default: enabled). +: Disable/enable quarantining of downloads (default: enabled). Enabled by + default if `$HOMEBREW_CASK_OPTS_QUARANTINE` is set. `--adopt` @@ -1145,6 +1151,7 @@ otherwise. `-g`, `--greedy` : Also include outdated casks with `auto_updates true` or `version :latest`. + Enabled by default if `$HOMEBREW_UPGRADE_GREEDY` is set. `--greedy-latest` @@ -1234,7 +1241,8 @@ for the reinstalled formulae or, every 30 days, for all formulae. `--display-times` -: Print install times for each package at the end of the run. +: Print install times for each package at the end of the run. Enabled by default + if `$HOMEBREW_DISPLAY_INSTALL_TIMES` is set. `-f`, `--force` @@ -1247,8 +1255,9 @@ for the reinstalled formulae or, every 30 days, for all formulae. `--ask` -: Ask for confirmation before downloading and upgrading formulae. Print bottles - and dependencies download size, install and net install size. +: Ask for confirmation before downloading and upgrading formulae. Print + download, install and net install sizes of bottles and dependencies. Enabled + by default if `$HOMEBREW_ASK` is set. `--formula` @@ -1287,15 +1296,18 @@ for the reinstalled formulae or, every 30 days, for all formulae. `--[no-]binaries` -: Disable/enable linking of helper executables (default: enabled). +: Disable/enable linking of helper executables (default: enabled). Enabled by + default if `$HOMEBREW_CASK_OPTS_BINARIES` is set. `--require-sha` -: Require all casks to have a checksum. +: Require all casks to have a checksum. Enabled by default if + `$HOMEBREW_CASK_OPTS_REQUIRE_SHA` is set. `--[no-]quarantine` -: Disable/enable quarantining of downloads (default: enabled). +: Disable/enable quarantining of downloads (default: enabled). Enabled by + default if `$HOMEBREW_CASK_OPTS_QUARANTINE` is set. `--adopt` @@ -1464,12 +1476,12 @@ run Bundler if necessary for that command. Valid shells: bash\|csh\|fish\|pwsh\|sh\|tcsh\|zsh Print export statements. When run in a shell, this installation of Homebrew will -be added to your `PATH`, `MANPATH`, and `INFOPATH`. +be added to your `$PATH`, `$MANPATH`, and `$INFOPATH`. The variables `$HOMEBREW_PREFIX`, `$HOMEBREW_CELLAR` and `$HOMEBREW_REPOSITORY` are also exported to avoid querying them multiple times. To help guarantee idempotence, this command produces no output when Homebrew's `bin` and `sbin` -directories are first and second respectively in your `PATH`. Consider adding +directories are first and second respectively in your `$PATH`. Consider adding evaluation of this command's output to your dotfiles (e.g. `~/.bash_profile` or ~/.zprofile` on macOS and ~/.bashrc` or ~/.zshrc` on Linux) with: `eval "$(brew shellenv)"\` @@ -1663,7 +1675,8 @@ for the upgraded formulae or, every 30 days, for all formulae. `--display-times` -: Print install times for each package at the end of the run. +: Print install times for each package at the end of the run. Enabled by default + if `$HOMEBREW_DISPLAY_INSTALL_TIMES` is set. `-f`, `--force` @@ -1681,8 +1694,9 @@ for the upgraded formulae or, every 30 days, for all formulae. `--ask` -: Ask for confirmation before downloading and upgrading formulae. Print bottles - and dependencies download size, install and net install size. +: Ask for confirmation before downloading and upgrading formulae. Print + download, install and net install sizes of bottles and dependencies. Enabled + by default if `$HOMEBREW_ASK` is set. `--formula` @@ -1745,15 +1759,18 @@ for the upgraded formulae or, every 30 days, for all formulae. `--[no-]binaries` -: Disable/enable linking of helper executables (default: enabled). +: Disable/enable linking of helper executables (default: enabled). Enabled by + default if `$HOMEBREW_CASK_OPTS_BINARIES` is set. `--require-sha` -: Require all casks to have a checksum. +: Require all casks to have a checksum. Enabled by default if + `$HOMEBREW_CASK_OPTS_REQUIRE_SHA` is set. `--[no-]quarantine` -: Disable/enable quarantining of downloads (default: enabled). +: Disable/enable quarantining of downloads (default: enabled). Enabled by + default if `$HOMEBREW_CASK_OPTS_QUARANTINE` is set. ### `uses` \[*`options`*\] *`formula`* \[...\] @@ -1951,7 +1968,7 @@ checks. Will exit with a non-zero status if any errors are found. `--eval-all` : Evaluate all available formulae and casks, whether installed or not, to audit - them. Implied if `HOMEBREW_EVAL_ALL` is set. + them. Implied if `$HOMEBREW_EVAL_ALL` is set. `--new` @@ -2551,9 +2568,9 @@ Build bottles for these formulae with GitHub Actions. ### `edit` \[*`options`*\] \[*`formula`*\|*`cask`*\|*`tap`* ...\] -Open a *`formula`*, *`cask`* or *`tap`* in the editor set by `EDITOR` or -`HOMEBREW_EDITOR`, or open the Homebrew repository for editing if no argument is -provided. +Open a *`formula`*, *`cask`* or *`tap`* in the editor set by `$EDITOR` or +`$HOMEBREW_EDITOR`, or open the Homebrew repository for editing if no argument +is provided. `--formula` @@ -2715,7 +2732,7 @@ Enter the interactive Homebrew Ruby shell. `--pry` -: Use Pry instead of IRB. Implied if `HOMEBREW_PRY` is set. +: Use Pry instead of IRB. Enabled by default if `$HOMEBREW_PRY` is set. ### `linkage` \[*`options`*\] \[*`installed_formula`* ...\] @@ -2739,14 +2756,14 @@ provided, check all kegs. Raises an error if run on uninstalled formulae. `--cached` -: Print the cached linkage values stored in `HOMEBREW_CACHE`, set by a previous +: Print the cached linkage values stored in `$HOMEBREW_CACHE`, set by a previous `brew linkage` run. ### `livecheck`, `lc` \[*`options`*\] \[*`formula`*\|*`cask`* ...\] Check for newer versions of formulae and/or casks from upstream. If no formula or cask argument is passed, the list of formulae and casks to check is taken -from `HOMEBREW_LIVECHECK_WATCHLIST` or `~/.homebrew/livecheck_watchlist.txt`. +from `$HOMEBREW_LIVECHECK_WATCHLIST` or `~/.homebrew/livecheck_watchlist.txt`. `--full-name` @@ -3068,11 +3085,11 @@ Enter an interactive shell for Homebrew's build environment. Use years-battle-hardened build logic to help your `./configure && make && make install` and even your `gem install` succeed. Especially handy if you run Homebrew in an Xcode-only configuration since it adds tools like `make` to your -`PATH` which build systems would not find otherwise. +`$PATH` which build systems would not find otherwise. `--env` -: Use the standard `PATH` instead of superenv's when `std` is passed. +: Use the standard `$PATH` instead of superenv's when `std` is passed. `-c`, `--cmd` @@ -3263,7 +3280,7 @@ Show the unbottled dependents of formulae. `--eval-all` : Evaluate all available formulae and casks, whether installed or not, to check - them. Implied if `HOMEBREW_EVAL_ALL` is set. + them. Implied if `$HOMEBREW_EVAL_ALL` is set. ### `unpack` \[*`options`*\] *`formula`* \[...\] @@ -3350,7 +3367,7 @@ passed, use `origin/master` as the start commit. `--to-tag` -: Set `HOMEBREW_UPDATE_TO_TAG` to test updating between tags. +: Set `$HOMEBREW_UPDATE_TO_TAG` to test updating between tags. `--keep-tmp` @@ -3738,7 +3755,7 @@ Database update for `brew which-formula`. ## CUSTOM EXTERNAL COMMANDS Homebrew, like `git`(1), supports external commands. These are executable -scripts that reside somewhere in the `PATH`, named `brew-`*`cmdname`* or +scripts that reside somewhere in the `$PATH`, named `brew-`*`cmdname`* or `brew-`*`cmdname`*`.rb`, which can be invoked like `brew` *`cmdname`*. This allows you to create your own commands without modifying Homebrew's internals. @@ -3785,7 +3802,7 @@ files: User-specific environment files take precedence over prefix-specific files and prefix-specific files take precedence over system-wide files (unless -`HOMEBREW_SYSTEM_ENV_TAKES_PRIORITY` is set, see below). +`$HOMEBREW_SYSTEM_ENV_TAKES_PRIORITY` is set, see below). Note that these files do not support shell variable expansion e.g. `$HOME` or command execution e.g. `$(cat file)`. @@ -4333,7 +4350,7 @@ command execution e.g. `$(cat file)`. `HOMEBREW_SUDO_THROUGH_SUDO_USER` -: If set, Homebrew will use the `SUDO_USER` environment variable to define the +: If set, Homebrew will use the `$SUDO_USER` environment variable to define the user to `sudo`(8) through when running `sudo`(8). `HOMEBREW_SVN` diff --git a/manpages/brew.1 b/manpages/brew.1 index 1d84a042df..c2c51dd6a3 100644 --- a/manpages/brew.1 +++ b/manpages/brew.1 @@ -1,5 +1,5 @@ .\" generated by kramdown -.TH "BREW" "1" "May 2025" "Homebrew" +.TH "BREW" "1" "June 2025" "Homebrew" .SH NAME brew \- The Missing Package Manager for macOS (or Linux) .SH "SYNOPSIS" @@ -145,7 +145,7 @@ Read from or write to the \fBBrewfile\fP from \fB$HOMEBREW_BUNDLE_FILE_GLOBAL\fP \fBinstall\fP prints output from commands as they are run\. \fBcheck\fP lists all missing dependencies\. .TP \fB\-\-no\-upgrade\fP -\fBinstall\fP does not run \fBbrew upgrade\fP on outdated dependencies\. \fBcheck\fP does not check for outdated dependencies\. Note they may still be upgraded by \fBbrew install\fP if needed\. This is enabled by default if \fB$HOMEBREW_BUNDLE_NO_UPGRADE\fP is set\. +\fBinstall\fP does not run \fBbrew upgrade\fP on outdated dependencies\. \fBcheck\fP does not check for outdated dependencies\. Note they may still be upgraded by \fBbrew install\fP if needed\. Enabled by default if \fB$HOMEBREW_BUNDLE_NO_UPGRADE\fP is set\. .TP \fB\-\-upgrade\fP \fBinstall\fP runs \fBbrew upgrade\fP on outdated dependencies, even if \fB$HOMEBREW_BUNDLE_NO_UPGRADE\fP is set\. @@ -157,13 +157,13 @@ Read from or write to the \fBBrewfile\fP from \fB$HOMEBREW_BUNDLE_FILE_GLOBAL\fP Run \fBinstall\fP before continuing to other operations e\.g\. \fBexec\fP\&\. .TP \fB\-\-services\fP -Temporarily start services while running the \fBexec\fP or \fBsh\fP command\. This is enabled by default if \fB$HOMEBREW_BUNDLE_SERVICES\fP is set\. +Temporarily start services while running the \fBexec\fP or \fBsh\fP command\. Enabled by default if \fB$HOMEBREW_BUNDLE_SERVICES\fP is set\. .TP \fB\-f\fP, \fB\-\-force\fP \fBinstall\fP runs with \fB\-\-force\fP/\fB\-\-overwrite\fP\&\. \fBdump\fP overwrites an existing \fBBrewfile\fP\&\. \fBcleanup\fP actually performs its cleanup operations\. .TP \fB\-\-cleanup\fP -\fBinstall\fP performs cleanup operation, same as running \fBcleanup \-\-force\fP\&\. This is enabled by default if \fB$HOMEBREW_BUNDLE_INSTALL_CLEANUP\fP is set and \fB\-\-global\fP is passed\. +\fBinstall\fP performs cleanup operation, same as running \fBcleanup \-\-force\fP\&\. Enabled by default if \fB$HOMEBREW_BUNDLE_INSTALL_CLEANUP\fP is set and \fB\-\-global\fP is passed\. .TP \fB\-\-all\fP \fBlist\fP all dependencies\. @@ -187,10 +187,10 @@ Temporarily start services while running the \fBexec\fP or \fBsh\fP command\. Th \fBlist\fP, \fBdump\fP or \fBcleanup\fP VSCode (and forks/variants) extensions\. .TP \fB\-\-no\-vscode\fP -\fBdump\fP without VSCode (and forks/variants) extensions\. This is enabled by default if \fB$HOMEBREW_BUNDLE_DUMP_NO_VSCODE\fP is set\. +\fBdump\fP without VSCode (and forks/variants) extensions\. Enabled by default if \fB$HOMEBREW_BUNDLE_DUMP_NO_VSCODE\fP is set\. .TP \fB\-\-describe\fP -\fBdump\fP adds a description comment above each line, unless the dependency does not have a description\. This is enabled by default if \fB$HOMEBREW_BUNDLE_DUMP_DESCRIBE\fP is set\. +\fBdump\fP adds a description comment above each line, unless the dependency does not have a description\. Enabled by default if \fB$HOMEBREW_BUNDLE_DUMP_DESCRIBE\fP is set\. .TP \fB\-\-no\-restart\fP \fBdump\fP does not add \fBrestart_service\fP to formula lines\. @@ -393,7 +393,7 @@ Download source packages (for eventual bottling) rather than a bottle\. Download a bottle if it exists for the current or newest version of macOS, even if it would not be used during installation\. .TP \fB\-\-[no\-]quarantine\fP -Disable/enable quarantining of downloads (default: enabled)\. +Disable/enable quarantining of downloads (default: enabled)\. Enabled by default if \fB$HOMEBREW_CASK_OPTS_QUARANTINE\fP is set\. .TP \fB\-\-formula\fP Treat all named arguments as formulae\. @@ -476,7 +476,7 @@ Unless \fB$HOMEBREW_NO_INSTALL_UPGRADE\fP is set, \fBbrew install\fP \fIformula\ If brewing fails, open an interactive debugging session with access to IRB or a shell inside the temporary build directory\. .TP \fB\-\-display\-times\fP -Print install times for each package at the end of the run\. +Print install times for each package at the end of the run\. Enabled by default if \fB$HOMEBREW_DISPLAY_INSTALL_TIMES\fP is set\. .TP \fB\-f\fP, \fB\-\-force\fP Install formulae without checking for previously installed keg\-only or non\-migrated versions\. When installing casks, overwrite existing files (binaries and symlinks are excluded, unless originally from the same cask)\. @@ -488,7 +488,7 @@ Print the verification and post\-install steps\. Show what would be installed, but do not actually install anything\. .TP \fB\-\-ask\fP -Ask for confirmation before downloading and installing formulae\. Print bottles and dependencies download size and install size\. +Ask for confirmation before downloading and installing formulae\. Print download and install sizes of bottles and dependencies\. Enabled by default if \fB$HOMEBREW_ASK\fP is set\. .TP \fB\-\-formula\fP Treat all named arguments as formulae\. @@ -551,13 +551,13 @@ Delete files that already exist in the prefix while linking\. Treat all named arguments as casks\. .TP \fB\-\-[no\-]binaries\fP -Disable/enable linking of helper executables (default: enabled)\. +Disable/enable linking of helper executables (default: enabled)\. Enabled by default if \fB$HOMEBREW_CASK_OPTS_BINARIES\fP is set\. .TP \fB\-\-require\-sha\fP -Require all casks to have a checksum\. +Require all casks to have a checksum\. Enabled by default if \fB$HOMEBREW_CASK_OPTS_REQUIRE_SHA\fP is set\. .TP \fB\-\-[no\-]quarantine\fP -Disable/enable quarantining of downloads (default: enabled)\. +Disable/enable quarantining of downloads (default: enabled)\. Enabled by default if \fB$HOMEBREW_CASK_OPTS_QUARANTINE\fP is set\. .TP \fB\-\-adopt\fP Adopt existing artifacts in the destination that are identical to those being installed\. Cannot be combined with \fB\-\-force\fP\&\. @@ -715,7 +715,7 @@ Print output in JSON format\. There are two versions: \fBv1\fP and \fBv2\fP\&\. Fetch the upstream repository to detect if the HEAD installation of the formula is outdated\. Otherwise, the repository\[u2019]s HEAD will only be checked for updates when a new stable or development version has been released\. .TP \fB\-g\fP, \fB\-\-greedy\fP -Also include outdated casks with \fBauto_updates true\fP or \fBversion :latest\fP\&\. +Also include outdated casks with \fBauto_updates true\fP or \fBversion :latest\fP\&\. Enabled by default if \fB$HOMEBREW_UPGRADE_GREEDY\fP is set\. .TP \fB\-\-greedy\-latest\fP Also include outdated casks including those with \fBversion :latest\fP\&\. @@ -767,7 +767,7 @@ Unless \fB$HOMEBREW_NO_INSTALL_CLEANUP\fP is set, \fBbrew cleanup\fP will then b If brewing fails, open an interactive debugging session with access to IRB or a shell inside the temporary build directory\. .TP \fB\-\-display\-times\fP -Print install times for each package at the end of the run\. +Print install times for each package at the end of the run\. Enabled by default if \fB$HOMEBREW_DISPLAY_INSTALL_TIMES\fP is set\. .TP \fB\-f\fP, \fB\-\-force\fP Install without checking for previously installed keg\-only or non\-migrated versions\. @@ -776,7 +776,7 @@ Install without checking for previously installed keg\-only or non\-migrated ver Print the verification and post\-install steps\. .TP \fB\-\-ask\fP -Ask for confirmation before downloading and upgrading formulae\. Print bottles and dependencies download size, install and net install size\. +Ask for confirmation before downloading and upgrading formulae\. Print download, install and net install sizes of bottles and dependencies\. Enabled by default if \fB$HOMEBREW_ASK\fP is set\. .TP \fB\-\-formula\fP Treat all named arguments as formulae\. @@ -803,13 +803,13 @@ Create a Git repository, useful for creating patches to the software\. Treat all named arguments as casks\. .TP \fB\-\-[no\-]binaries\fP -Disable/enable linking of helper executables (default: enabled)\. +Disable/enable linking of helper executables (default: enabled)\. Enabled by default if \fB$HOMEBREW_CASK_OPTS_BINARIES\fP is set\. .TP \fB\-\-require\-sha\fP -Require all casks to have a checksum\. +Require all casks to have a checksum\. Enabled by default if \fB$HOMEBREW_CASK_OPTS_REQUIRE_SHA\fP is set\. .TP \fB\-\-[no\-]quarantine\fP -Disable/enable quarantining of downloads (default: enabled)\. +Disable/enable quarantining of downloads (default: enabled)\. Enabled by default if \fB$HOMEBREW_CASK_OPTS_QUARANTINE\fP is set\. .TP \fB\-\-adopt\fP Adopt existing artifacts in the destination that are identical to those being installed\. Cannot be combined with \fB\-\-force\fP\&\. @@ -920,9 +920,9 @@ Installs and configures Homebrew\[u2019]s Ruby\. If \fBcommand\fP is passed, it .SS "\fBshellenv\fP \fR[\fIshell\fP \.\.\.]" Valid shells: bash|csh|fish|pwsh|sh|tcsh|zsh .P -Print export statements\. When run in a shell, this installation of Homebrew will be added to your \fBPATH\fP, \fBMANPATH\fP, and \fBINFOPATH\fP\&\. +Print export statements\. When run in a shell, this installation of Homebrew will be added to your \fB$PATH\fP, \fB$MANPATH\fP, and \fB$INFOPATH\fP\&\. .P -The variables \fB$HOMEBREW_PREFIX\fP, \fB$HOMEBREW_CELLAR\fP and \fB$HOMEBREW_REPOSITORY\fP are also exported to avoid querying them multiple times\. To help guarantee idempotence, this command produces no output when Homebrew\[u2019]s \fBbin\fP and \fBsbin\fP directories are first and second respectively in your \fBPATH\fP\&\. Consider adding evaluation of this command\[u2019]s output to your dotfiles (e\.g\. \fB~/\.bash_profile\fP or ~/\.zprofile\fB on macOS and ~/\.bashrc\fP or ~/\.zshrc\fB on Linux) with: \fPeval \[u201c]$(brew shellenv)\[u201d]` +The variables \fB$HOMEBREW_PREFIX\fP, \fB$HOMEBREW_CELLAR\fP and \fB$HOMEBREW_REPOSITORY\fP are also exported to avoid querying them multiple times\. To help guarantee idempotence, this command produces no output when Homebrew\[u2019]s \fBbin\fP and \fBsbin\fP directories are first and second respectively in your \fB$PATH\fP\&\. Consider adding evaluation of this command\[u2019]s output to your dotfiles (e\.g\. \fB~/\.bash_profile\fP or ~/\.zprofile\fB on macOS and ~/\.bashrc\fP or ~/\.zshrc\fB on Linux) with: \fPeval \[u201c]$(brew shellenv)\[u201d]` .P The shell can be specified explicitly with a supported shell name parameter\. Unknown shells will output POSIX exports\. .SS "\fBtab\fP \fR[\fIoptions\fP] \fIinstalled_formula\fP|\fIinstalled_cask\fP \fR[\.\.\.]" @@ -1034,7 +1034,7 @@ Unless \fB$HOMEBREW_NO_INSTALL_CLEANUP\fP is set, \fBbrew cleanup\fP will then b If brewing fails, open an interactive debugging session with access to IRB or a shell inside the temporary build directory\. .TP \fB\-\-display\-times\fP -Print install times for each package at the end of the run\. +Print install times for each package at the end of the run\. Enabled by default if \fB$HOMEBREW_DISPLAY_INSTALL_TIMES\fP is set\. .TP \fB\-f\fP, \fB\-\-force\fP Install formulae without checking for previously installed keg\-only or non\-migrated versions\. When installing casks, overwrite existing files (binaries and symlinks are excluded, unless originally from the same cask)\. @@ -1046,7 +1046,7 @@ Print the verification and post\-install steps\. Show what would be upgraded, but do not actually upgrade anything\. .TP \fB\-\-ask\fP -Ask for confirmation before downloading and upgrading formulae\. Print bottles and dependencies download size, install and net install size\. +Ask for confirmation before downloading and upgrading formulae\. Print download, install and net install sizes of bottles and dependencies\. Enabled by default if \fB$HOMEBREW_ASK\fP is set\. .TP \fB\-\-formula\fP Treat all named arguments as formulae\. If no named arguments are specified, upgrade only outdated formulae\. @@ -1088,13 +1088,13 @@ Also include casks with \fBversion :latest\fP\&\. Also include casks with \fBauto_updates true\fP\&\. .TP \fB\-\-[no\-]binaries\fP -Disable/enable linking of helper executables (default: enabled)\. +Disable/enable linking of helper executables (default: enabled)\. Enabled by default if \fB$HOMEBREW_CASK_OPTS_BINARIES\fP is set\. .TP \fB\-\-require\-sha\fP -Require all casks to have a checksum\. +Require all casks to have a checksum\. Enabled by default if \fB$HOMEBREW_CASK_OPTS_REQUIRE_SHA\fP is set\. .TP \fB\-\-[no\-]quarantine\fP -Disable/enable quarantining of downloads (default: enabled)\. +Disable/enable quarantining of downloads (default: enabled)\. Enabled by default if \fB$HOMEBREW_CASK_OPTS_QUARANTINE\fP is set\. .SS "\fBuses\fP \fR[\fIoptions\fP] \fIformula\fP \fR[\.\.\.]" Show formulae and casks that specify \fIformula\fP as a dependency; that is, show dependents of \fIformula\fP\&\. When given multiple formula arguments, show the intersection of formulae that use \fIformula\fP\&\. By default, \fBuses\fP shows all formulae and casks that specify \fIformula\fP as a required or recommended dependency for their stable builds\. .P @@ -1223,7 +1223,7 @@ Run additional, slower style checks that require a network connection\. Only check formulae and casks that are currently installed\. .TP \fB\-\-eval\-all\fP -Evaluate all available formulae and casks, whether installed or not, to audit them\. Implied if \fBHOMEBREW_EVAL_ALL\fP is set\. +Evaluate all available formulae and casks, whether installed or not, to audit them\. Implied if \fB$HOMEBREW_EVAL_ALL\fP is set\. .TP \fB\-\-new\fP Run various additional style checks to determine if a new formula or cask is eligible for Homebrew\. This should be used when creating new formulae or casks and implies \fB\-\-strict\fP and \fB\-\-online\fP\&\. @@ -1621,7 +1621,7 @@ Dispatch bottle for Linux x86_64 (using self\-hosted runner)\. \fB\-\-linux\-wheezy\fP Use Debian Wheezy container for building the bottle on Linux\. .SS "\fBedit\fP \fR[\fIoptions\fP] \fR[\fIformula\fP|\fIcask\fP|\fItap\fP \.\.\.]" -Open a \fIformula\fP, \fIcask\fP or \fItap\fP in the editor set by \fBEDITOR\fP or \fBHOMEBREW_EDITOR\fP, or open the Homebrew repository for editing if no argument is provided\. +Open a \fIformula\fP, \fIcask\fP or \fItap\fP in the editor set by \fB$EDITOR\fP or \fB$HOMEBREW_EDITOR\fP, or open the Homebrew repository for editing if no argument is provided\. .TP \fB\-\-formula\fP Treat all named arguments as formulae\. @@ -1729,7 +1729,7 @@ Enter the interactive Homebrew Ruby shell\. Show several examples\. .TP \fB\-\-pry\fP -Use Pry instead of IRB\. Implied if \fBHOMEBREW_PRY\fP is set\. +Use Pry instead of IRB\. Enabled by default if \fB$HOMEBREW_PRY\fP is set\. .SS "\fBlinkage\fP \fR[\fIoptions\fP] \fR[\fIinstalled_formula\fP \.\.\.]" Check the library links from the given \fIformula\fP kegs\. If no \fIformula\fP are provided, check all kegs\. Raises an error if run on uninstalled formulae\. .TP @@ -1743,9 +1743,9 @@ Exit with a non\-zero status if any undeclared dependencies with linkage are fou For every library that a keg references, print its dylib path followed by the binaries that link to it\. .TP \fB\-\-cached\fP -Print the cached linkage values stored in \fBHOMEBREW_CACHE\fP, set by a previous \fBbrew linkage\fP run\. +Print the cached linkage values stored in \fB$HOMEBREW_CACHE\fP, set by a previous \fBbrew linkage\fP run\. .SS "\fBlivecheck\fP, \fBlc\fP \fR[\fIoptions\fP] \fR[\fIformula\fP|\fIcask\fP \.\.\.]" -Check for newer versions of formulae and/or casks from upstream\. If no formula or cask argument is passed, the list of formulae and casks to check is taken from \fBHOMEBREW_LIVECHECK_WATCHLIST\fP or \fB~/\.homebrew/livecheck_watchlist\.txt\fP\&\. +Check for newer versions of formulae and/or casks from upstream\. If no formula or cask argument is passed, the list of formulae and casks to check is taken from \fB$HOMEBREW_LIVECHECK_WATCHLIST\fP or \fB~/\.homebrew/livecheck_watchlist\.txt\fP\&\. .TP \fB\-\-full\-name\fP Print formulae and casks with fully\-qualified names\. @@ -1954,10 +1954,10 @@ Only generate public API documentation\. \fB\-\-open\fP Open generated documentation in a browser\. .SS "\fBsh\fP \fR[\fB\-\-env=\fP] \fR[\fB\-\-cmd=\fP] \fR[\fIfile\fP]" -Enter an interactive shell for Homebrew\[u2019]s build environment\. Use years\-battle\-hardened build logic to help your \fB\&\./configure && make && make install\fP and even your \fBgem install\fP succeed\. Especially handy if you run Homebrew in an Xcode\-only configuration since it adds tools like \fBmake\fP to your \fBPATH\fP which build systems would not find otherwise\. +Enter an interactive shell for Homebrew\[u2019]s build environment\. Use years\-battle\-hardened build logic to help your \fB\&\./configure && make && make install\fP and even your \fBgem install\fP succeed\. Especially handy if you run Homebrew in an Xcode\-only configuration since it adds tools like \fBmake\fP to your \fB$PATH\fP which build systems would not find otherwise\. .TP \fB\-\-env\fP -Use the standard \fBPATH\fP instead of superenv\[u2019]s when \fBstd\fP is passed\. +Use the standard \fB$PATH\fP instead of superenv\[u2019]s when \fBstd\fP is passed\. .TP \fB\-c\fP, \fB\-\-cmd\fP Execute commands in a non\-interactive shell\. @@ -2087,7 +2087,7 @@ Print the number of unbottled and total formulae\. Print the \fBhomebrew/core\fP commits where bottles were lost in the last week\. .TP \fB\-\-eval\-all\fP -Evaluate all available formulae and casks, whether installed or not, to check them\. Implied if \fBHOMEBREW_EVAL_ALL\fP is set\. +Evaluate all available formulae and casks, whether installed or not, to check them\. Implied if \fB$HOMEBREW_EVAL_ALL\fP is set\. .SS "\fBunpack\fP \fR[\fIoptions\fP] \fIformula\fP \fR[\.\.\.]" Unpack the source files for \fIformula\fP into subdirectories of the current working directory\. .TP @@ -2141,7 +2141,7 @@ Update the list of GitHub Sponsors in the \fBHomebrew/brew\fP README\. Run a test of \fBbrew update\fP with a new repository clone\. If no options are passed, use \fBorigin/master\fP as the start commit\. .TP \fB\-\-to\-tag\fP -Set \fBHOMEBREW_UPDATE_TO_TAG\fP to test updating between tags\. +Set \fB$HOMEBREW_UPDATE_TO_TAG\fP to test updating between tags\. .TP \fB\-\-keep\-tmp\fP Retain the temporary directory containing the new repository clone\. @@ -2401,7 +2401,7 @@ Evaluate all installed taps, rather than just the core tap\. \fB\-\-max\-downloads\fP Specify a maximum number of formulae to download and update\. .SH "CUSTOM EXTERNAL COMMANDS" -Homebrew, like \fBgit\fP(1), supports external commands\. These are executable scripts that reside somewhere in the \fBPATH\fP, named \fBbrew\-\fP\fIcmdname\fP or \fBbrew\-\fP\fIcmdname\fP\fB\&\.rb\fP, which can be invoked like \fBbrew\fP \fIcmdname\fP\&\. This allows you to create your own commands without modifying Homebrew\[u2019]s internals\. +Homebrew, like \fBgit\fP(1), supports external commands\. These are executable scripts that reside somewhere in the \fB$PATH\fP, named \fBbrew\-\fP\fIcmdname\fP or \fBbrew\-\fP\fIcmdname\fP\fB\&\.rb\fP, which can be invoked like \fBbrew\fP \fIcmdname\fP\&\. This allows you to create your own commands without modifying Homebrew\[u2019]s internals\. .P Instructions for creating your own commands can be found in the docs: .UR https://docs\.brew\.sh/External\-Commands @@ -2427,7 +2427,7 @@ Note that environment variables must have a value set to be detected\. For examp .IP \(bu 4 \fB$XDG_CONFIG_HOME/homebrew/brew\.env\fP if \fB$XDG_CONFIG_HOME\fP is set or \fB~/\.homebrew/brew\.env\fP otherwise (user\-specific) .P -User\-specific environment files take precedence over prefix\-specific files and prefix\-specific files take precedence over system\-wide files (unless \fBHOMEBREW_SYSTEM_ENV_TAKES_PRIORITY\fP is set, see below)\. +User\-specific environment files take precedence over prefix\-specific files and prefix\-specific files take precedence over system\-wide files (unless \fB$HOMEBREW_SYSTEM_ENV_TAKES_PRIORITY\fP is set, see below)\. .P Note that these files do not support shell variable expansion e\.g\. \fB$HOME\fP or command execution e\.g\. \fB$(cat file)\fP\&\. .TP @@ -2836,7 +2836,7 @@ If set, Homebrew will use the given config file instead of \fB~/\.ssh/config\fP .RE .TP \fBHOMEBREW_SUDO_THROUGH_SUDO_USER\fP -If set, Homebrew will use the \fBSUDO_USER\fP environment variable to define the user to \fBsudo\fP(8) through when running \fBsudo\fP(8)\. +If set, Homebrew will use the \fB$SUDO_USER\fP environment variable to define the user to \fBsudo\fP(8) through when running \fBsudo\fP(8)\. .TP \fBHOMEBREW_SVN\fP Use this as the \fBsvn\fP(1) binary\. From fa45209f09f8e0c20a557a0d5653522d23f40fcb Mon Sep 17 00:00:00 2001 From: Rylan Polster Date: Tue, 3 Jun 2025 16:58:47 -0400 Subject: [PATCH 09/34] Fix sharded API structure to match existing API --- Library/Homebrew/dev-cmd/generate-cask-api.rb | 2 +- Library/Homebrew/dev-cmd/generate-formula-api.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Library/Homebrew/dev-cmd/generate-cask-api.rb b/Library/Homebrew/dev-cmd/generate-cask-api.rb index 5102d863b6..48bcfdbd40 100644 --- a/Library/Homebrew/dev-cmd/generate-cask-api.rb +++ b/Library/Homebrew/dev-cmd/generate-cask-api.rb @@ -71,7 +71,7 @@ module Homebrew File.write("_data/cask_canonical.json", "#{canonical_json}\n") unless args.dry_run? OnSystem::VALID_OS_ARCH_TAGS.each do |bottle_tag| - variation_casks = all_casks.transform_values do |cask| + variation_casks = all_casks.map do |_, cask| Homebrew::API.merge_variations(cask, bottle_tag:) end diff --git a/Library/Homebrew/dev-cmd/generate-formula-api.rb b/Library/Homebrew/dev-cmd/generate-formula-api.rb index 5d161ad89d..04a2077f9d 100644 --- a/Library/Homebrew/dev-cmd/generate-formula-api.rb +++ b/Library/Homebrew/dev-cmd/generate-formula-api.rb @@ -69,7 +69,7 @@ module Homebrew File.write("_data/formula_canonical.json", "#{canonical_json}\n") unless args.dry_run? OnSystem::VALID_OS_ARCH_TAGS.each do |bottle_tag| - variation_formulae = all_formulae.transform_values do |formula| + variation_formulae = all_formulae.map do |_, formula| Homebrew::API.merge_variations(formula, bottle_tag:) end From da624601bb9277f526b5ff312b3741db01ca8ba6 Mon Sep 17 00:00:00 2001 From: Rylan Polster Date: Wed, 4 Jun 2025 15:46:41 -0400 Subject: [PATCH 10/34] os/mac/pkgconfig/15: update `expat` version --- Library/Homebrew/os/mac/pkgconfig/15/expat.pc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Library/Homebrew/os/mac/pkgconfig/15/expat.pc b/Library/Homebrew/os/mac/pkgconfig/15/expat.pc index 32ce93ec72..883859e68a 100644 --- a/Library/Homebrew/os/mac/pkgconfig/15/expat.pc +++ b/Library/Homebrew/os/mac/pkgconfig/15/expat.pc @@ -5,7 +5,7 @@ libdir=${exec_prefix}/lib includedir=${prefix}/include Name: expat -Version: 2.6.3 +Version: 2.7.1 Description: expat XML parser URL: https://libexpat.github.io/ Libs: -L${libdir} -lexpat From 71c81741361d96864e533b6617397370434a2510 Mon Sep 17 00:00:00 2001 From: Rylan Polster Date: Wed, 4 Jun 2025 11:40:27 -0400 Subject: [PATCH 11/34] Add undocumented `HOMEBREW_USE_INTERNAL_API` switch --- Library/Homebrew/api/cask.rb | 11 +++++++++-- Library/Homebrew/api/formula.rb | 11 +++++++++-- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/Library/Homebrew/api/cask.rb b/Library/Homebrew/api/cask.rb index 03b94f848a..a06aa9b495 100644 --- a/Library/Homebrew/api/cask.rb +++ b/Library/Homebrew/api/cask.rb @@ -12,6 +12,13 @@ module Homebrew DEFAULT_API_FILENAME = "cask.jws.json" + sig { returns(String) } + def self.api_filename + return DEFAULT_API_FILENAME unless ENV.fetch("HOMEBREW_USE_INTERNAL_API", false) + + "cask.#{SimulateSystem.current_tag}.jws.json" + end + private_class_method :cache sig { params(token: String).returns(Hash) } @@ -41,12 +48,12 @@ module Homebrew end def self.cached_json_file_path - HOMEBREW_CACHE_API/DEFAULT_API_FILENAME + HOMEBREW_CACHE_API/api_filename end sig { returns(T::Boolean) } def self.download_and_cache_data! - json_casks, updated = Homebrew::API.fetch_json_api_file DEFAULT_API_FILENAME + json_casks, updated = Homebrew::API.fetch_json_api_file api_filename cache["renames"] = {} cache["casks"] = json_casks.to_h do |json_cask| diff --git a/Library/Homebrew/api/formula.rb b/Library/Homebrew/api/formula.rb index 1bcd622da4..fe02c4bc08 100644 --- a/Library/Homebrew/api/formula.rb +++ b/Library/Homebrew/api/formula.rb @@ -12,6 +12,13 @@ module Homebrew DEFAULT_API_FILENAME = "formula.jws.json" + sig { returns(String) } + def self.api_filename + return DEFAULT_API_FILENAME unless ENV.fetch("HOMEBREW_USE_INTERNAL_API", false) + + "internal/formula.#{SimulateSystem.current_tag}.jws.json" + end + private_class_method :cache sig { params(name: String).returns(T::Hash[String, T.untyped]) } @@ -42,12 +49,12 @@ module Homebrew sig { returns(Pathname) } def self.cached_json_file_path - HOMEBREW_CACHE_API/DEFAULT_API_FILENAME + HOMEBREW_CACHE_API/api_filename end sig { returns(T::Boolean) } def self.download_and_cache_data! - json_formulae, updated = Homebrew::API.fetch_json_api_file DEFAULT_API_FILENAME + json_formulae, updated = Homebrew::API.fetch_json_api_file api_filename cache["aliases"] = {} cache["renames"] = {} From b44ec56267366ce22fc90459bcd2f671b8d01748 Mon Sep 17 00:00:00 2001 From: Rylan Polster Date: Thu, 5 Jun 2025 02:08:29 -0400 Subject: [PATCH 12/34] Reduce the internal formula API to contain the bare minimum data --- Library/Homebrew/dev-cmd/generate-cask-api.rb | 4 +--- Library/Homebrew/dev-cmd/generate-formula-api.rb | 12 ++++++++++-- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/Library/Homebrew/dev-cmd/generate-cask-api.rb b/Library/Homebrew/dev-cmd/generate-cask-api.rb index 48bcfdbd40..9f639aec52 100644 --- a/Library/Homebrew/dev-cmd/generate-cask-api.rb +++ b/Library/Homebrew/dev-cmd/generate-cask-api.rb @@ -75,9 +75,7 @@ module Homebrew Homebrew::API.merge_variations(cask, bottle_tag:) end - unless args.dry_run? - File.write("api/internal/cask.#{bottle_tag}.json", JSON.pretty_generate(variation_casks)) - end + File.write("api/internal/cask.#{bottle_tag}.json", JSON.generate(variation_casks)) unless args.dry_run? end end end diff --git a/Library/Homebrew/dev-cmd/generate-formula-api.rb b/Library/Homebrew/dev-cmd/generate-formula-api.rb index 04a2077f9d..041b815f2d 100644 --- a/Library/Homebrew/dev-cmd/generate-formula-api.rb +++ b/Library/Homebrew/dev-cmd/generate-formula-api.rb @@ -70,11 +70,19 @@ module Homebrew OnSystem::VALID_OS_ARCH_TAGS.each do |bottle_tag| variation_formulae = all_formulae.map do |_, formula| - Homebrew::API.merge_variations(formula, bottle_tag:) + formula = Homebrew::API.merge_variations(formula, bottle_tag:) + + version = Version.new(formula.dig("versions", "stable")) + pkg_version = PkgVersion.new(version, formula["revision"]) + rebuild = formula.dig("bottle", "stable", "rebuild") || 0 + sha256 = formula.dig("bottle", "stable", "files", :all, "sha256") + sha256 ||= formula.dig("bottle", "stable", "files", bottle_tag.to_sym, "sha256") + + [formula["name"], pkg_version.to_s, rebuild, sha256] end unless args.dry_run? - File.write("api/internal/formula.#{bottle_tag}.json", JSON.pretty_generate(variation_formulae)) + File.write("api/internal/formula.#{bottle_tag}.json", JSON.generate(variation_formulae)) end end end From e47bc2fb86dbe037b8f566c7a19305ce704c7ae8 Mon Sep 17 00:00:00 2001 From: Rylan Polster Date: Thu, 5 Jun 2025 03:15:44 -0400 Subject: [PATCH 13/34] Use hashes of arrays instead --- Library/Homebrew/dev-cmd/generate-formula-api.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Library/Homebrew/dev-cmd/generate-formula-api.rb b/Library/Homebrew/dev-cmd/generate-formula-api.rb index 041b815f2d..a9afe47ee7 100644 --- a/Library/Homebrew/dev-cmd/generate-formula-api.rb +++ b/Library/Homebrew/dev-cmd/generate-formula-api.rb @@ -69,7 +69,7 @@ module Homebrew File.write("_data/formula_canonical.json", "#{canonical_json}\n") unless args.dry_run? OnSystem::VALID_OS_ARCH_TAGS.each do |bottle_tag| - variation_formulae = all_formulae.map do |_, formula| + variation_formulae = all_formulae.to_h do |name, formula| formula = Homebrew::API.merge_variations(formula, bottle_tag:) version = Version.new(formula.dig("versions", "stable")) @@ -78,7 +78,7 @@ module Homebrew sha256 = formula.dig("bottle", "stable", "files", :all, "sha256") sha256 ||= formula.dig("bottle", "stable", "files", bottle_tag.to_sym, "sha256") - [formula["name"], pkg_version.to_s, rebuild, sha256] + [name, [pkg_version.to_s, rebuild, sha256]] end unless args.dry_run? From 916c25ef1827e02c385423aaf8c185f7aef9d43c Mon Sep 17 00:00:00 2001 From: Mike McQuaid Date: Thu, 5 Jun 2025 08:33:08 +0100 Subject: [PATCH 14/34] bin/brew: don't copy across zeroed env values. --- bin/brew | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/brew b/bin/brew index f0b0e5adc3..3ed923d1e4 100755 --- a/bin/brew +++ b/bin/brew @@ -183,8 +183,8 @@ MANPAGE_VARS=( ) for VAR in "${MANPAGE_VARS[@]}" do - # Skip if variable value is empty. - [[ -z "${!VAR:-}" ]] && continue + # Skip if variable value is empty or set to 0. + [[ -z "${!VAR:-}" || "${!VAR:-}" = "0" ]] && continue VAR_NEW="HOMEBREW_${VAR}" # Skip if existing HOMEBREW_* variable is set. From 5fe43ed3f26713c8a515c1e11fdaaf6efeed191e Mon Sep 17 00:00:00 2001 From: Mike McQuaid Date: Thu, 5 Jun 2025 15:43:34 +0100 Subject: [PATCH 15/34] `brew (bundle|) sh`: use user's configuration but override prompts. This was more painful that I expected but will allow `brew bundle sh` and `brew sh` to use the user's configuration but use our custom prompt for Bash and ZSH. --- Library/Homebrew/bundle/commands/exec.rb | 12 +++++++ Library/Homebrew/cmd/bundle.rb | 12 +------ Library/Homebrew/test/utils/shell_spec.rb | 32 ++++++++++++++----- .../utils/bash/brew-sh-prompt-bashrc.bash | 12 +++++++ Library/Homebrew/utils/shell.rb | 22 ++++++++++--- .../utils/zsh/brew-sh-prompt-zshrc.zsh | 13 ++++++++ 6 files changed, 80 insertions(+), 23 deletions(-) create mode 100644 Library/Homebrew/utils/bash/brew-sh-prompt-bashrc.bash create mode 100644 Library/Homebrew/utils/zsh/brew-sh-prompt-zshrc.zsh diff --git a/Library/Homebrew/bundle/commands/exec.rb b/Library/Homebrew/bundle/commands/exec.rb index 103706dd76..d7babf8afc 100644 --- a/Library/Homebrew/bundle/commands/exec.rb +++ b/Library/Homebrew/bundle/commands/exec.rb @@ -170,6 +170,18 @@ module Homebrew end end return + elsif subcommand == "sh" + preferred_path = Utils::Shell.preferred_path(default: "/bin/bash") + notice = unless Homebrew::EnvConfig.no_env_hints? + <<~EOS + Your shell has been configured to use a build environment from your `Brewfile`. + This should help you build stuff. + Hide these hints with HOMEBREW_NO_ENV_HINTS (see `man brew`). + When done, type `exit`. + EOS + end + ENV["HOMEBREW_FORCE_API_AUTO_UPDATE"] = nil + args = [Utils::Shell.shell_with_prompt("brew bundle", preferred_path:, notice:)] end if services diff --git a/Library/Homebrew/cmd/bundle.rb b/Library/Homebrew/cmd/bundle.rb index 122341a741..b942802e5f 100755 --- a/Library/Homebrew/cmd/bundle.rb +++ b/Library/Homebrew/cmd/bundle.rb @@ -276,17 +276,7 @@ module Homebrew _subcommand, *named_args = args.named named_args when "sh" - preferred_path = Utils::Shell.preferred_path(default: "/bin/bash") - notice = unless Homebrew::EnvConfig.no_env_hints? - <<~EOS - Your shell has been configured to use a build environment from your `Brewfile`. - This should help you build stuff. - Hide these hints with HOMEBREW_NO_ENV_HINTS (see `man brew`). - When done, type `exit`. - EOS - end - ENV["HOMEBREW_FORCE_API_AUTO_UPDATE"] = nil - [Utils::Shell.shell_with_prompt("brew bundle", preferred_path:, notice:)] + ["sh"] when "env" ["env"] end diff --git a/Library/Homebrew/test/utils/shell_spec.rb b/Library/Homebrew/test/utils/shell_spec.rb index 66cf8edfd8..bd07c39d71 100644 --- a/Library/Homebrew/test/utils/shell_spec.rb +++ b/Library/Homebrew/test/utils/shell_spec.rb @@ -107,18 +107,34 @@ RSpec.describe Utils::Shell do end describe "::shell_with_prompt" do + let(:home) { HOMEBREW_TEMP } + let(:notice) { "" } + let(:prompt) { "test" } + let(:path) { "/some/path" } + it "returns zsh-specific prompt configuration" do - ENV["SHELL"] = "/bin/zsh" - expect(described_class.shell_with_prompt("test", preferred_path: "/bin/zsh", notice: "")).to eq( - "PROMPT='%B%F{green}test%f %F{blue}$%f%b ' RPROMPT='[%B%F{red}%~%f%b]' /bin/zsh -f", - ) + preferred_path = "/bin/zsh" + ENV["SHELL"] = preferred_path + ENV["PATH"] = path + zdotdir = "#{HOMEBREW_TEMP}/brew-zsh-prompt-#{Process.euid}" + expect(described_class.shell_with_prompt(prompt, preferred_path:, notice:, home:)).to eq \ + "BREW_PROMPT_PATH=\"#{path}\" BREW_PROMPT_TYPE=\"#{prompt}\" ZDOTDIR=\"#{zdotdir}\" #{preferred_path}" + end + + it "returns bash-specific prompt configuration" do + preferred_path = "/bin/bash" + ENV["SHELL"] = "/bin/bash" + ENV["PATH"] = path + rcfile = "#{HOMEBREW_LIBRARY_PATH}/utils/bash/brew-sh-prompt-bashrc.bash" + expect(described_class.shell_with_prompt(prompt, preferred_path:, notice:, home:)).to eq \ + "BREW_PROMPT_PATH=\"#{path}\" BREW_PROMPT_TYPE=\"#{prompt}\" #{preferred_path} --rcfile \"#{rcfile}\"" end it "returns generic shell prompt configuration" do - ENV["SHELL"] = "/bin/bash" - expect(described_class.shell_with_prompt("test", preferred_path: "/bin/bash", notice: "")).to eq( - "PS1=\"\\[\\033[1;32m\\]brew \\[\\033[1;31m\\]\\w \\[\\033[1;34m\\]$\\[\\033[0m\\] \" /bin/bash", - ) + preferred_path = "/bin/dash" + ENV["SHELL"] = preferred_path + expect(described_class.shell_with_prompt(prompt, preferred_path:, notice:, home:)).to eq \ + "PS1=\"\\[\\033[1;32m\\]#{prompt} \\[\\033[1;31m\\]\\w \\[\\033[1;34m\\]$\\[\\033[0m\\] \" #{preferred_path}" end it "outputs notice when provided" do diff --git a/Library/Homebrew/utils/bash/brew-sh-prompt-bashrc.bash b/Library/Homebrew/utils/bash/brew-sh-prompt-bashrc.bash new file mode 100644 index 0000000000..d4d9dd7e3e --- /dev/null +++ b/Library/Homebrew/utils/bash/brew-sh-prompt-bashrc.bash @@ -0,0 +1,12 @@ +# Read the user's ~/.bashrc first +if [[ -f "${HOME}/.bashrc" ]] +then + source "${HOME}/.bashrc" +fi + +# Override the user's Bash prompt with our custom prompt +export PS1="\\[\\033[1;32m\\]${BREW_PROMPT_TYPE} \\[\\033[1;31m\\]\\w \\[\\033[1;34m\\]$\\[\\033[0m\\] " + +# Add the Homebrew PATH in front of the user's PATH +export PATH="${BREW_PROMPT_PATH}:${PATH}" +unset BREW_PROMPT_TYPE BREW_PROMPT_PATH diff --git a/Library/Homebrew/utils/shell.rb b/Library/Homebrew/utils/shell.rb index 4582542438..bb9396d5fd 100644 --- a/Library/Homebrew/utils/shell.rb +++ b/Library/Homebrew/utils/shell.rb @@ -153,14 +153,28 @@ module Utils str end - sig { params(type: String, preferred_path: String, notice: T.nilable(String)).returns(String) } - def shell_with_prompt(type, preferred_path:, notice:) + sig { params(type: String, preferred_path: String, notice: T.nilable(String), home: String).returns(String) } + def shell_with_prompt(type, preferred_path:, notice:, home: Dir.home) preferred = from_path(preferred_path) + path = ENV.fetch("PATH") subshell = case preferred when :zsh - "PROMPT='%B%F{green}#{type}%f %F{blue}$%f%b ' RPROMPT='[%B%F{red}%~%f%b]' #{preferred_path} -f" + zdotdir = Pathname.new(HOMEBREW_TEMP/"brew-zsh-prompt-#{Process.euid}") + zdotdir.mkpath + FileUtils.chmod_R(0700, zdotdir) + FileUtils.cp(HOMEBREW_LIBRARY_PATH/"utils/zsh/brew-sh-prompt-zshrc.zsh", zdotdir/".zshrc") + %w[.zcompdump .zsh_history .zsh_sessions].each do |file| + FileUtils.ln_sf("#{home}/#{file}", zdotdir/file) + end + <<~ZSH.strip + BREW_PROMPT_PATH="#{path}" BREW_PROMPT_TYPE="#{type}" ZDOTDIR="#{zdotdir}" #{preferred_path} + ZSH + when :bash + <<~BASH.strip + BREW_PROMPT_PATH="#{path}" BREW_PROMPT_TYPE="#{type}" #{preferred_path} --rcfile "#{HOMEBREW_LIBRARY_PATH}/utils/bash/brew-sh-prompt-bashrc.bash" + BASH else - "PS1=\"\\[\\033[1;32m\\]brew \\[\\033[1;31m\\]\\w \\[\\033[1;34m\\]$\\[\\033[0m\\] \" #{preferred_path}" + "PS1=\"\\[\\033[1;32m\\]#{type} \\[\\033[1;31m\\]\\w \\[\\033[1;34m\\]$\\[\\033[0m\\] \" #{preferred_path}" end puts notice if notice.present? diff --git a/Library/Homebrew/utils/zsh/brew-sh-prompt-zshrc.zsh b/Library/Homebrew/utils/zsh/brew-sh-prompt-zshrc.zsh new file mode 100644 index 0000000000..8ef8cda5ac --- /dev/null +++ b/Library/Homebrew/utils/zsh/brew-sh-prompt-zshrc.zsh @@ -0,0 +1,13 @@ +# Read the user's ~/.zshrc first +if [[ -f "${HOME}/.zshrc" ]] +then + source "${HOME}/.zshrc" +fi + +# Override the user's ZSH prompt with our custom prompt +export PROMPT="%B%F{green}${BREW_PROMPT_TYPE}%f %F{blue}$%f%b " +export RPROMPT="[%B%F{red}%~%f%b]" + +# Add the Homebrew PATH in front of the user's PATH +export PATH="${BREW_PROMPT_PATH}:${PATH}" +unset BREW_PROMPT_TYPE BREW_PROMPT_PATH From c75122c694c07cf55526ec1a4f0fd265b414b913 Mon Sep 17 00:00:00 2001 From: Eric Knibbe Date: Thu, 5 Jun 2025 10:36:19 -0400 Subject: [PATCH 16/34] rubocops/cask/url: put keyword parameters on a new line --- Library/Homebrew/rubocops/cask/url.rb | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Library/Homebrew/rubocops/cask/url.rb b/Library/Homebrew/rubocops/cask/url.rb index a62f5e884a..54ffcd1e84 100644 --- a/Library/Homebrew/rubocops/cask/url.rb +++ b/Library/Homebrew/rubocops/cask/url.rb @@ -41,6 +41,15 @@ module RuboCop return unless hash_node.hash_type? + unless stanza_node.source.match?(/",\n *\w+:/) + add_offense( + stanza_node.source_range, + message: "Keyword URL parameter should be on a new indented line.", + ) do |corrector| + corrector.replace(stanza_node.source_range, stanza_node.source.gsub(/",\s*/, "\",\n ")) + end + end + hash_node.each_pair do |key_node, value_node| next if key_node.source != "verified" next unless value_node.str_type? From e83dc1cb3c16812a61aac37f3594cbf760c7013b Mon Sep 17 00:00:00 2001 From: Rylan Polster Date: Thu, 5 Jun 2025 11:32:47 -0400 Subject: [PATCH 17/34] Fallback to older bottle hashes when viable --- .../Homebrew/dev-cmd/generate-formula-api.rb | 32 ++++++++++- .../test/dev-cmd/generate-formula-api_spec.rb | 54 +++++++++++++++++++ 2 files changed, 84 insertions(+), 2 deletions(-) diff --git a/Library/Homebrew/dev-cmd/generate-formula-api.rb b/Library/Homebrew/dev-cmd/generate-formula-api.rb index a9afe47ee7..747f838e17 100644 --- a/Library/Homebrew/dev-cmd/generate-formula-api.rb +++ b/Library/Homebrew/dev-cmd/generate-formula-api.rb @@ -75,8 +75,7 @@ module Homebrew version = Version.new(formula.dig("versions", "stable")) pkg_version = PkgVersion.new(version, formula["revision"]) rebuild = formula.dig("bottle", "stable", "rebuild") || 0 - sha256 = formula.dig("bottle", "stable", "files", :all, "sha256") - sha256 ||= formula.dig("bottle", "stable", "files", bottle_tag.to_sym, "sha256") + sha256 = newest_bottle_sha256(formula, bottle_tag) [name, [pkg_version.to_s, rebuild, sha256]] end @@ -88,6 +87,35 @@ module Homebrew end end + sig { + params(formula_json: T::Hash[String, T.untyped], bottle_tag: Utils::Bottles::Tag).returns(T.nilable(String)) + } + def newest_bottle_sha256(formula_json, bottle_tag) + available_tags = formula_json.dig("bottle", "stable", "files")&.keys&.map(&:to_sym) + return unless available_tags + + return formula_json.dig("bottle", "stable", "files", :all, "sha256") if available_tags.include? :all + + if available_tags.include? bottle_tag.to_sym + return formula_json.dig("bottle", "stable", "files", bottle_tag.to_sym, "sha256") + end + + return unless bottle_tag.macos? + + # If the actual tag is not available, find the newest tag with matching arch that's older than the actual tag + newest_viable_macos_tag = available_tags.filter_map do |tag_sym| + tag = Utils::Bottles::Tag.from_symbol(tag_sym) + next unless tag.macos? + next if tag.arch != bottle_tag.arch + next if tag.to_macos_version > bottle_tag.to_macos_version + + tag + end.max_by(&:to_macos_version) + return unless newest_viable_macos_tag + + formula_json.dig("bottle", "stable", "files", newest_viable_macos_tag.to_sym, "sha256") + end + private sig { params(title: String).returns(String) } diff --git a/Library/Homebrew/test/dev-cmd/generate-formula-api_spec.rb b/Library/Homebrew/test/dev-cmd/generate-formula-api_spec.rb index 74136d6645..675d937ed7 100644 --- a/Library/Homebrew/test/dev-cmd/generate-formula-api_spec.rb +++ b/Library/Homebrew/test/dev-cmd/generate-formula-api_spec.rb @@ -5,4 +5,58 @@ require "dev-cmd/generate-formula-api" RSpec.describe Homebrew::DevCmd::GenerateFormulaApi do it_behaves_like "parseable arguments" + + describe "#newest_bottle_sha256" do + subject(:generate_formula_api) { described_class.new [] } + + def make_json(bottles) + json = { + "bottle" => { + "stable" => { + "files" => {}, + }, + }, + } + bottles.each do |tag, sha256| + json["bottle"]["stable"]["files"][tag] = { "sha256" => sha256 } + end + json + end + + expected_sha256s = { + arm64_sequoia: "abc123", + arm64_sonoma: "abc123", + arm64_ventura: "ghi789", + arm64_monterey: nil, + sequoia: "jkl012", + sonoma: "jkl012", + ventura: "mno345", + monterey: "mno345", + x86_64_linux: "pqr678", + arm64_linux: nil, + }.transform_keys do |tag| + Utils::Bottles::Tag.from_symbol(tag) + end + + let(:all_json) { make_json all: "abc123" } + let(:standard_json) do + make_json arm64_sonoma: "abc123", + arm64_ventura: "ghi789", + sonoma: "jkl012", + big_sur: "mno345", + x86_64_linux: "pqr678" + end + + it "returns the sha256 for the :all tag on all systems" do + expected_sha256s.each_key do |tag| + expect(generate_formula_api.newest_bottle_sha256(all_json, tag)).to eq("abc123") + end + end + + expected_sha256s.each_key do |tag| + it "returns the corrent sha256 for #{tag}" do + expect(generate_formula_api.newest_bottle_sha256(standard_json, tag)).to eq(expected_sha256s[tag]) + end + end + end end From 73b64390b3d296f78ec2331e00ac74282c6143f4 Mon Sep 17 00:00:00 2001 From: Rylan Polster Date: Thu, 5 Jun 2025 12:38:15 -0400 Subject: [PATCH 18/34] Use existing `Utils::Bottles::Collector#specification_for` method --- .../Homebrew/dev-cmd/generate-formula-api.rb | 38 +++---------- .../Homebrew/extend/os/mac/utils/bottles.rb | 2 +- .../test/dev-cmd/generate-formula-api_spec.rb | 54 ------------------- 3 files changed, 9 insertions(+), 85 deletions(-) diff --git a/Library/Homebrew/dev-cmd/generate-formula-api.rb b/Library/Homebrew/dev-cmd/generate-formula-api.rb index 747f838e17..5741ce6872 100644 --- a/Library/Homebrew/dev-cmd/generate-formula-api.rb +++ b/Library/Homebrew/dev-cmd/generate-formula-api.rb @@ -75,7 +75,14 @@ module Homebrew version = Version.new(formula.dig("versions", "stable")) pkg_version = PkgVersion.new(version, formula["revision"]) rebuild = formula.dig("bottle", "stable", "rebuild") || 0 - sha256 = newest_bottle_sha256(formula, bottle_tag) + + bottle_collector = Utils::Bottles::Collector.new + formula.dig("bottle", "stable", "files")&.each do |tag, data| + tag = Utils::Bottles::Tag.from_symbol(tag) + bottle_collector.add tag, checksum: Checksum.new(data["sha256"]), cellar: :any + end + + sha256 = bottle_collector.specification_for(bottle_tag)&.checksum&.to_s [name, [pkg_version.to_s, rebuild, sha256]] end @@ -87,35 +94,6 @@ module Homebrew end end - sig { - params(formula_json: T::Hash[String, T.untyped], bottle_tag: Utils::Bottles::Tag).returns(T.nilable(String)) - } - def newest_bottle_sha256(formula_json, bottle_tag) - available_tags = formula_json.dig("bottle", "stable", "files")&.keys&.map(&:to_sym) - return unless available_tags - - return formula_json.dig("bottle", "stable", "files", :all, "sha256") if available_tags.include? :all - - if available_tags.include? bottle_tag.to_sym - return formula_json.dig("bottle", "stable", "files", bottle_tag.to_sym, "sha256") - end - - return unless bottle_tag.macos? - - # If the actual tag is not available, find the newest tag with matching arch that's older than the actual tag - newest_viable_macos_tag = available_tags.filter_map do |tag_sym| - tag = Utils::Bottles::Tag.from_symbol(tag_sym) - next unless tag.macos? - next if tag.arch != bottle_tag.arch - next if tag.to_macos_version > bottle_tag.to_macos_version - - tag - end.max_by(&:to_macos_version) - return unless newest_viable_macos_tag - - formula_json.dig("bottle", "stable", "files", newest_viable_macos_tag.to_sym, "sha256") - end - private sig { params(title: String).returns(String) } diff --git a/Library/Homebrew/extend/os/mac/utils/bottles.rb b/Library/Homebrew/extend/os/mac/utils/bottles.rb index 754aeaec64..9b4c71a914 100644 --- a/Library/Homebrew/extend/os/mac/utils/bottles.rb +++ b/Library/Homebrew/extend/os/mac/utils/bottles.rb @@ -47,7 +47,7 @@ module Utils return if tag_version.blank? tags.find do |candidate| - next if candidate.arch != tag.arch + next if candidate.standardized_arch != tag.standardized_arch candidate.to_macos_version <= tag_version rescue MacOSVersion::Error diff --git a/Library/Homebrew/test/dev-cmd/generate-formula-api_spec.rb b/Library/Homebrew/test/dev-cmd/generate-formula-api_spec.rb index 675d937ed7..74136d6645 100644 --- a/Library/Homebrew/test/dev-cmd/generate-formula-api_spec.rb +++ b/Library/Homebrew/test/dev-cmd/generate-formula-api_spec.rb @@ -5,58 +5,4 @@ require "dev-cmd/generate-formula-api" RSpec.describe Homebrew::DevCmd::GenerateFormulaApi do it_behaves_like "parseable arguments" - - describe "#newest_bottle_sha256" do - subject(:generate_formula_api) { described_class.new [] } - - def make_json(bottles) - json = { - "bottle" => { - "stable" => { - "files" => {}, - }, - }, - } - bottles.each do |tag, sha256| - json["bottle"]["stable"]["files"][tag] = { "sha256" => sha256 } - end - json - end - - expected_sha256s = { - arm64_sequoia: "abc123", - arm64_sonoma: "abc123", - arm64_ventura: "ghi789", - arm64_monterey: nil, - sequoia: "jkl012", - sonoma: "jkl012", - ventura: "mno345", - monterey: "mno345", - x86_64_linux: "pqr678", - arm64_linux: nil, - }.transform_keys do |tag| - Utils::Bottles::Tag.from_symbol(tag) - end - - let(:all_json) { make_json all: "abc123" } - let(:standard_json) do - make_json arm64_sonoma: "abc123", - arm64_ventura: "ghi789", - sonoma: "jkl012", - big_sur: "mno345", - x86_64_linux: "pqr678" - end - - it "returns the sha256 for the :all tag on all systems" do - expected_sha256s.each_key do |tag| - expect(generate_formula_api.newest_bottle_sha256(all_json, tag)).to eq("abc123") - end - end - - expected_sha256s.each_key do |tag| - it "returns the corrent sha256 for #{tag}" do - expect(generate_formula_api.newest_bottle_sha256(standard_json, tag)).to eq(expected_sha256s[tag]) - end - end - end end From 08e9a4365f8906458ebb846d8524d7eb09862f78 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 6 Jun 2025 08:33:23 +0000 Subject: [PATCH 19/34] build(deps): bump github/codeql-action in the github-actions group Bumps the github-actions group with 1 update: [github/codeql-action](https://github.com/github/codeql-action). Updates `github/codeql-action` from 3.28.18 to 3.28.19 - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/ff0a06e83cb2de871e5a09832bc6a81e7276941f...fca7ace96b7d713c7035871441bd52efbe39e27e) --- updated-dependencies: - dependency-name: github/codeql-action dependency-version: 3.28.19 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: github-actions ... Signed-off-by: dependabot[bot] --- .github/workflows/actionlint.yml | 2 +- .github/workflows/codeql-analysis.yml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/actionlint.yml b/.github/workflows/actionlint.yml index d35fac7a95..3185517144 100644 --- a/.github/workflows/actionlint.yml +++ b/.github/workflows/actionlint.yml @@ -77,7 +77,7 @@ jobs: path: results.sarif - name: Upload SARIF file - uses: github/codeql-action/upload-sarif@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18 + uses: github/codeql-action/upload-sarif@fca7ace96b7d713c7035871441bd52efbe39e27e # v3.28.19 with: sarif_file: results.sarif category: zizmor diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 939da5f9e7..a3386e59c4 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -28,7 +28,7 @@ jobs: persist-credentials: false - name: Initialize CodeQL - uses: github/codeql-action/init@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18 + uses: github/codeql-action/init@fca7ace96b7d713c7035871441bd52efbe39e27e # v3.28.19 with: languages: ruby config: | @@ -36,4 +36,4 @@ jobs: - Library/Homebrew/vendor - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18 + uses: github/codeql-action/analyze@fca7ace96b7d713c7035871441bd52efbe39e27e # v3.28.19 From e7f667c19879114524719b1c6fda9db974d484a4 Mon Sep 17 00:00:00 2001 From: Mike McQuaid Date: Fri, 6 Jun 2025 14:18:56 +0100 Subject: [PATCH 20/34] cask_loader: improve error handling. Handle weird edge cases where we try to read a cask from invalid paths. --- Library/Homebrew/cask/cask_loader.rb | 29 ++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/Library/Homebrew/cask/cask_loader.rb b/Library/Homebrew/cask/cask_loader.rb index bdf4bded72..24befa53a3 100644 --- a/Library/Homebrew/cask/cask_loader.rb +++ b/Library/Homebrew/cask/cask_loader.rb @@ -6,6 +6,7 @@ require "cask/cask" require "uri" require "utils/curl" require "extend/hash/keys" +require "api" module Cask # Loads a cask from various sources. @@ -104,8 +105,8 @@ module Cask return end - return if %w[.rb .json].exclude?(path.extname) return unless path.expand_path.exist? + return if invalid_path?(path) return if Homebrew::EnvConfig.forbid_packages_from_paths? && !path.realpath.to_s.start_with?("#{Caskroom.path}/", "#{HOMEBREW_LIBRARY}/Taps/") @@ -113,6 +114,14 @@ module Cask new(path) end + sig { params(pathname: Pathname, valid_extnames: T::Array[String]).returns(T::Boolean) } + def self.invalid_path?(pathname, valid_extnames: %w[.rb .json]) + return true if valid_extnames.exclude?(pathname.extname) + + @invalid_basenames ||= %w[INSTALL_RECEIPT.json sbom.spdx.json].freeze + @invalid_basenames.include?(pathname.basename.to_s) + end + attr_reader :token, :path sig { params(path: T.any(Pathname, String), token: String).void } @@ -135,8 +144,10 @@ module Cask @content = path.read(encoding: "UTF-8") @config = config - if path.extname == ".json" - return FromAPILoader.new(token, from_json: JSON.parse(@content), path:).load(config:) + if !self.class.invalid_path?(path, valid_extnames: %w[.json]) && + (from_json = JSON.parse(@content).presence) && + from_json.is_a?(Hash) + return FromAPILoader.new(token, from_json:, path:).load(config:) end begin @@ -284,7 +295,7 @@ module Cask sig { returns(Pathname) } attr_reader :path - sig { returns(T.nilable(Hash)) } + sig { returns(T.nilable(T::Hash[T.any(String, Symbol), T.anything])) } attr_reader :from_json sig { @@ -306,7 +317,13 @@ module Cask new("#{tap}/#{token}") end - sig { params(token: String, from_json: Hash, path: T.nilable(Pathname)).void } + sig { + params( + token: String, + from_json: T.nilable(T::Hash[T.any(String, Symbol), T.anything]), + path: T.nilable(Pathname), + ).void + } def initialize(token, from_json: T.unsafe(nil), path: nil) @token = token.sub(%r{^homebrew/(?:homebrew-)?cask/}i, "") @sourcefile_path = path || Homebrew::API::Cask.cached_json_file_path @@ -400,7 +417,7 @@ module Cask container(**container_hash) end - json_cask[:artifacts].each do |artifact| + json_cask[:artifacts]&.each do |artifact| # convert generic string replacements into actual ones artifact = cask.loader.from_h_gsubs(artifact, appdir) key = artifact.keys.first From ff710f81919ffc170949bc760688b24bba55d84a Mon Sep 17 00:00:00 2001 From: Mike McQuaid Date: Fri, 6 Jun 2025 17:09:28 +0100 Subject: [PATCH 21/34] Improve completions (and elisp) output in caveats Instead of repeatedly outputting the same identical messages across multiple packages and repeating them all for every package after they were all installed: just output the identical messages in the final caveats output instead. --- Library/Homebrew/caveats.rb | 68 +++++++++++++-------- Library/Homebrew/formula_installer.rb | 4 +- Library/Homebrew/messages.rb | 19 ++++-- Library/Homebrew/sorbet/rbi/dsl/caveats.rbi | 3 - Library/Homebrew/test/caveats_spec.rb | 10 +-- 5 files changed, 62 insertions(+), 42 deletions(-) diff --git a/Library/Homebrew/caveats.rb b/Library/Homebrew/caveats.rb index b843926058..c473590630 100644 --- a/Library/Homebrew/caveats.rb +++ b/Library/Homebrew/caveats.rb @@ -14,40 +14,54 @@ class Caveats sig { params(formula: Formula).void } def initialize(formula) @formula = formula + @caveats = T.let(nil, T.nilable(String)) + @completions_and_elisp = T.let(nil, T.nilable(T::Array[String])) end sig { returns(String) } def caveats - caveats = [] - build = formula.build - begin - formula.build = Tab.for_formula(formula) - string = formula.caveats.to_s - caveats << "#{string.chomp}\n" unless string.empty? - ensure - formula.build = build + @caveats ||= begin + caveats = [] + build = formula.build + begin + formula.build = Tab.for_formula(formula) + string = formula.caveats.to_s + caveats << "#{string.chomp}\n" unless string.empty? + ensure + formula.build = build + end + caveats << keg_only_text + caveats << service_caveats + caveats.compact.join("\n") end - caveats << keg_only_text - - valid_shells = [:bash, :zsh, :fish, :pwsh].freeze - current_shell = Utils::Shell.preferred || Utils::Shell.parent - shells = if current_shell.present? && - (shell_sym = current_shell.to_sym) && - valid_shells.include?(shell_sym) - [shell_sym] - else - valid_shells - end - shells.each do |shell| - caveats << function_completion_caveats(shell) - end - - caveats << service_caveats - caveats << elisp_caveats - caveats.compact.join("\n") end - delegate [:empty?, :to_s] => :caveats + sig { returns(T::Boolean) } + def empty? + caveats.blank? && completions_and_elisp.blank? + end + + delegate [:to_s] => :caveats + + sig { returns(T::Array[String]) } + def completions_and_elisp + @completions_and_elisp ||= begin + valid_shells = [:bash, :zsh, :fish, :pwsh].freeze + current_shell = Utils::Shell.preferred || Utils::Shell.parent + shells = if current_shell.present? && + (shell_sym = current_shell.to_sym) && + valid_shells.include?(shell_sym) + [shell_sym] + else + valid_shells + end + completions_and_elisp = shells.map do |shell| + function_completion_caveats(shell) + end + completions_and_elisp << elisp_caveats + completions_and_elisp.compact + end + end sig { params(skip_reason: T::Boolean).returns(T.nilable(String)) } def keg_only_text(skip_reason: false) diff --git a/Library/Homebrew/formula_installer.rb b/Library/Homebrew/formula_installer.rb index 7d7aad186d..bff2564824 100644 --- a/Library/Homebrew/formula_installer.rb +++ b/Library/Homebrew/formula_installer.rb @@ -892,9 +892,11 @@ on_request: installed_on_request?, options:) return if quiet? caveats = Caveats.new(formula) - return if caveats.empty? + Homebrew.messages.record_completions_and_elisp(caveats.completions_and_elisp) + return if caveats.caveats.empty? + @show_summary_heading = true ohai "Caveats", caveats.to_s Homebrew.messages.record_caveats(formula.name, caveats) diff --git a/Library/Homebrew/messages.rb b/Library/Homebrew/messages.rb index cdbf7059e9..830ce46fac 100644 --- a/Library/Homebrew/messages.rb +++ b/Library/Homebrew/messages.rb @@ -16,6 +16,7 @@ class Messages sig { void } def initialize @caveats = T.let([], T::Array[T::Hash[Symbol, Symbol]]) + @completions_and_elisp = T.let(Set.new, T::Set[String]) @package_count = T.let(0, Integer) @install_times = T.let([], T::Array[T::Hash[String, Float]]) end @@ -25,6 +26,11 @@ class Messages @caveats.push(package:, caveats:) end + sig { params(completions_and_elisp: T::Array[String]).void } + def record_completions_and_elisp(completions_and_elisp) + @completions_and_elisp.merge(completions_and_elisp) + end + sig { params(package: String, elapsed_time: Float).void } def package_installed(package, elapsed_time) @package_count += 1 @@ -40,13 +46,14 @@ class Messages sig { params(force: T::Boolean).void } def display_caveats(force: false) return if @package_count.zero? - return if @package_count == 1 && !force - return if @caveats.empty? + return if @caveats.empty? && @completions_and_elisp.empty? - oh1 "Caveats" - @caveats.each do |c| - ohai c[:package], c[:caveats] - end + oh1 "Caveats" unless @completions_and_elisp.empty? + @completions_and_elisp.each { |c| puts c } + return if @package_count == 1 && !force + + oh1 "Caveats" if @completions_and_elisp.empty? + @caveats.each { |c| ohai c[:package], c[:caveats] } end sig { void } diff --git a/Library/Homebrew/sorbet/rbi/dsl/caveats.rbi b/Library/Homebrew/sorbet/rbi/dsl/caveats.rbi index dbe807aa31..e544438a19 100644 --- a/Library/Homebrew/sorbet/rbi/dsl/caveats.rbi +++ b/Library/Homebrew/sorbet/rbi/dsl/caveats.rbi @@ -6,9 +6,6 @@ class Caveats - sig { params(args: T.untyped, block: T.untyped).returns(T::Boolean) } - def empty?(*args, &block); end - sig { params(args: T.untyped, block: T.untyped).returns(String) } def to_s(*args, &block); end end diff --git a/Library/Homebrew/test/caveats_spec.rb b/Library/Homebrew/test/caveats_spec.rb index 7871177928..089c80c527 100644 --- a/Library/Homebrew/test/caveats_spec.rb +++ b/Library/Homebrew/test/caveats_spec.rb @@ -242,7 +242,7 @@ RSpec.describe Caveats do url "foo-1.0" end end - let(:caveats) { described_class.new(f).caveats } + let(:caveats) { described_class.new(f) } let(:path) { f.prefix.resolved_path } let(:bash_completion_dir) { path/"etc/bash_completion.d" } @@ -261,25 +261,25 @@ RSpec.describe Caveats do it "includes where Bash completions have been installed to" do bash_completion_dir.mkpath FileUtils.touch bash_completion_dir/f.name - expect(caveats).to include(HOMEBREW_PREFIX/"etc/bash_completion.d") + expect(caveats.completions_and_elisp.join).to include(HOMEBREW_PREFIX/"etc/bash_completion.d") end it "includes where fish completions have been installed to" do fish_vendor_completions.mkpath FileUtils.touch fish_vendor_completions/f.name - expect(caveats).to include(HOMEBREW_PREFIX/"share/fish/vendor_completions.d") + expect(caveats.completions_and_elisp.join).to include(HOMEBREW_PREFIX/"share/fish/vendor_completions.d") end it "includes where zsh completions have been installed to" do zsh_site_functions.mkpath FileUtils.touch zsh_site_functions/f.name - expect(caveats).to include(HOMEBREW_PREFIX/"share/zsh/site-functions") + expect(caveats.completions_and_elisp.join).to include(HOMEBREW_PREFIX/"share/zsh/site-functions") end it "includes where pwsh completions have been installed to" do pwsh_completion_dir.mkpath FileUtils.touch pwsh_completion_dir/f.name - expect(caveats).to include(HOMEBREW_PREFIX/"share/pwsh/completions") + expect(caveats.completions_and_elisp.join).to include(HOMEBREW_PREFIX/"share/pwsh/completions") end end end From cc03340af308b58c54b1f11a08d77d3df4a8b5ba Mon Sep 17 00:00:00 2001 From: Mike McQuaid Date: Mon, 9 Jun 2025 09:25:28 +0100 Subject: [PATCH 22/34] Reduce Homebrew/brew CI warnings - Remove a bunch of non-actionable/unnecessary noise in GitHub Actions CI. - Limit number of threads used to generate analytics API data to avoid reproducible failures producing errors and requiring retries. - Move to Debian Old Stable for testing non-system `glibc`. - Remove unneeded core taps/updates. - Improve naming of CI jobs to clarify purpose i.e. we're testing things work on Linux, not Ubuntu specifically. - Remove dedicated non-online/non-generic Linux `brew tests` jobs from 3 to 1. Co-authored-by: Rylan Polster --- .github/workflows/tests.yml | 63 +++++++++++++------ Library/Homebrew/cask/installer.rb | 2 +- .../dev-cmd/generate-analytics-api.rb | 39 +++++++++--- Library/Homebrew/dev-cmd/tests.rb | 11 ++-- Library/Homebrew/extend/kernel.rb | 11 ++++ Library/Homebrew/utils/backtrace.rb | 3 +- 6 files changed, 96 insertions(+), 33 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 5742f294cb..e92d390238 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -141,7 +141,7 @@ jobs: id: set-up-homebrew uses: Homebrew/actions/setup-homebrew@master with: - core: true + core: false cask: false test-bot: false @@ -164,7 +164,7 @@ jobs: id: set-up-homebrew uses: Homebrew/actions/setup-homebrew@master with: - core: true + core: false cask: true test-bot: false @@ -213,7 +213,7 @@ jobs: strategy: matrix: include: - - name: update-test (Ubuntu) + - name: update-test (Linux) runs-on: ubuntu-latest - name: update-test (macOS) runs-on: macos-15 @@ -237,7 +237,6 @@ jobs: name: ${{ matrix.name }} needs: syntax runs-on: ${{ matrix.runs-on }} - container: ${{ matrix.container }} strategy: matrix: include: @@ -247,17 +246,10 @@ jobs: - name: tests (generic OS) test-flags: --generic --coverage runs-on: ubuntu-latest - - name: tests (Ubuntu 24.04) + - name: tests (Linux) test-flags: --coverage runs-on: ubuntu-24.04 - - name: tests (Ubuntu 22.04) - test-flags: --coverage - runs-on: ubuntu-22.04 - - name: tests (Ubuntu 20.04) - test-flags: --coverage - runs-on: ubuntu-latest - container: ghcr.io/homebrew/ubuntu20.04:latest - - name: tests (macOS 15 arm64) + - name: tests (macOS) test-flags: --coverage runs-on: macos-15 steps: @@ -364,9 +356,10 @@ jobs: - name: test default formula (Ubuntu 22.04) runs-on: ubuntu-latest container: ghcr.io/homebrew/ubuntu22.04:master - - name: test default formula (Ubuntu 20.04) + # Need to keep this as a target that installs a Homebrew glibc + - name: test default formula (Debian Old Stable) runs-on: ubuntu-latest - container: ghcr.io/homebrew/ubuntu20.04:latest + container: debian:oldstable - name: test default formula (macOS 13 x86_64) runs-on: macos-13 - name: test default formula (macOS 15 arm64) @@ -375,18 +368,50 @@ jobs: HOMEBREW_TEST_BOT_ANALYTICS: 1 HOMEBREW_ENFORCE_SBOM: 1 steps: + - name: Install Homebrew and Homebrew's dependencies + # All other images are built from our Homebrew Dockerfile. + # This is the only one that needs to be set up manually. + if: matrix.container == 'debian:oldstable' + run: | + # Slimmed down version from the Homebrew Dockerfile + apt-get update + apt-get install -y --no-install-recommends \ + bzip2 \ + ca-certificates \ + curl \ + file \ + g++ \ + git-core \ + less \ + locales \ + make \ + netbase \ + patch \ + procps \ + sudo \ + uuid-runtime \ + tzdata + + # Install Homebrew + mkdir -p /home/linuxbrew/.linuxbrew/bin + # Don't do shallow clone or it's unshallowed by "Set up Homebrew" + git clone https://github.com/Homebrew/brew.git /home/linuxbrew/.linuxbrew/Homebrew + cd /home/linuxbrew/.linuxbrew/bin + ln -s ../Homebrew/bin/brew brew + echo "/home/linuxbrew/.linuxbrew/bin" >>"$GITHUB_PATH" + - name: Set up Homebrew id: set-up-homebrew uses: Homebrew/actions/setup-homebrew@master with: - core: true + core: false cask: false test-bot: true - run: brew test-bot --only-cleanup-before - name: Setup environment variables - if: matrix.container == 'ghcr.io/homebrew/ubuntu20.04:latest' + if: matrix.container == 'debian:oldstable' run: echo "HOMEBREW_GLIBC_TESTING=1" >> "$GITHUB_ENV" - run: brew test-bot --only-setup @@ -403,7 +428,7 @@ jobs: strategy: matrix: include: - - name: test brew bundle and brew services (Ubuntu) + - name: test brew bundle and brew services (Linux) runs-on: ubuntu-latest - name: test brew bundle and brew services (macOS) runs-on: macos-15 @@ -412,7 +437,7 @@ jobs: id: set-up-homebrew uses: Homebrew/actions/setup-homebrew@master with: - core: true + core: false cask: false test-bot: false diff --git a/Library/Homebrew/cask/installer.rb b/Library/Homebrew/cask/installer.rb index de73305989..dc9cb82f5e 100644 --- a/Library/Homebrew/cask/installer.rb +++ b/Library/Homebrew/cask/installer.rb @@ -149,7 +149,7 @@ module Cask oh1 "Installing Cask #{Formatter.identifier(@cask)}" # GitHub Actions globally disables Gatekeeper. - opoo "macOS's Gatekeeper has been disabled for this Cask" if !quarantine? && !GitHub::Actions.env_set? + opoo_outside_github_actions "macOS's Gatekeeper has been disabled for this Cask" unless quarantine? stage @cask.config = @cask.default_config.merge(old_config) diff --git a/Library/Homebrew/dev-cmd/generate-analytics-api.rb b/Library/Homebrew/dev-cmd/generate-analytics-api.rb index 3d3fe20ede..a07abe2694 100755 --- a/Library/Homebrew/dev-cmd/generate-analytics-api.rb +++ b/Library/Homebrew/dev-cmd/generate-analytics-api.rb @@ -77,7 +77,7 @@ module Homebrew analytics_data_dir = root_dir/"_data/analytics" analytics_api_dir = root_dir/"api/analytics" - threads = [] + analytics_output_queue = Queue.new CATEGORIES.each do |category| formula_analytics_args = [] @@ -124,15 +124,40 @@ module Homebrew DAYS.each do |days| next if days != "30" && category_name == "build-error" && !data_source.nil? - threads << Thread.new do - args = %W[--days-ago=#{days}] - (analytics_data_path/"#{days}d.json").write run_formula_analytics(*formula_analytics_args, *args) - (analytics_api_path/"#{days}d.json").write analytics_json_template(category_name, data_source:) - end + analytics_output_queue << { + formula_analytics_args: formula_analytics_args.dup, + days: days, + analytics_data_path: analytics_data_path, + analytics_api_path: analytics_api_path, + category_name: category_name, + data_source: data_source, + } end end - threads.each(&:join) + workers = [] + 4.times do + workers << Thread.new do + until analytics_output_queue.empty? + analytics_output_type = begin + analytics_output_queue.pop(true) + rescue ThreadError + break + end + + days = analytics_output_type[:days] + args = ["--days-ago=#{days}"] + + (analytics_output_type[:analytics_data_path]/"#{days}d.json").write \ + run_formula_analytics(*analytics_output_type[:formula_analytics_args], *args) + + data_source = analytics_output_type[:data_source] + (analytics_output_type[:analytics_api_path]/"#{days}d.json").write \ + analytics_json_template(analytics_output_type[:category_name], data_source:) + end + end + end + workers.each(&:join) end end end diff --git a/Library/Homebrew/dev-cmd/tests.rb b/Library/Homebrew/dev-cmd/tests.rb index 4df8acd792..c14a44b92b 100644 --- a/Library/Homebrew/dev-cmd/tests.rb +++ b/Library/Homebrew/dev-cmd/tests.rb @@ -125,11 +125,14 @@ module Homebrew # rubocop:disable Homebrew/MoveToExtendOS unless OS.mac? bundle_args << "--tag" << "~needs_macos" << "--tag" << "~cask" + bundle_args << "--tag" << "~needs_homebrew_core" if ENV["CI"] + bundle_args << "--tag" << "~needs_svn" unless args.online? + files = files.grep_v(%r{^test/(os/mac|cask)(/.*|_spec\.rb)$}) end unless OS.linux? - bundle_args << "--tag" << "~needs_linux" + bundle_args << "--tag" << "~needs_linux" << "--tag" << "~needs_systemd" files = files.grep_v(%r{^test/os/linux(/.*|_spec\.rb)$}) end # rubocop:enable Homebrew/MoveToExtendOS @@ -139,10 +142,8 @@ module Homebrew bundle_args << "--tag" << "~needs_intel" unless Hardware::CPU.intel? bundle_args << "--tag" << "~needs_network" unless args.online? - unless ENV["CI"] - bundle_args << "--tag" << "~needs_ci" \ - << "--tag" << "~needs_svn" - end + + bundle_args << "--tag" << "~needs_ci" unless ENV["CI"] puts "Randomized with seed #{seed}" diff --git a/Library/Homebrew/extend/kernel.rb b/Library/Homebrew/extend/kernel.rb index 56eb04b97d..abc1aaff79 100644 --- a/Library/Homebrew/extend/kernel.rb +++ b/Library/Homebrew/extend/kernel.rb @@ -82,6 +82,17 @@ module Kernel end end + # Print a warning message only if not running in GitHub Actions. + # + # @api public + sig { params(message: T.any(String, Exception)).void } + def opoo_outside_github_actions(message) + require "utils/github/actions" + return if GitHub::Actions.env_set? + + opoo(message) + end + # Print an error message. # # @api public diff --git a/Library/Homebrew/utils/backtrace.rb b/Library/Homebrew/utils/backtrace.rb index b04f349729..376e5fc5c9 100644 --- a/Library/Homebrew/utils/backtrace.rb +++ b/Library/Homebrew/utils/backtrace.rb @@ -31,7 +31,8 @@ module Utils def self.print_backtrace_message return if @print_backtrace_message - opoo "Removed Sorbet lines from backtrace!" + # This is just unactionable noise in GitHub Actions. + opoo_outside_github_actions "Removed Sorbet lines from backtrace!" puts "Rerun with `--verbose` to see the original backtrace" unless Homebrew::EnvConfig.no_env_hints? @print_backtrace_message = true From 63abe0bebf46e41dc81025789eb6538f3cc23871 Mon Sep 17 00:00:00 2001 From: Mike McQuaid Date: Mon, 9 Jun 2025 17:15:48 +0100 Subject: [PATCH 23/34] workflows/tests.yml: more CI tweaks. - use `macos-15` for tap syntax, no reason to use (old) `macos-14` - use `macos-latest` for all macOS jobs where we're only testing a single macOS and single Linux target - add `test default formula` jobs for Linux `arm64` - rename a few more jobs for consistency and clarity --- .github/workflows/tests.yml | 52 ++++++++++++++++++++++--------------- 1 file changed, 31 insertions(+), 21 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index e92d390238..5ee26c11ff 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -80,7 +80,7 @@ jobs: name: tap syntax needs: syntax if: github.repository_owner == 'Homebrew' - runs-on: macos-14 + runs-on: macos-15 steps: - name: Set up Homebrew id: set-up-homebrew @@ -216,7 +216,7 @@ jobs: - name: update-test (Linux) runs-on: ubuntu-latest - name: update-test (macOS) - runs-on: macos-15 + runs-on: macos-latest steps: - name: Set up Homebrew id: set-up-homebrew @@ -341,7 +341,7 @@ jobs: disable_search: true token: ${{ secrets.CODECOV_TOKEN }} - test-default-formula: + test-bot: name: ${{ matrix.name }} needs: syntax if: github.repository_owner == 'Homebrew' && github.event_name != 'push' @@ -350,19 +350,19 @@ jobs: strategy: matrix: include: - - name: test default formula (Ubuntu 24.04) - runs-on: ubuntu-latest + - name: test-bot (Linux arm64) + runs-on: ubuntu-24.04-arm container: ghcr.io/homebrew/ubuntu24.04:latest - - name: test default formula (Ubuntu 22.04) + - name: test-bot (Linux x86_64) runs-on: ubuntu-latest container: ghcr.io/homebrew/ubuntu22.04:master - # Need to keep this as a target that installs a Homebrew glibc - - name: test default formula (Debian Old Stable) + # Use Debian Old Stable for testing Homebrew's glibc support. + - name: test-bot (Linux Homebrew glibc) runs-on: ubuntu-latest container: debian:oldstable - - name: test default formula (macOS 13 x86_64) + - name: test-bot (macOS x86_64) runs-on: macos-13 - - name: test default formula (macOS 15 arm64) + - name: test-bot (macOS arm64) runs-on: macos-15 env: HOMEBREW_TEST_BOT_ANALYTICS: 1 @@ -411,8 +411,15 @@ jobs: - run: brew test-bot --only-cleanup-before - name: Setup environment variables - if: matrix.container == 'debian:oldstable' - run: echo "HOMEBREW_GLIBC_TESTING=1" >> "$GITHUB_ENV" + run: | + # Set enviroment variables to bypass `brew doctor` failures on Tier >=2 configurations + if [[ "${MATRIX_NAME}" == "test-bot (Linux arm64)" ]]; then + echo "HOMEBREW_ARM64_TESTING=1" >> "$GITHUB_ENV" + elif [[ "${MATRIX_NAME}" == "test-bot (Linux Homebrew glibc)" ]]; then + echo "HOMEBREW_GLIBC_TESTING=1" >> "$GITHUB_ENV" + fi + env: + MATRIX_NAME: ${{ matrix.name }} - run: brew test-bot --only-setup @@ -420,7 +427,7 @@ jobs: - run: brew test-bot --only-formulae --only-json-tab --test-default-formula - test-brew-bundle-services: + bundle-and-services: name: ${{ matrix.name }} needs: syntax if: github.repository_owner == 'Homebrew' && github.event_name != 'push' @@ -428,10 +435,10 @@ jobs: strategy: matrix: include: - - name: test brew bundle and brew services (Linux) + - name: bundle and services (Linux) runs-on: ubuntu-latest - - name: test brew bundle and brew services (macOS) - runs-on: macos-15 + - name: bundle and services (macOS) + runs-on: macos-latest steps: - name: Set up Homebrew id: set-up-homebrew @@ -474,13 +481,16 @@ jobs: brew services cleanup brew bundle cleanup --force - test-analytics: - runs-on: ${{ matrix.os }} + analytics: + name: ${{ matrix.name }} + runs-on: ${{ matrix.runs-on }} strategy: matrix: - os: - - ubuntu-latest - - macos-latest + include: + - name: analytics (Linux) + runs-on: ubuntu-latest + - name: analytics (macOS) + runs-on: macos-latest needs: syntax if: github.repository_owner == 'Homebrew' && github.event_name != 'push' steps: From dc71b7c8f6c16cd9a4d6a910326d9914101130a2 Mon Sep 17 00:00:00 2001 From: Mike McQuaid Date: Mon, 9 Jun 2025 19:06:16 +0100 Subject: [PATCH 24/34] Cleanup `extend/` directory usage. - move some things out of `extend` that don't really fit there e.g. `Module`s that are included but not doing any overriding/monkeypatching - move some code into `extend/os` to fix all remaining `rubocop:todo Homebrew/MoveToExtendOS`s - remove some unneeded `bundle` skipper code that doesn't really make sense given our current bottling strategy - extract some `Pathname` extensions to `extend/pathname` for separate files - move a `ENV` `Kernel` extension into `kernel.rb` - `odeprecate` a seemingly unused backwards compatibility method - move `readline_nonblock` from a monkeypatch to a `ReadlineNonblock.read` method as its only used in one place - fix up a link in documentation --- Library/Homebrew/api/cask.rb | 2 +- Library/Homebrew/api/formula.rb | 2 +- Library/Homebrew/{extend => }/api_hashable.rb | 0 Library/Homebrew/bundle.rb | 3 + Library/Homebrew/bundle/commands/exec.rb | 10 +- Library/Homebrew/bundle/skipper.rb | 13 -- Library/Homebrew/{extend => }/cachable.rb | 0 Library/Homebrew/cask/cask.rb | 2 +- Library/Homebrew/cask/dsl.rb | 2 +- Library/Homebrew/cask/dsl/base.rb | 2 +- Library/Homebrew/dependency_collector.rb | 2 +- Library/Homebrew/dev-cmd/bottle.rb | 30 +--- Library/Homebrew/dev-cmd/tests.rb | 60 ++++--- Library/Homebrew/extend/ENV.rb | 10 -- Library/Homebrew/extend/kernel.rb | 8 + Library/Homebrew/extend/os/dev-cmd/tests.rb | 5 + .../Homebrew/extend/os/linux/bundle/bundle.rb | 10 ++ .../Homebrew/extend/os/linux/dev-cmd/tests.rb | 23 +++ .../Homebrew/extend/os/mac/dev-cmd/bottle.rb | 20 +++ .../Homebrew/extend/os/mac/dev-cmd/tests.rb | 23 +++ Library/Homebrew/extend/os/mac/diagnostic.rb | 4 +- Library/Homebrew/extend/os/mac/readall.rb | 2 +- Library/Homebrew/extend/os/mac/tap.rb | 17 ++ Library/Homebrew/extend/os/tap.rb | 4 + Library/Homebrew/extend/pathname.rb | 163 +----------------- .../extend/pathname/disk_usage_extension.rb | 74 ++++++++ .../pathname/observer_pathname_extension.rb | 91 ++++++++++ Library/Homebrew/extend/time.rb | 6 +- Library/Homebrew/formula.rb | 4 +- Library/Homebrew/formulary.rb | 2 +- Library/Homebrew/global.rb | 2 +- Library/Homebrew/keg.rb | 2 +- Library/Homebrew/{extend => }/on_system.rb | 0 Library/Homebrew/{extend => }/on_system.rbi | 0 .../{extend/io.rb => readline_nonblock.rb} | 10 +- Library/Homebrew/resource.rb | 2 +- Library/Homebrew/sbom.rb | 2 +- Library/Homebrew/service.rb | 2 +- Library/Homebrew/software_spec.rb | 2 +- Library/Homebrew/system_command.rb | 4 +- Library/Homebrew/tab.rb | 2 +- Library/Homebrew/tap.rb | 15 +- Library/Homebrew/utils/analytics.rb | 2 +- docs/Typechecking.md | 2 +- 44 files changed, 368 insertions(+), 273 deletions(-) rename Library/Homebrew/{extend => }/api_hashable.rb (100%) rename Library/Homebrew/{extend => }/cachable.rb (100%) create mode 100644 Library/Homebrew/extend/os/dev-cmd/tests.rb create mode 100644 Library/Homebrew/extend/os/linux/dev-cmd/tests.rb create mode 100644 Library/Homebrew/extend/os/mac/dev-cmd/tests.rb create mode 100644 Library/Homebrew/extend/os/mac/tap.rb create mode 100644 Library/Homebrew/extend/os/tap.rb create mode 100644 Library/Homebrew/extend/pathname/disk_usage_extension.rb create mode 100644 Library/Homebrew/extend/pathname/observer_pathname_extension.rb rename Library/Homebrew/{extend => }/on_system.rb (100%) rename Library/Homebrew/{extend => }/on_system.rbi (100%) rename Library/Homebrew/{extend/io.rb => readline_nonblock.rb} (60%) diff --git a/Library/Homebrew/api/cask.rb b/Library/Homebrew/api/cask.rb index a06aa9b495..5de578f0ed 100644 --- a/Library/Homebrew/api/cask.rb +++ b/Library/Homebrew/api/cask.rb @@ -1,7 +1,7 @@ # typed: true # rubocop:todo Sorbet/StrictSigil # frozen_string_literal: true -require "extend/cachable" +require "cachable" require "api/download" module Homebrew diff --git a/Library/Homebrew/api/formula.rb b/Library/Homebrew/api/formula.rb index fe02c4bc08..5ef30a0f0a 100644 --- a/Library/Homebrew/api/formula.rb +++ b/Library/Homebrew/api/formula.rb @@ -1,7 +1,7 @@ # typed: strict # frozen_string_literal: true -require "extend/cachable" +require "cachable" require "api/download" module Homebrew diff --git a/Library/Homebrew/extend/api_hashable.rb b/Library/Homebrew/api_hashable.rb similarity index 100% rename from Library/Homebrew/extend/api_hashable.rb rename to Library/Homebrew/api_hashable.rb diff --git a/Library/Homebrew/bundle.rb b/Library/Homebrew/bundle.rb index e5676f1094..43f8de77a5 100644 --- a/Library/Homebrew/bundle.rb +++ b/Library/Homebrew/bundle.rb @@ -130,6 +130,9 @@ module Homebrew @formula_versions_from_env[formula_env_name] end + sig { void } + def prepend_pkgconf_path_if_needed!; end + sig { void } def reset! @mas_installed = T.let(nil, T.nilable(T::Boolean)) diff --git a/Library/Homebrew/bundle/commands/exec.rb b/Library/Homebrew/bundle/commands/exec.rb index d7babf8afc..588de100e2 100644 --- a/Library/Homebrew/bundle/commands/exec.rb +++ b/Library/Homebrew/bundle/commands/exec.rb @@ -64,14 +64,8 @@ module Homebrew ENV.prepend_path "PATH", Pathname.new(dep_root)/"shims" end - # Setup pkg-config, if present, to help locate packages - # Only need this on Linux as Homebrew provides a shim on macOS - # TODO: use extend/OS here - # rubocop:todo Homebrew/MoveToExtendOS - if OS.linux? && (pkgconf = Formulary.factory("pkgconf")) && pkgconf.any_version_installed? - ENV.prepend_path "PATH", pkgconf.opt_bin.to_s - end - # rubocop:enable Homebrew/MoveToExtendOS + # Setup pkgconf, if needed, to help locate packages + Bundle.prepend_pkgconf_path_if_needed! # For commands which aren't either absolute or relative # Add the command directory to PATH, since it may get blown away by superenv diff --git a/Library/Homebrew/bundle/skipper.rb b/Library/Homebrew/bundle/skipper.rb index f2788907a2..8c49f042b3 100644 --- a/Library/Homebrew/bundle/skipper.rb +++ b/Library/Homebrew/bundle/skipper.rb @@ -11,19 +11,6 @@ module Homebrew def skip?(entry, silent: false) require "bundle/brew_dumper" - # TODO: use extend/OS here - # rubocop:todo Homebrew/MoveToExtendOS - if (Hardware::CPU.arm? || OS.linux?) && - Homebrew.default_prefix? && - entry.type == :brew && entry.name.exclude?("/") && - (formula = BrewDumper.formulae_by_full_name(entry.name)) && - formula[:official_tap] && - !formula[:bottled] - reason = Hardware::CPU.arm? ? "Apple Silicon" : "Linux" - puts Formatter.warning "Skipping #{entry.name} (no bottle for #{reason})" unless silent - return true - end - # rubocop:enable Homebrew/MoveToExtendOS return true if @failed_taps&.any? do |tap| prefix = "#{tap}/" entry.name.start_with?(prefix) || entry.options[:full_name]&.start_with?(prefix) diff --git a/Library/Homebrew/extend/cachable.rb b/Library/Homebrew/cachable.rb similarity index 100% rename from Library/Homebrew/extend/cachable.rb rename to Library/Homebrew/cachable.rb diff --git a/Library/Homebrew/cask/cask.rb b/Library/Homebrew/cask/cask.rb index ec26010e90..b59b876072 100644 --- a/Library/Homebrew/cask/cask.rb +++ b/Library/Homebrew/cask/cask.rb @@ -8,7 +8,7 @@ require "cask/dsl" require "cask/metadata" require "cask/tab" require "utils/bottles" -require "extend/api_hashable" +require "api_hashable" module Cask # An instance of a cask. diff --git a/Library/Homebrew/cask/dsl.rb b/Library/Homebrew/cask/dsl.rb index ca35eebe39..2bd371b6e2 100644 --- a/Library/Homebrew/cask/dsl.rb +++ b/Library/Homebrew/cask/dsl.rb @@ -26,7 +26,7 @@ require "cask/dsl/version" require "cask/url" require "cask/utils" -require "extend/on_system" +require "on_system" module Cask # Class representing the domain-specific language used for casks. diff --git a/Library/Homebrew/cask/dsl/base.rb b/Library/Homebrew/cask/dsl/base.rb index 900889a59e..e9932dae84 100644 --- a/Library/Homebrew/cask/dsl/base.rb +++ b/Library/Homebrew/cask/dsl/base.rb @@ -2,7 +2,7 @@ # frozen_string_literal: true require "cask/utils" -require "extend/on_system" +require "on_system" module Cask class DSL diff --git a/Library/Homebrew/dependency_collector.rb b/Library/Homebrew/dependency_collector.rb index 6420504515..cddae5fcdc 100644 --- a/Library/Homebrew/dependency_collector.rb +++ b/Library/Homebrew/dependency_collector.rb @@ -5,7 +5,7 @@ require "dependency" require "dependencies" require "requirement" require "requirements" -require "extend/cachable" +require "cachable" # A dependency is a formula that another formula needs to install. # A requirement is something other than a formula that another formula diff --git a/Library/Homebrew/dev-cmd/bottle.rb b/Library/Homebrew/dev-cmd/bottle.rb index 04307077bc..cb69bb464c 100644 --- a/Library/Homebrew/dev-cmd/bottle.rb +++ b/Library/Homebrew/dev-cmd/bottle.rb @@ -227,7 +227,7 @@ module Homebrew private sig { - params(string: String, keg: Keg, ignores: T::Array[String], + params(string: String, keg: Keg, ignores: T::Array[Regexp], formula_and_runtime_deps_names: T.nilable(T::Array[String])).returns(T::Boolean) } def keg_contain?(string, keg, ignores, formula_and_runtime_deps_names = nil) @@ -373,35 +373,17 @@ module Homebrew [gnu_tar(gnu_tar_formula), reproducible_gnutar_args(mtime)].freeze end - sig { params(formula: T.untyped).returns(T::Array[T.untyped]) } + sig { params(formula: Formula).returns(T::Array[Regexp]) } def formula_ignores(formula) - ignores = [] - cellar_regex = Regexp.escape(HOMEBREW_CELLAR) - prefix_regex = Regexp.escape(HOMEBREW_PREFIX) - # Ignore matches to go keg, because all go binaries are statically linked. any_go_deps = formula.deps.any? do |dep| Version.formula_optionally_versioned_regex(:go).match?(dep.name) end - if any_go_deps - go_regex = Version.formula_optionally_versioned_regex(:go, full: false) - ignores << %r{#{cellar_regex}/#{go_regex}/[\d.]+/libexec} - end + return [] unless any_go_deps - # TODO: Refactor and move to extend/os - # rubocop:disable Homebrew/MoveToExtendOS - ignores << case formula.name - # On Linux, GCC installation can be moved so long as the whole directory tree is moved together: - # https://gcc-help.gcc.gnu.narkive.com/GnwuCA7l/moving-gcc-from-the-installation-path-is-it-allowed. - when Version.formula_optionally_versioned_regex(:gcc) - Regexp.union(%r{#{cellar_regex}/gcc}, %r{#{prefix_regex}/opt/gcc}) if OS.linux? - # binutils is relocatable for the same reason: https://github.com/Homebrew/brew/pull/11899#issuecomment-906804451. - when Version.formula_optionally_versioned_regex(:binutils) - %r{#{cellar_regex}/binutils} if OS.linux? - end - # rubocop:enable Homebrew/MoveToExtendOS - - ignores.compact + cellar_regex = Regexp.escape(HOMEBREW_CELLAR) + go_regex = Version.formula_optionally_versioned_regex(:go, full: false) + Array(%r{#{cellar_regex}/#{go_regex}/[\d.]+/libexec}) end sig { params(formula: Formula).void } diff --git a/Library/Homebrew/dev-cmd/tests.rb b/Library/Homebrew/dev-cmd/tests.rb index c14a44b92b..450098d268 100644 --- a/Library/Homebrew/dev-cmd/tests.rb +++ b/Library/Homebrew/dev-cmd/tests.rb @@ -120,31 +120,14 @@ module Homebrew ] bundle_args << "--fail-fast" if args.fail_fast? bundle_args << "--profile" << args.profile if args.profile - - # TODO: Refactor and move to extend/os - # rubocop:disable Homebrew/MoveToExtendOS - unless OS.mac? - bundle_args << "--tag" << "~needs_macos" << "--tag" << "~cask" - bundle_args << "--tag" << "~needs_homebrew_core" if ENV["CI"] - bundle_args << "--tag" << "~needs_svn" unless args.online? - - files = files.grep_v(%r{^test/(os/mac|cask)(/.*|_spec\.rb)$}) - end - - unless OS.linux? - bundle_args << "--tag" << "~needs_linux" << "--tag" << "~needs_systemd" - files = files.grep_v(%r{^test/os/linux(/.*|_spec\.rb)$}) - end - # rubocop:enable Homebrew/MoveToExtendOS - bundle_args << "--tag" << "~needs_arm" unless Hardware::CPU.arm? - bundle_args << "--tag" << "~needs_intel" unless Hardware::CPU.intel? - bundle_args << "--tag" << "~needs_network" unless args.online? - bundle_args << "--tag" << "~needs_ci" unless ENV["CI"] + bundle_args = os_bundle_args(bundle_args) + files = os_files(files) + puts "Randomized with seed #{seed}" ENV["HOMEBREW_DEBUG"] = "1" if args.debug? # Used in spec_helper.rb to require the "debug" gem. @@ -171,6 +154,41 @@ module Homebrew private + sig { params(bundle_args: T::Array[String]).returns(T::Array[String]) } + def os_bundle_args(bundle_args) + # for generic tests, remove macOS or Linux specific tests + non_linux_bundle_args(non_macos_bundle_args(bundle_args)) + end + + sig { params(bundle_args: T::Array[String]).returns(T::Array[String]) } + def non_macos_bundle_args(bundle_args) + bundle_args << "--tag" << "~needs_homebrew_core" if ENV["CI"] + bundle_args << "--tag" << "~needs_svn" unless args.online? + + bundle_args << "--tag" << "~needs_macos" << "--tag" << "~cask" + end + + sig { params(bundle_args: T::Array[String]).returns(T::Array[String]) } + def non_linux_bundle_args(bundle_args) + bundle_args << "--tag" << "~needs_linux" << "--tag" << "~needs_systemd" + end + + sig { params(files: T::Array[String]).returns(T::Array[String]) } + def os_files(files) + # for generic tests, remove macOS or Linux specific files + non_linux_files(non_macos_files(files)) + end + + sig { params(files: T::Array[String]).returns(T::Array[String]) } + def non_macos_files(files) + files.grep_v(%r{^test/(os/mac|cask)(/.*|_spec\.rb)$}) + end + + sig { params(files: T::Array[String]).returns(T::Array[String]) } + def non_linux_files(files) + files.grep_v(%r{^test/os/linux(/.*|_spec\.rb)$}) + end + sig { returns(T::Array[String]) } def changed_test_files changed_files = Utils.popen_read("git", "diff", "--name-only", "master") @@ -250,3 +268,5 @@ module Homebrew end end end + +require "extend/os/dev-cmd/tests" diff --git a/Library/Homebrew/extend/ENV.rb b/Library/Homebrew/extend/ENV.rb index b7a9afb644..4a449993f7 100644 --- a/Library/Homebrew/extend/ENV.rb +++ b/Library/Homebrew/extend/ENV.rb @@ -7,16 +7,6 @@ require "extend/ENV/shared" require "extend/ENV/std" require "extend/ENV/super" -module Kernel - sig { params(env: T.nilable(String)).returns(T::Boolean) } - def superenv?(env) - return false if env == "std" - - !Superenv.bin.nil? - end - private :superenv? -end - # # @!parse # # `ENV` is not actually a class, but this makes YARD happy diff --git a/Library/Homebrew/extend/kernel.rb b/Library/Homebrew/extend/kernel.rb index abc1aaff79..948c0b3fba 100644 --- a/Library/Homebrew/extend/kernel.rb +++ b/Library/Homebrew/extend/kernel.rb @@ -5,6 +5,14 @@ # TODO: move these out of `Kernel`. module Kernel + sig { params(env: T.nilable(String)).returns(T::Boolean) } + def superenv?(env) + return false if env == "std" + + !Superenv.bin.nil? + end + private :superenv? + def require?(path) return false if path.nil? diff --git a/Library/Homebrew/extend/os/dev-cmd/tests.rb b/Library/Homebrew/extend/os/dev-cmd/tests.rb new file mode 100644 index 0000000000..556052a63f --- /dev/null +++ b/Library/Homebrew/extend/os/dev-cmd/tests.rb @@ -0,0 +1,5 @@ +# typed: strict +# frozen_string_literal: true + +require "extend/os/linux/dev-cmd/tests" if OS.linux? +require "extend/os/mac/dev-cmd/tests" if OS.mac? diff --git a/Library/Homebrew/extend/os/linux/bundle/bundle.rb b/Library/Homebrew/extend/os/linux/bundle/bundle.rb index 71c2e41625..1acbb70541 100644 --- a/Library/Homebrew/extend/os/linux/bundle/bundle.rb +++ b/Library/Homebrew/extend/os/linux/bundle/bundle.rb @@ -9,6 +9,16 @@ module OS def mas_installed? false end + + # Setup pkg-config, if present, to help locate packages + # Only need this on Linux as Homebrew provides a shim on macOS + sig { void } + def prepend_pkgconf_path_if_needed! + pkgconf = Formulary.factory("pkgconf") + return unless pkgconf.any_version_installed? + + ENV.prepend_path "PATH", pkgconf.opt_bin.to_s + end end end end diff --git a/Library/Homebrew/extend/os/linux/dev-cmd/tests.rb b/Library/Homebrew/extend/os/linux/dev-cmd/tests.rb new file mode 100644 index 0000000000..e7f3d30d65 --- /dev/null +++ b/Library/Homebrew/extend/os/linux/dev-cmd/tests.rb @@ -0,0 +1,23 @@ +# typed: strict +# frozen_string_literal: true + +module OS + module Linux + module DevCmd + module Tests + extend T::Helpers + + requires_ancestor { Homebrew::DevCmd::Tests } + + private + + sig { params(bundle_args: T::Array[String]).returns(T::Array[String]) } + def os_bundle_args(bundle_args) + non_macos_bundle_args(bundle_args) + end + end + end + end +end + +Homebrew::DevCmd::Tests.prepend(OS::Linux::DevCmd::Tests) diff --git a/Library/Homebrew/extend/os/mac/dev-cmd/bottle.rb b/Library/Homebrew/extend/os/mac/dev-cmd/bottle.rb index 9d07b43695..e75eeab739 100644 --- a/Library/Homebrew/extend/os/mac/dev-cmd/bottle.rb +++ b/Library/Homebrew/extend/os/mac/dev-cmd/bottle.rb @@ -18,6 +18,26 @@ module OS def gnu_tar(gnu_tar_formula) "#{gnu_tar_formula.opt_bin}/gtar" end + + sig { params(formula: Formula).returns(T::Array[Regexp]) } + def formula_ignores(formula) + ignores = super + + cellar_regex = Regexp.escape(HOMEBREW_CELLAR) + prefix_regex = Regexp.escape(HOMEBREW_PREFIX) + + ignores << case formula.name + # On Linux, GCC installation can be moved so long as the whole directory tree is moved together: + # https://gcc-help.gcc.gnu.narkive.com/GnwuCA7l/moving-gcc-from-the-installation-path-is-it-allowed. + when Version.formula_optionally_versioned_regex(:gcc) + Regexp.union(%r{#{cellar_regex}/gcc}, %r{#{prefix_regex}/opt/gcc}) if OS.linux? + # binutils is relocatable for the same reason: https://github.com/Homebrew/brew/pull/11899#issuecomment-906804451. + when Version.formula_optionally_versioned_regex(:binutils) + %r{#{cellar_regex}/binutils} if OS.linux? + end + + ignores.compact + end end end end diff --git a/Library/Homebrew/extend/os/mac/dev-cmd/tests.rb b/Library/Homebrew/extend/os/mac/dev-cmd/tests.rb new file mode 100644 index 0000000000..112ad3b6c8 --- /dev/null +++ b/Library/Homebrew/extend/os/mac/dev-cmd/tests.rb @@ -0,0 +1,23 @@ +# typed: strict +# frozen_string_literal: true + +module OS + module Mac + module DevCmd + module Tests + extend T::Helpers + + requires_ancestor { Homebrew::DevCmd::Tests } + + private + + sig { params(bundle_args: T::Array[String]).returns(T::Array[String]) } + def os_bundle_args(bundle_args) + non_linux_bundle_args(bundle_args) + end + end + end + end +end + +Homebrew::DevCmd::Tests.prepend(OS::Mac::DevCmd::Tests) diff --git a/Library/Homebrew/extend/os/mac/diagnostic.rb b/Library/Homebrew/extend/os/mac/diagnostic.rb index 311b68167e..c3d92eb374 100644 --- a/Library/Homebrew/extend/os/mac/diagnostic.rb +++ b/Library/Homebrew/extend/os/mac/diagnostic.rb @@ -425,8 +425,8 @@ module OS end def check_deprecated_caskroom_taps - tapped_caskroom_taps = Tap.select { |t| t.user == "caskroom" || t.name == "phinze/cask" } - .map(&:name) + tapped_caskroom_taps = ::Tap.select { |t| t.user == "caskroom" || t.name == "phinze/cask" } + .map(&:name) return if tapped_caskroom_taps.empty? <<~EOS diff --git a/Library/Homebrew/extend/os/mac/readall.rb b/Library/Homebrew/extend/os/mac/readall.rb index 23f71e403c..90e89c17d5 100644 --- a/Library/Homebrew/extend/os/mac/readall.rb +++ b/Library/Homebrew/extend/os/mac/readall.rb @@ -8,7 +8,7 @@ module OS requires_ancestor { Kernel } - sig { params(tap: Tap, os_name: T.nilable(Symbol), arch: T.nilable(Symbol)).returns(T::Boolean) } + sig { params(tap: ::Tap, os_name: T.nilable(Symbol), arch: T.nilable(Symbol)).returns(T::Boolean) } def valid_casks?(tap, os_name: nil, arch: ::Hardware::CPU.type) return true if os_name == :linux diff --git a/Library/Homebrew/extend/os/mac/tap.rb b/Library/Homebrew/extend/os/mac/tap.rb new file mode 100644 index 0000000000..2213a4f757 --- /dev/null +++ b/Library/Homebrew/extend/os/mac/tap.rb @@ -0,0 +1,17 @@ +# typed: strict +# frozen_string_literal: true + +module OS + module Mac + module Tap + module ClassMethods + sig { returns(T::Array[::Tap]) } + def core_taps + [CoreTap.instance, CoreCaskTap.instance].freeze + end + end + end + end +end + +Tap.singleton_class.prepend(OS::Mac::Tap::ClassMethods) diff --git a/Library/Homebrew/extend/os/tap.rb b/Library/Homebrew/extend/os/tap.rb new file mode 100644 index 0000000000..e6662ff704 --- /dev/null +++ b/Library/Homebrew/extend/os/tap.rb @@ -0,0 +1,4 @@ +# typed: strict +# frozen_string_literal: true + +require "extend/os/mac/tap" if OS.mac? diff --git a/Library/Homebrew/extend/pathname.rb b/Library/Homebrew/extend/pathname.rb index 91337f81d1..2e28057a2c 100644 --- a/Library/Homebrew/extend/pathname.rb +++ b/Library/Homebrew/extend/pathname.rb @@ -1,79 +1,9 @@ # typed: true # rubocop:todo Sorbet/StrictSigil # frozen_string_literal: true -module DiskUsageExtension - extend T::Helpers - - requires_ancestor { Pathname } - - sig { returns(Integer) } - def disk_usage - return @disk_usage if defined?(@disk_usage) - - compute_disk_usage - @disk_usage - end - - sig { returns(Integer) } - def file_count - return @file_count if defined?(@file_count) - - compute_disk_usage - @file_count - end - - sig { returns(String) } - def abv - out = +"" - compute_disk_usage - out << "#{number_readable(@file_count)} files, " if @file_count > 1 - out << disk_usage_readable(@disk_usage).to_s - out.freeze - end - - private - - sig { void } - def compute_disk_usage - if symlink? && !exist? - @file_count = 1 - @disk_usage = 0 - return - end - - path = if symlink? - resolved_path - else - self - end - - if path.directory? - scanned_files = Set.new - @file_count = 0 - @disk_usage = 0 - path.find do |f| - if f.directory? - @disk_usage += f.lstat.size - else - @file_count += 1 if f.basename.to_s != ".DS_Store" - # use Pathname#lstat instead of Pathname#stat to get info of symlink itself. - stat = f.lstat - file_id = [stat.dev, stat.ino] - # count hardlinks only once. - unless scanned_files.include?(file_id) - @disk_usage += stat.size - scanned_files.add(file_id) - end - end - end - else - @file_count = 1 - @disk_usage = path.lstat.size - end - end -end - require "system_command" +require "extend/pathname/disk_usage_extension" +require "extend/pathname/observer_pathname_extension" # Homebrew extends Ruby's `Pathname` to make our code more readable. # @see https://ruby-doc.org/stdlib-2.6.3/libdoc/pathname/rdoc/Pathname.html Ruby's Pathname API @@ -524,92 +454,3 @@ class Pathname end end require "extend/os/pathname" - -require "context" - -module ObserverPathnameExtension - extend T::Helpers - - requires_ancestor { Pathname } - - class << self - include Context - - sig { returns(Integer) } - attr_accessor :n, :d - - sig { void } - def reset_counts! - @n = @d = 0 - @put_verbose_trimmed_warning = false - end - - sig { returns(Integer) } - def total - n + d - end - - sig { returns([Integer, Integer]) } - def counts - [n, d] - end - - MAXIMUM_VERBOSE_OUTPUT = 100 - private_constant :MAXIMUM_VERBOSE_OUTPUT - - sig { returns(T::Boolean) } - def verbose? - return super unless ENV["CI"] - return false unless super - - if total < MAXIMUM_VERBOSE_OUTPUT - true - else - unless @put_verbose_trimmed_warning - puts "Only the first #{MAXIMUM_VERBOSE_OUTPUT} operations were output." - @put_verbose_trimmed_warning = true - end - false - end - end - end - - sig { void } - def unlink - super - puts "rm #{self}" if ObserverPathnameExtension.verbose? - ObserverPathnameExtension.n += 1 - end - - sig { void } - def mkpath - super - puts "mkdir -p #{self}" if ObserverPathnameExtension.verbose? - end - - sig { void } - def rmdir - super - puts "rmdir #{self}" if ObserverPathnameExtension.verbose? - ObserverPathnameExtension.d += 1 - end - - sig { params(src: Pathname).void } - def make_relative_symlink(src) - super - puts "ln -s #{src.relative_path_from(dirname)} #{basename}" if ObserverPathnameExtension.verbose? - ObserverPathnameExtension.n += 1 - end - - sig { void } - def install_info - super - puts "info #{self}" if ObserverPathnameExtension.verbose? - end - - sig { void } - def uninstall_info - super - puts "uninfo #{self}" if ObserverPathnameExtension.verbose? - end -end diff --git a/Library/Homebrew/extend/pathname/disk_usage_extension.rb b/Library/Homebrew/extend/pathname/disk_usage_extension.rb new file mode 100644 index 0000000000..4781ebfeb5 --- /dev/null +++ b/Library/Homebrew/extend/pathname/disk_usage_extension.rb @@ -0,0 +1,74 @@ +# typed: true # rubocop:todo Sorbet/StrictSigil +# frozen_string_literal: true + +module DiskUsageExtension + extend T::Helpers + + requires_ancestor { Pathname } + + sig { returns(Integer) } + def disk_usage + return @disk_usage if defined?(@disk_usage) + + compute_disk_usage + @disk_usage + end + + sig { returns(Integer) } + def file_count + return @file_count if defined?(@file_count) + + compute_disk_usage + @file_count + end + + sig { returns(String) } + def abv + out = +"" + compute_disk_usage + out << "#{number_readable(@file_count)} files, " if @file_count > 1 + out << disk_usage_readable(@disk_usage).to_s + out.freeze + end + + private + + sig { void } + def compute_disk_usage + if symlink? && !exist? + @file_count = 1 + @disk_usage = 0 + return + end + + path = if symlink? + resolved_path + else + self + end + + if path.directory? + scanned_files = Set.new + @file_count = 0 + @disk_usage = 0 + path.find do |f| + if f.directory? + @disk_usage += f.lstat.size + else + @file_count += 1 if f.basename.to_s != ".DS_Store" + # use Pathname#lstat instead of Pathname#stat to get info of symlink itself. + stat = f.lstat + file_id = [stat.dev, stat.ino] + # count hardlinks only once. + unless scanned_files.include?(file_id) + @disk_usage += stat.size + scanned_files.add(file_id) + end + end + end + else + @file_count = 1 + @disk_usage = path.lstat.size + end + end +end diff --git a/Library/Homebrew/extend/pathname/observer_pathname_extension.rb b/Library/Homebrew/extend/pathname/observer_pathname_extension.rb new file mode 100644 index 0000000000..2ef2035cb7 --- /dev/null +++ b/Library/Homebrew/extend/pathname/observer_pathname_extension.rb @@ -0,0 +1,91 @@ +# typed: true # rubocop:todo Sorbet/StrictSigil +# frozen_string_literal: true + +require "context" + +module ObserverPathnameExtension + extend T::Helpers + + requires_ancestor { Pathname } + + class << self + include Context + + sig { returns(Integer) } + attr_accessor :n, :d + + sig { void } + def reset_counts! + @n = @d = 0 + @put_verbose_trimmed_warning = false + end + + sig { returns(Integer) } + def total + n + d + end + + sig { returns([Integer, Integer]) } + def counts + [n, d] + end + + MAXIMUM_VERBOSE_OUTPUT = 100 + private_constant :MAXIMUM_VERBOSE_OUTPUT + + sig { returns(T::Boolean) } + def verbose? + return super unless ENV["CI"] + return false unless super + + if total < MAXIMUM_VERBOSE_OUTPUT + true + else + unless @put_verbose_trimmed_warning + puts "Only the first #{MAXIMUM_VERBOSE_OUTPUT} operations were output." + @put_verbose_trimmed_warning = true + end + false + end + end + end + + sig { void } + def unlink + super + puts "rm #{self}" if ObserverPathnameExtension.verbose? + ObserverPathnameExtension.n += 1 + end + + sig { void } + def mkpath + super + puts "mkdir -p #{self}" if ObserverPathnameExtension.verbose? + end + + sig { void } + def rmdir + super + puts "rmdir #{self}" if ObserverPathnameExtension.verbose? + ObserverPathnameExtension.d += 1 + end + + sig { params(src: Pathname).void } + def make_relative_symlink(src) + super + puts "ln -s #{src.relative_path_from(dirname)} #{basename}" if ObserverPathnameExtension.verbose? + ObserverPathnameExtension.n += 1 + end + + sig { void } + def install_info + super + puts "info #{self}" if ObserverPathnameExtension.verbose? + end + + sig { void } + def uninstall_info + super + puts "uninfo #{self}" if ObserverPathnameExtension.verbose? + end +end diff --git a/Library/Homebrew/extend/time.rb b/Library/Homebrew/extend/time.rb index 75a79b864b..2d266db5ff 100644 --- a/Library/Homebrew/extend/time.rb +++ b/Library/Homebrew/extend/time.rb @@ -5,5 +5,9 @@ require "time" class Time # Backwards compatibility for formulae that used this ActiveSupport extension - alias rfc3339 xmlschema + sig { returns(String) } + def rfc3339 + odeprecated "Time#rfc3339", "Time#xmlschema" + xmlschema + end end diff --git a/Library/Homebrew/formula.rb b/Library/Homebrew/formula.rb index 740e258a32..bf570f6c1e 100644 --- a/Library/Homebrew/formula.rb +++ b/Library/Homebrew/formula.rb @@ -38,9 +38,9 @@ require "tab" require "mktemp" require "find" require "utils/spdx" -require "extend/on_system" +require "on_system" require "api" -require "extend/api_hashable" +require "api_hashable" # A formula provides instructions and metadata for Homebrew to install a piece # of software. Every Homebrew formula is a {Formula}. diff --git a/Library/Homebrew/formulary.rb b/Library/Homebrew/formulary.rb index 2f191fb787..5a48b25d8b 100644 --- a/Library/Homebrew/formulary.rb +++ b/Library/Homebrew/formulary.rb @@ -2,7 +2,7 @@ # frozen_string_literal: true require "digest/sha2" -require "extend/cachable" +require "cachable" require "tab" require "utils" require "utils/bottles" diff --git a/Library/Homebrew/global.rb b/Library/Homebrew/global.rb index ee4f5fa916..ff9d0f79b3 100644 --- a/Library/Homebrew/global.rb +++ b/Library/Homebrew/global.rb @@ -138,7 +138,7 @@ require "extend/kernel" require "os" require "extend/array" -require "extend/cachable" +require "cachable" require "extend/enumerable" require "extend/string" require "extend/pathname" diff --git a/Library/Homebrew/keg.rb b/Library/Homebrew/keg.rb index 40f96d48ba..275cc8fed0 100644 --- a/Library/Homebrew/keg.rb +++ b/Library/Homebrew/keg.rb @@ -4,7 +4,7 @@ require "keg_relocate" require "language/python" require "lock_file" -require "extend/cachable" +require "cachable" # Installation prefix of a formula. class Keg diff --git a/Library/Homebrew/extend/on_system.rb b/Library/Homebrew/on_system.rb similarity index 100% rename from Library/Homebrew/extend/on_system.rb rename to Library/Homebrew/on_system.rb diff --git a/Library/Homebrew/extend/on_system.rbi b/Library/Homebrew/on_system.rbi similarity index 100% rename from Library/Homebrew/extend/on_system.rbi rename to Library/Homebrew/on_system.rbi diff --git a/Library/Homebrew/extend/io.rb b/Library/Homebrew/readline_nonblock.rb similarity index 60% rename from Library/Homebrew/extend/io.rb rename to Library/Homebrew/readline_nonblock.rb index a6eb7d4b70..7888b46399 100644 --- a/Library/Homebrew/extend/io.rb +++ b/Library/Homebrew/readline_nonblock.rb @@ -1,17 +1,17 @@ # typed: strict # frozen_string_literal: true -class IO - sig { params(sep: String).returns(String) } - def readline_nonblock(sep = $INPUT_RECORD_SEPARATOR) +class ReadlineNonblock + sig { params(io: IO).returns(String) } + def self.read(io) line = +"" buffer = +"" begin loop do - break if buffer == sep + break if buffer == $INPUT_RECORD_SEPARATOR - read_nonblock(1, buffer) + io.read_nonblock(1, buffer) line.concat(buffer) end diff --git a/Library/Homebrew/resource.rb b/Library/Homebrew/resource.rb index 2b37c2ec43..a774f659df 100644 --- a/Library/Homebrew/resource.rb +++ b/Library/Homebrew/resource.rb @@ -4,7 +4,7 @@ require "downloadable" require "mktemp" require "livecheck" -require "extend/on_system" +require "on_system" # Resource is the fundamental representation of an external resource. The # primary formula download, along with other declared resources, are instances diff --git a/Library/Homebrew/sbom.rb b/Library/Homebrew/sbom.rb index 8873cdf751..4df1d7e815 100644 --- a/Library/Homebrew/sbom.rb +++ b/Library/Homebrew/sbom.rb @@ -4,7 +4,7 @@ require "cxxstdlib" require "json" require "development_tools" -require "extend/cachable" +require "cachable" require "utils/curl" # Rather than calling `new` directly, use one of the class methods like {SBOM.create}. diff --git a/Library/Homebrew/service.rb b/Library/Homebrew/service.rb index 2ae807da14..b52c1bb083 100644 --- a/Library/Homebrew/service.rb +++ b/Library/Homebrew/service.rb @@ -2,7 +2,7 @@ # frozen_string_literal: true require "ipaddr" -require "extend/on_system" +require "on_system" require "utils/service" module Homebrew diff --git a/Library/Homebrew/software_spec.rb b/Library/Homebrew/software_spec.rb index 7463429257..a6172182cb 100644 --- a/Library/Homebrew/software_spec.rb +++ b/Library/Homebrew/software_spec.rb @@ -12,7 +12,7 @@ require "utils/bottles" require "patch" require "compilers" require "macos_version" -require "extend/on_system" +require "on_system" class SoftwareSpec include Downloadable diff --git a/Library/Homebrew/system_command.rb b/Library/Homebrew/system_command.rb index 737eea4322..b70e2d7583 100644 --- a/Library/Homebrew/system_command.rb +++ b/Library/Homebrew/system_command.rb @@ -6,7 +6,7 @@ require "shellwords" require "uri" require "context" -require "extend/io" +require "readline_nonblock" require "utils/timer" # Class for running sub-processes and capturing their output and exit status. @@ -361,7 +361,7 @@ class SystemCommand readable_sources.each do |source| loop do - line = source.readline_nonblock || "" + line = ReadlineNonblock.read(source) yield(sources.fetch(source), line) end rescue EOFError diff --git a/Library/Homebrew/tab.rb b/Library/Homebrew/tab.rb index 70f7118234..dc57bb4d20 100644 --- a/Library/Homebrew/tab.rb +++ b/Library/Homebrew/tab.rb @@ -5,7 +5,7 @@ require "cxxstdlib" require "options" require "json" require "development_tools" -require "extend/cachable" +require "cachable" # Rather than calling `new` directly, use one of the class methods like {Tab.create}. class AbstractTab diff --git a/Library/Homebrew/tap.rb b/Library/Homebrew/tap.rb index bf83e7ee29..545d91cd76 100644 --- a/Library/Homebrew/tap.rb +++ b/Library/Homebrew/tap.rb @@ -1079,15 +1079,12 @@ class Tap # All locally installed and core taps. Core taps might not be installed locally when using the API. sig { returns(T::Array[Tap]) } def self.all - cache[:all] ||= begin - core_taps = [ - CoreTap.instance, - # The conditional is valid here because we only want the cask tap on macOS. - (CoreCaskTap.instance if OS.mac?), # rubocop:disable Homebrew/MoveToExtendOS - ].compact + cache[:all] ||= installed | core_taps + end - installed | core_taps - end + sig { returns(T::Array[Tap]) } + def self.core_taps + [CoreTap.instance].freeze end # Enumerate all available {Tap}s. @@ -1517,3 +1514,5 @@ class TapConfig Homebrew::Settings.delete key, repo: tap.path end end + +require "extend/os/tap" diff --git a/Library/Homebrew/utils/analytics.rb b/Library/Homebrew/utils/analytics.rb index 54674b019f..003290f824 100644 --- a/Library/Homebrew/utils/analytics.rb +++ b/Library/Homebrew/utils/analytics.rb @@ -4,7 +4,7 @@ require "context" require "erb" require "settings" -require "extend/cachable" +require "cachable" module Utils # Helper module for fetching and reporting analytics data. diff --git a/docs/Typechecking.md b/docs/Typechecking.md index 216b79f396..ea291945a8 100644 --- a/docs/Typechecking.md +++ b/docs/Typechecking.md @@ -34,7 +34,7 @@ For more information on how to express more complex types, refer to the official ### Ruby interface files (`.rbi`) -[RBI files](https://sorbet.org/docs/rbi) help Sorbet learn about constants, ancestors and methods defined in ways it doesn't understand natively. We can also create an RBI file to help Sorbet understand dynamic definitions. Some of these files are automatically generated (see the next section) and some are manually written, e.g. [`extend/on_system.rbi`](https://github.com/Homebrew/brew/blob/975fe8a83fd57a8d8e790ec6fb10c2f13f705d02/Library/Homebrew/extend/on_system.rbi). +[RBI files](https://sorbet.org/docs/rbi) help Sorbet learn about constants, ancestors and methods defined in ways it doesn't understand natively. We can also create an RBI file to help Sorbet understand dynamic definitions. Some of these files are automatically generated (see the next section) and some are manually written, e.g. [`on_system.rbi`](https://github.com/Homebrew/brew/blob/HEAD/Library/Homebrew/on_system.rbi). There are also a very small number of files that Homebrew loads before `sorbet-runtime`, such as `utils/gems.rb`. Those files cannot have type signatures alongside the code itself, so RBI files are used there instead to retain static type checking. From 57ed94c4218e2a3dddc7eee4982d95dfec9ad7f4 Mon Sep 17 00:00:00 2001 From: Bo Anderson Date: Mon, 9 Jun 2025 19:59:41 +0100 Subject: [PATCH 25/34] cmd/vendor-install: fix exit code handling for curl --- Library/Homebrew/cmd/vendor-install.sh | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/Library/Homebrew/cmd/vendor-install.sh b/Library/Homebrew/cmd/vendor-install.sh index 8825d9fccd..3d58dab372 100644 --- a/Library/Homebrew/cmd/vendor-install.sh +++ b/Library/Homebrew/cmd/vendor-install.sh @@ -101,6 +101,7 @@ fetch() { local first_try=1 local vendor_locations local temporary_path + local curl_exit_code=0 curl_args=() @@ -149,19 +150,27 @@ fetch() { # HOMEBREW_CURL is set by brew.sh (and isn't misspelt here) # shellcheck disable=SC2153 "${HOMEBREW_CURL}" "${curl_args[@]}" -C - "${url}" -o "${temporary_path}" - if [[ $? -eq 33 ]] + curl_exit_code="$?" + if [[ "${curl_exit_code}" -eq 33 ]] then [[ -n "${HOMEBREW_QUIET}" ]] || echo "Trying a full download" >&2 rm -f "${temporary_path}" "${HOMEBREW_CURL}" "${curl_args[@]}" "${url}" -o "${temporary_path}" + curl_exit_code="$?" fi else "${HOMEBREW_CURL}" "${curl_args[@]}" "${url}" -o "${temporary_path}" + curl_exit_code="$?" fi [[ -f "${temporary_path}" ]] && break done + if [[ "${curl_exit_code}" -ne 0 ]] + then + rm -f "${temporary_path}" + fi + if [[ ! -f "${temporary_path}" ]] then vendor_locations="$(printf " - %s\n" "${VENDOR_URLs[@]}")" From b8e2cddbbd8f98fb0f63a3e0cf3772d5d44e6c90 Mon Sep 17 00:00:00 2001 From: Bo Anderson Date: Mon, 9 Jun 2025 19:02:37 +0100 Subject: [PATCH 26/34] Preliminary macOS 26 (Tahoe) support --- Library/Homebrew/macos_version.rb | 7 ++- Library/Homebrew/os/mac/pkgconfig/26/bzip2.pc | 12 +++++ Library/Homebrew/os/mac/pkgconfig/26/expat.pc | 14 ++++++ .../Homebrew/os/mac/pkgconfig/26/libcurl.pc | 42 +++++++++++++++++ .../Homebrew/os/mac/pkgconfig/26/libedit.pc | 12 +++++ .../Homebrew/os/mac/pkgconfig/26/libexslt.pc | 14 ++++++ .../Homebrew/os/mac/pkgconfig/26/libffi.pc | 12 +++++ .../os/mac/pkgconfig/26/libxml-2.0.pc | 14 ++++++ .../Homebrew/os/mac/pkgconfig/26/libxslt.pc | 14 ++++++ .../Homebrew/os/mac/pkgconfig/26/ncurses.pc | 17 +++++++ .../Homebrew/os/mac/pkgconfig/26/ncursesw.pc | 17 +++++++ .../Homebrew/os/mac/pkgconfig/26/sqlite3.pc | 12 +++++ Library/Homebrew/os/mac/pkgconfig/26/uuid.pc | 14 ++++++ Library/Homebrew/os/mac/pkgconfig/26/zlib.pc | 14 ++++++ Library/Homebrew/os/mac/xcode.rb | 47 +++++++++++-------- Library/Homebrew/test/cask/cask_spec.rb | 11 +++++ .../test/github_runner_matrix_spec.rb | 1 + ...tball_bottle-0.1.arm64_tahoe.bottle.tar.gz | 1 + .../testball_bottle-0.1.tahoe.bottle.tar.gz | 1 + 19 files changed, 255 insertions(+), 21 deletions(-) create mode 100644 Library/Homebrew/os/mac/pkgconfig/26/bzip2.pc create mode 100644 Library/Homebrew/os/mac/pkgconfig/26/expat.pc create mode 100644 Library/Homebrew/os/mac/pkgconfig/26/libcurl.pc create mode 100644 Library/Homebrew/os/mac/pkgconfig/26/libedit.pc create mode 100644 Library/Homebrew/os/mac/pkgconfig/26/libexslt.pc create mode 100644 Library/Homebrew/os/mac/pkgconfig/26/libffi.pc create mode 100644 Library/Homebrew/os/mac/pkgconfig/26/libxml-2.0.pc create mode 100644 Library/Homebrew/os/mac/pkgconfig/26/libxslt.pc create mode 100644 Library/Homebrew/os/mac/pkgconfig/26/ncurses.pc create mode 100644 Library/Homebrew/os/mac/pkgconfig/26/ncursesw.pc create mode 100644 Library/Homebrew/os/mac/pkgconfig/26/sqlite3.pc create mode 100644 Library/Homebrew/os/mac/pkgconfig/26/uuid.pc create mode 100644 Library/Homebrew/os/mac/pkgconfig/26/zlib.pc create mode 120000 Library/Homebrew/test/support/fixtures/bottles/testball_bottle-0.1.arm64_tahoe.bottle.tar.gz create mode 120000 Library/Homebrew/test/support/fixtures/bottles/testball_bottle-0.1.tahoe.bottle.tar.gz diff --git a/Library/Homebrew/macos_version.rb b/Library/Homebrew/macos_version.rb index 9c1cd7117f..f71a2e6e73 100644 --- a/Library/Homebrew/macos_version.rb +++ b/Library/Homebrew/macos_version.rb @@ -19,6 +19,7 @@ class MacOSVersion < Version # NOTE: When removing symbols here, ensure that they are added # to `DEPRECATED_MACOS_VERSIONS` in `MacOSRequirement`. SYMBOLS = { + tahoe: "26", sequoia: "15", sonoma: "14", ventura: "13", @@ -34,7 +35,9 @@ class MacOSVersion < Version sig { params(macos_version: MacOSVersion).returns(Version) } def self.kernel_major_version(macos_version) version_major = macos_version.major.to_i - if version_major > 10 + if version_major >= 26 + Version.new((version_major - 1).to_s) + elsif version_major > 10 Version.new((version_major + 9).to_s) else version_minor = macos_version.minor.to_i @@ -50,7 +53,7 @@ class MacOSVersion < Version sig { params(version: T.nilable(String)).void } def initialize(version) - raise MacOSVersion::Error, version unless /\A1\d+(?:\.\d+){0,2}\Z/.match?(version) + raise MacOSVersion::Error, version unless /\A\d{2,}(?:\.\d+){0,2}\z/.match?(version) super(T.must(version)) diff --git a/Library/Homebrew/os/mac/pkgconfig/26/bzip2.pc b/Library/Homebrew/os/mac/pkgconfig/26/bzip2.pc new file mode 100644 index 0000000000..aded4844b2 --- /dev/null +++ b/Library/Homebrew/os/mac/pkgconfig/26/bzip2.pc @@ -0,0 +1,12 @@ +homebrew_sdkroot=/Library/Developer/CommandLineTools/SDKs/MacOSX26.sdk +prefix=${homebrew_sdkroot}/usr +exec_prefix=/usr +bindir=${exec_prefix}/bin +libdir=${exec_prefix}/lib +includedir=${prefix}/include + +Name: bzip2 +Description: Lossless, block-sorting data compression +Version: 1.0.8 +Libs: -L${libdir} -lbz2 +Cflags: diff --git a/Library/Homebrew/os/mac/pkgconfig/26/expat.pc b/Library/Homebrew/os/mac/pkgconfig/26/expat.pc new file mode 100644 index 0000000000..8395575305 --- /dev/null +++ b/Library/Homebrew/os/mac/pkgconfig/26/expat.pc @@ -0,0 +1,14 @@ +homebrew_sdkroot=/Library/Developer/CommandLineTools/SDKs/MacOSX26.sdk +prefix=${homebrew_sdkroot}/usr +exec_prefix=/usr +libdir=${exec_prefix}/lib +includedir=${prefix}/include + +Name: expat +Version: 2.7.1 +Description: expat XML parser +URL: https://libexpat.github.io/ +Libs: -L${libdir} -lexpat +Libs.private: +Cflags: +Cflags.private: -DXML_STATIC diff --git a/Library/Homebrew/os/mac/pkgconfig/26/libcurl.pc b/Library/Homebrew/os/mac/pkgconfig/26/libcurl.pc new file mode 100644 index 0000000000..3247df2e81 --- /dev/null +++ b/Library/Homebrew/os/mac/pkgconfig/26/libcurl.pc @@ -0,0 +1,42 @@ +#*************************************************************************** +# _ _ ____ _ +# Project ___| | | | _ \| | +# / __| | | | |_) | | +# | (__| |_| | _ <| |___ +# \___|\___/|_| \_\_____| +# +# Copyright (C) Daniel Stenberg, , et al. +# +# This software is licensed as described in the file COPYING, which +# you should have received as part of this distribution. The terms +# are also available at https://curl.se/docs/copyright.html. +# +# You may opt to use, copy, modify, merge, publish, distribute and/or sell +# copies of the Software, and permit persons to whom the Software is +# furnished to do so, under the terms of the COPYING file. +# +# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +# KIND, either express or implied. +# +# SPDX-License-Identifier: curl +# +########################################################################### + +# This should most probably benefit from getting a "Requires:" field added +# dynamically by configure. +# +homebrew_sdkroot=/Library/Developer/CommandLineTools/SDKs/MacOSX26.sdk +prefix=${homebrew_sdkroot}/usr +exec_prefix=/usr +libdir=${exec_prefix}/lib +includedir=${prefix}/include +supported_protocols="DICT FILE FTP FTPS GOPHER GOPHERS HTTP HTTPS IMAP IMAPS IPFS IPNS LDAP LDAPS MQTT POP3 POP3S RTSP SMB SMBS SMTP SMTPS TELNET TFTP" +supported_features="alt-svc AsynchDNS GSS-API HSTS HTTP2 HTTPS-proxy IPv6 Kerberos Largefile libz MultiSSL NTLM SPNEGO SSL threadsafe UnixSockets" + +Name: libcurl +URL: https://curl.se/ +Description: Library to transfer files with ftp, http, etc. +Version: 8.7.1 +Libs: -L${libdir} -lcurl +Libs.private: -lldap -lz +Cflags: diff --git a/Library/Homebrew/os/mac/pkgconfig/26/libedit.pc b/Library/Homebrew/os/mac/pkgconfig/26/libedit.pc new file mode 100644 index 0000000000..a20a0f6a13 --- /dev/null +++ b/Library/Homebrew/os/mac/pkgconfig/26/libedit.pc @@ -0,0 +1,12 @@ +homebrew_sdkroot=/Library/Developer/CommandLineTools/SDKs/MacOSX26.sdk +prefix=${homebrew_sdkroot}/usr +exec_prefix=/usr +libdir=${exec_prefix}/lib +includedir=${prefix}/include + +Name: libedit +Description: command line editor library provides generic line editing, history, and tokenization functions. +Version: 3.0 +Requires: +Libs: -L${libdir} -ledit +Cflags: -I${includedir}/editline diff --git a/Library/Homebrew/os/mac/pkgconfig/26/libexslt.pc b/Library/Homebrew/os/mac/pkgconfig/26/libexslt.pc new file mode 100644 index 0000000000..4da5570157 --- /dev/null +++ b/Library/Homebrew/os/mac/pkgconfig/26/libexslt.pc @@ -0,0 +1,14 @@ +homebrew_sdkroot=/Library/Developer/CommandLineTools/SDKs/MacOSX26.sdk +prefix=${homebrew_sdkroot}/usr +exec_prefix=/usr +libdir=${exec_prefix}/lib +includedir=${prefix}/include + + +Name: libexslt +Version: 0.8.20 +Description: EXSLT Extension library +Requires: libxml-2.0, libxslt +Cflags: +Libs: -L${libdir} -lexslt +Libs.private: diff --git a/Library/Homebrew/os/mac/pkgconfig/26/libffi.pc b/Library/Homebrew/os/mac/pkgconfig/26/libffi.pc new file mode 100644 index 0000000000..2e462cc1eb --- /dev/null +++ b/Library/Homebrew/os/mac/pkgconfig/26/libffi.pc @@ -0,0 +1,12 @@ +homebrew_sdkroot=/Library/Developer/CommandLineTools/SDKs/MacOSX26.sdk +prefix=${homebrew_sdkroot}/usr +exec_prefix=/usr +libdir=${exec_prefix}/lib +toolexeclibdir=${libdir} +includedir=${prefix}/include/ffi + +Name: libffi +Description: Library supporting Foreign Function Interfaces +Version: 3.4-rc1 +Libs: -L${toolexeclibdir} -lffi +Cflags: -I${includedir} diff --git a/Library/Homebrew/os/mac/pkgconfig/26/libxml-2.0.pc b/Library/Homebrew/os/mac/pkgconfig/26/libxml-2.0.pc new file mode 100644 index 0000000000..214be9468b --- /dev/null +++ b/Library/Homebrew/os/mac/pkgconfig/26/libxml-2.0.pc @@ -0,0 +1,14 @@ +homebrew_sdkroot=/Library/Developer/CommandLineTools/SDKs/MacOSX26.sdk +prefix=${homebrew_sdkroot}/usr +exec_prefix=/usr +libdir=${exec_prefix}/lib +includedir=${prefix}/include +modules=1 + +Name: libXML +Version: 2.9.13 +Description: libXML library version2. +Requires: +Libs: -L${libdir} -lxml2 +Libs.private: -lz -lpthread -licucore -lm +Cflags: diff --git a/Library/Homebrew/os/mac/pkgconfig/26/libxslt.pc b/Library/Homebrew/os/mac/pkgconfig/26/libxslt.pc new file mode 100644 index 0000000000..09b03d6fb1 --- /dev/null +++ b/Library/Homebrew/os/mac/pkgconfig/26/libxslt.pc @@ -0,0 +1,14 @@ +homebrew_sdkroot=/Library/Developer/CommandLineTools/SDKs/MacOSX26.sdk +prefix=${homebrew_sdkroot}/usr +exec_prefix=/usr +libdir=${exec_prefix}/lib +includedir=${prefix}/include + + +Name: libxslt +Version: 1.1.35 +Description: XSLT library version 2. +Requires: libxml-2.0 +Cflags: +Libs: -L${libdir} -lxslt +Libs.private: diff --git a/Library/Homebrew/os/mac/pkgconfig/26/ncurses.pc b/Library/Homebrew/os/mac/pkgconfig/26/ncurses.pc new file mode 100644 index 0000000000..05acdc3fbb --- /dev/null +++ b/Library/Homebrew/os/mac/pkgconfig/26/ncurses.pc @@ -0,0 +1,17 @@ +homebrew_sdkroot=/Library/Developer/CommandLineTools/SDKs/MacOSX26.sdk +prefix=${homebrew_sdkroot}/usr +exec_prefix=/usr +libdir=${exec_prefix}/lib +includedir=${prefix}/include +abi_version=5.4 +major_version=6 +version=6.0.20150808 + +Name: ncurses +Description: ncurses 6.0 library +Version: ${version} +URL: http://invisible-island.net/ncurses +Requires.private: +Libs: -L${libdir} -lncurses +Libs.private: +Cflags: -D_DARWIN_C_SOURCE diff --git a/Library/Homebrew/os/mac/pkgconfig/26/ncursesw.pc b/Library/Homebrew/os/mac/pkgconfig/26/ncursesw.pc new file mode 100644 index 0000000000..1456908fa0 --- /dev/null +++ b/Library/Homebrew/os/mac/pkgconfig/26/ncursesw.pc @@ -0,0 +1,17 @@ +homebrew_sdkroot=/Library/Developer/CommandLineTools/SDKs/MacOSX26.sdk +prefix=${homebrew_sdkroot}/usr +exec_prefix=/usr +libdir=${exec_prefix}/lib +includedir=${prefix}/include +abi_version=5.4 +major_version=6 +version=6.0.20150808 + +Name: ncursesw +Description: ncurses 6.0 library +Version: ${version} +URL: http://invisible-island.net/ncurses +Requires.private: +Libs: -L${libdir} -lncurses +Libs.private: +Cflags: -D_DARWIN_C_SOURCE diff --git a/Library/Homebrew/os/mac/pkgconfig/26/sqlite3.pc b/Library/Homebrew/os/mac/pkgconfig/26/sqlite3.pc new file mode 100644 index 0000000000..e7f9019fd5 --- /dev/null +++ b/Library/Homebrew/os/mac/pkgconfig/26/sqlite3.pc @@ -0,0 +1,12 @@ +homebrew_sdkroot=/Library/Developer/CommandLineTools/SDKs/MacOSX26.sdk +prefix=${homebrew_sdkroot}/usr +exec_prefix=/usr +libdir=${exec_prefix}/lib +includedir=${prefix}/include + +Name: SQLite +Description: SQL database engine +Version: 3.48.0 +Libs: -L${libdir} -lsqlite3 +Libs.private: +Cflags: diff --git a/Library/Homebrew/os/mac/pkgconfig/26/uuid.pc b/Library/Homebrew/os/mac/pkgconfig/26/uuid.pc new file mode 100644 index 0000000000..3dc8070ed2 --- /dev/null +++ b/Library/Homebrew/os/mac/pkgconfig/26/uuid.pc @@ -0,0 +1,14 @@ +homebrew_sdkroot=/Library/Developer/CommandLineTools/SDKs/MacOSX26.sdk +prefix=${homebrew_sdkroot}/usr +exec_prefix=/usr +libdir=${exec_prefix}/lib +sharedlibdir=${libdir} +includedir=${prefix}/include/uuid + +Name: uuid +Description: Universally unique id library +Version: 1.0 + +Requires: +Libs: +Cflags: -I${includedir} diff --git a/Library/Homebrew/os/mac/pkgconfig/26/zlib.pc b/Library/Homebrew/os/mac/pkgconfig/26/zlib.pc new file mode 100644 index 0000000000..a86f93bc1b --- /dev/null +++ b/Library/Homebrew/os/mac/pkgconfig/26/zlib.pc @@ -0,0 +1,14 @@ +homebrew_sdkroot=/Library/Developer/CommandLineTools/SDKs/MacOSX26.sdk +prefix=${homebrew_sdkroot}/usr +exec_prefix=/usr +libdir=${exec_prefix}/lib +sharedlibdir=${libdir} +includedir=${prefix}/include + +Name: zlib +Description: zlib compression library +Version: 1.2.12 + +Requires: +Libs: -L${libdir} -L${sharedlibdir} -lz +Cflags: diff --git a/Library/Homebrew/os/mac/xcode.rb b/Library/Homebrew/os/mac/xcode.rb index 5af295fcf6..cec906f25e 100644 --- a/Library/Homebrew/os/mac/xcode.rb +++ b/Library/Homebrew/os/mac/xcode.rb @@ -15,10 +15,10 @@ module OS # This may be a beta version for a beta macOS. sig { params(macos: MacOSVersion).returns(String) } def self.latest_version(macos: MacOS.version) - latest_stable = "15.4" + macos = macos.strip_patch case macos - when "15" then "16.0" - when "14" then latest_stable + when "15" then "16.4" + when "14" then "16.2" when "13" then "15.2" when "12" then "14.2" when "11" then "13.2.1" @@ -28,10 +28,10 @@ module OS when "10.12" then "9.2" when "10.11" then "8.2.1" else - raise "macOS '#{MacOS.version}' is invalid" unless OS::Mac.version.prerelease? + raise "macOS '#{macos}' is invalid" unless macos.prerelease? - # Default to newest known version of Xcode for unreleased macOS versions. - latest_stable + # Assume matching yearly Xcode release + "#{macos}.0" end end @@ -41,7 +41,8 @@ module OS # also in beta). sig { returns(String) } def self.minimum_version - case MacOS.version + macos = MacOS.version + case macos when "15" then "16.0" when "14" then "15.0" when "13" then "14.1" @@ -51,7 +52,9 @@ module OS when "10.14" then "10.2" when "10.13" then "9.0" when "10.12" then "8.0" - else "7.3" + when "10.11" then "7.3" + else + "#{macos}.0" end end @@ -225,10 +228,8 @@ module OS detect_version_from_clang_version end - sig { returns(String) } - def self.detect_version_from_clang_version - version = ::DevelopmentTools.clang_version - + sig { params(version: ::Version).returns(String) } + def self.detect_version_from_clang_version(version = ::DevelopmentTools.clang_version) return "dunno" if version.null? # This logic provides a fake Xcode version based on the @@ -255,8 +256,9 @@ module OS when "13.1.6" then "13.4.1" when "14.0.0" then "14.2" when "14.0.3" then "14.3.1" - when "16.0.0" then "16.0" - else "15.4" + when "15.0.0" then "15.4" + when "16.0.0" then "16.2" + else "26.0" end end @@ -355,8 +357,9 @@ module OS sig { returns(String) } def self.latest_clang_version case MacOS.version - when "15" then "1600.0.20.10" - when "14" then "1500.3.9.4" + when "26" then "1700.3.9.908" + when "15" then "1700.0.13.5" + when "14" then "1600.0.26.6" when "13" then "1500.1.0.2.5" when "12" then "1400.0.29.202" when "11" then "1300.0.29.30" @@ -373,7 +376,8 @@ module OS # that macOS version. sig { returns(String) } def self.minimum_version - case MacOS.version + macos = MacOS.version + case macos when "15" then "16.0.0" when "14" then "15.0.0" when "13" then "14.0.0" @@ -383,7 +387,9 @@ module OS when "10.14" then "10.0.0" when "10.13" then "9.0.0" when "10.12" then "8.0.0" - else "7.3.0" + when "10.11" then "7.3.0" + else + "#{macos}.0.0" end end @@ -410,7 +416,10 @@ module OS sig { returns(T.nilable(String)) } def self.detect_version_from_clang_version - detect_clang_version&.sub(/^(\d+)0(\d)\./, "\\1.\\2.") + clang_version = detect_clang_version + return if clang_version.nil? + + MacOS::Xcode.detect_version_from_clang_version(Version.new(clang_version)) end # Version string (a pretty long one) of the CLT package. diff --git a/Library/Homebrew/test/cask/cask_spec.rb b/Library/Homebrew/test/cask/cask_spec.rb index 2dd30c87cc..bb499f2001 100644 --- a/Library/Homebrew/test/cask/cask_spec.rb +++ b/Library/Homebrew/test/cask/cask_spec.rb @@ -324,6 +324,9 @@ RSpec.describe Cask::Cask, :cask do let(:expected_versions_variations) do <<~JSON { + "tahoe": { + "url": "file://#{TEST_FIXTURE_DIR}/cask/caffeine/darwin/1.2.3/intel.zip" + }, "sequoia": { "url": "file://#{TEST_FIXTURE_DIR}/cask/caffeine/darwin/1.2.3/intel.zip" }, @@ -377,6 +380,10 @@ RSpec.describe Cask::Cask, :cask do let(:expected_sha256_variations) do <<~JSON { + "tahoe": { + "url": "file://#{TEST_FIXTURE_DIR}/cask/caffeine-intel.zip", + "sha256": "8c62a2b791cf5f0da6066a0a4b6e85f62949cd60975da062df44adf887f4370b" + }, "sequoia": { "url": "file://#{TEST_FIXTURE_DIR}/cask/caffeine-intel.zip", "sha256": "8c62a2b791cf5f0da6066a0a4b6e85f62949cd60975da062df44adf887f4370b" @@ -423,6 +430,10 @@ RSpec.describe Cask::Cask, :cask do let(:expected_sha256_variations_os) do <<~JSON { + "tahoe": { + "url": "file://#{TEST_FIXTURE_DIR}/cask/caffeine-intel-darwin.zip", + "sha256": "8c62a2b791cf5f0da6066a0a4b6e85f62949cd60975da062df44adf887f4370b" + }, "sequoia": { "url": "file://#{TEST_FIXTURE_DIR}/cask/caffeine-intel-darwin.zip", "sha256": "8c62a2b791cf5f0da6066a0a4b6e85f62949cd60975da062df44adf887f4370b" diff --git a/Library/Homebrew/test/github_runner_matrix_spec.rb b/Library/Homebrew/test/github_runner_matrix_spec.rb index 2920ca6698..ce1c73eaaa 100644 --- a/Library/Homebrew/test/github_runner_matrix_spec.rb +++ b/Library/Homebrew/test/github_runner_matrix_spec.rb @@ -13,6 +13,7 @@ RSpec.describe GitHubRunnerMatrix do allow(ENV).to receive(:fetch).with("HOMEBREW_EVAL_ALL", nil).and_call_original allow(ENV).to receive(:fetch).with("HOMEBREW_SIMULATE_MACOS_ON_LINUX", nil).and_call_original allow(ENV).to receive(:fetch).with("HOMEBREW_FORBID_PACKAGES_FROM_PATHS", nil).and_call_original + allow(ENV).to receive(:fetch).with("HOMEBREW_DEVELOPER", nil).and_call_original end let(:newest_supported_macos) do diff --git a/Library/Homebrew/test/support/fixtures/bottles/testball_bottle-0.1.arm64_tahoe.bottle.tar.gz b/Library/Homebrew/test/support/fixtures/bottles/testball_bottle-0.1.arm64_tahoe.bottle.tar.gz new file mode 120000 index 0000000000..3e989830ba --- /dev/null +++ b/Library/Homebrew/test/support/fixtures/bottles/testball_bottle-0.1.arm64_tahoe.bottle.tar.gz @@ -0,0 +1 @@ +testball_bottle-0.1.yosemite.bottle.tar.gz \ No newline at end of file diff --git a/Library/Homebrew/test/support/fixtures/bottles/testball_bottle-0.1.tahoe.bottle.tar.gz b/Library/Homebrew/test/support/fixtures/bottles/testball_bottle-0.1.tahoe.bottle.tar.gz new file mode 120000 index 0000000000..3e989830ba --- /dev/null +++ b/Library/Homebrew/test/support/fixtures/bottles/testball_bottle-0.1.tahoe.bottle.tar.gz @@ -0,0 +1 @@ +testball_bottle-0.1.yosemite.bottle.tar.gz \ No newline at end of file From c086bdcbba05b637051511a9d598ad815801e863 Mon Sep 17 00:00:00 2001 From: BrewTestBot <1589480+BrewTestBot@users.noreply.github.com> Date: Tue, 10 Jun 2025 00:29:54 +0000 Subject: [PATCH 27/34] sorbet: Update RBI files. Autogenerated by the [sorbet](https://github.com/Homebrew/brew/blob/master/.github/workflows/sorbet.yml) workflow. --- .../rbi/dsl/homebrew/cmd/mcp_server_cmd.rbi | 16 ++++++++++++++++ .../sorbet/rbi/dsl/rubo_cop/cask/ast/stanza.rbi | 3 +++ 2 files changed, 19 insertions(+) create mode 100644 Library/Homebrew/sorbet/rbi/dsl/homebrew/cmd/mcp_server_cmd.rbi diff --git a/Library/Homebrew/sorbet/rbi/dsl/homebrew/cmd/mcp_server_cmd.rbi b/Library/Homebrew/sorbet/rbi/dsl/homebrew/cmd/mcp_server_cmd.rbi new file mode 100644 index 0000000000..c9fc49bef8 --- /dev/null +++ b/Library/Homebrew/sorbet/rbi/dsl/homebrew/cmd/mcp_server_cmd.rbi @@ -0,0 +1,16 @@ +# typed: true + +# DO NOT EDIT MANUALLY +# This is an autogenerated file for dynamic methods in `Homebrew::Cmd::McpServerCmd`. +# Please instead update this file by running `bin/tapioca dsl Homebrew::Cmd::McpServerCmd`. + + +class Homebrew::Cmd::McpServerCmd + sig { returns(Homebrew::Cmd::McpServerCmd::Args) } + def args; end +end + +class Homebrew::Cmd::McpServerCmd::Args < Homebrew::CLI::Args + sig { returns(T::Boolean) } + def ping?; end +end diff --git a/Library/Homebrew/sorbet/rbi/dsl/rubo_cop/cask/ast/stanza.rbi b/Library/Homebrew/sorbet/rbi/dsl/rubo_cop/cask/ast/stanza.rbi index a8c6e4f8af..b07393aca9 100644 --- a/Library/Homebrew/sorbet/rbi/dsl/rubo_cop/cask/ast/stanza.rbi +++ b/Library/Homebrew/sorbet/rbi/dsl/rubo_cop/cask/ast/stanza.rbi @@ -129,6 +129,9 @@ class RuboCop::Cask::AST::Stanza sig { params(args: T.untyped, block: T.untyped).returns(T::Boolean) } def on_system_block?(*args, &block); end + sig { returns(T::Boolean) } + def on_tahoe?; end + sig { returns(T::Boolean) } def on_ventura?; end From e9f55a8f716a3f25125e33482c46792d7f738eb5 Mon Sep 17 00:00:00 2001 From: Mike McQuaid Date: Tue, 10 Jun 2025 14:37:21 +0000 Subject: [PATCH 28/34] tests: default to API mode enabled. While we're here, also add `brew tests --no-parallel` which I relied on during testing. Pretty much anywhere we rely on a stubbed formula on disk to work: we need to disable the API. --- Library/Homebrew/dev-cmd/tests.rb | 7 +++---- Library/Homebrew/formula_installer.rb | 1 + .../sorbet/rbi/dsl/homebrew/dev_cmd/tests.rbi | 3 +++ Library/Homebrew/test/api/cask_spec.rb | 1 + .../test/bundle/commands/check_spec.rb | 2 +- .../test/bundle/commands/cleanup_spec.rb | 2 +- .../Homebrew/test/bundle/commands/exec_spec.rb | 2 +- .../test/bundle/commands/install_spec.rb | 2 +- .../cask/cask_loader/from_api_loader_spec.rb | 4 ---- Library/Homebrew/test/cask/cask_loader_spec.rb | 4 ---- Library/Homebrew/test/cask/cask_spec.rb | 4 ++-- Library/Homebrew/test/cask_dependent_spec.rb | 2 +- Library/Homebrew/test/cmd/deps_spec.rb | 2 +- Library/Homebrew/test/cmd/desc_spec.rb | 7 +++---- Library/Homebrew/test/cmd/leaves_spec.rb | 2 +- Library/Homebrew/test/cmd/migrate_spec.rb | 2 +- Library/Homebrew/test/cmd/missing_spec.rb | 2 +- Library/Homebrew/test/cmd/search_spec.rb | 2 +- Library/Homebrew/test/cmd/tap-info_spec.rb | 2 +- Library/Homebrew/test/cmd/untap_spec.rb | 4 ++-- Library/Homebrew/test/cmd/uses_spec.rb | 4 ++-- .../Homebrew/test/compiler_selector_spec.rb | 2 +- .../Homebrew/test/diagnostic_checks_spec.rb | 2 -- Library/Homebrew/test/exceptions_spec.rb | 4 ++-- Library/Homebrew/test/formula_auditor_spec.rb | 6 +++--- Library/Homebrew/test/formulary_spec.rb | 14 ++++---------- .../Homebrew/test/github_runner_matrix_spec.rb | 4 ++-- Library/Homebrew/test/spec_helper.rb | 6 ++++++ .../spec/shared_context/integration_test.rb | 18 ++++++++++-------- Library/Homebrew/test/tap_spec.rb | 7 +++---- 30 files changed, 59 insertions(+), 65 deletions(-) diff --git a/Library/Homebrew/dev-cmd/tests.rb b/Library/Homebrew/dev-cmd/tests.rb index 450098d268..7e0329b1be 100644 --- a/Library/Homebrew/dev-cmd/tests.rb +++ b/Library/Homebrew/dev-cmd/tests.rb @@ -28,6 +28,8 @@ module Homebrew description: "Only runs tests on files that were changed from the master branch." switch "--fail-fast", description: "Exit early on the first failing test." + switch "--no-parallel", + description: "Run tests serially." flag "--only=", description: "Run only `_spec.rb`. Appending `:` will start at a " \ "specific line." @@ -49,7 +51,7 @@ module Homebrew HOMEBREW_LIBRARY_PATH.cd do setup_environment! - parallel = true + parallel = !args.no_parallel? only = args.only files = if only @@ -240,9 +242,6 @@ module Homebrew ENV["HOMEBREW_SORBET_RUNTIME"] = "1" ENV["HOMEBREW_NO_FORCE_BREW_WRAPPER"] = "1" - # TODO: remove this and fix tests when possible. - ENV["HOMEBREW_NO_INSTALL_FROM_API"] = "1" - ENV["USER"] ||= system_command!("id", args: ["-nu"]).stdout.chomp # Avoid local configuration messing with tests, e.g. git being configured diff --git a/Library/Homebrew/formula_installer.rb b/Library/Homebrew/formula_installer.rb index bff2564824..56d9094ac2 100644 --- a/Library/Homebrew/formula_installer.rb +++ b/Library/Homebrew/formula_installer.rb @@ -520,6 +520,7 @@ class FormulaInstaller oh1 "Installing #{Formatter.identifier(formula.full_name)} #{options}".strip if show_header? if (tap = formula.tap) && tap.should_report_analytics? + require "utils/analytics" Utils::Analytics.report_package_event(:formula_install, package_name: formula.name, tap_name: tap.name, on_request: installed_on_request?, options:) end diff --git a/Library/Homebrew/sorbet/rbi/dsl/homebrew/dev_cmd/tests.rbi b/Library/Homebrew/sorbet/rbi/dsl/homebrew/dev_cmd/tests.rbi index 863665ee93..32c70a843f 100644 --- a/Library/Homebrew/sorbet/rbi/dsl/homebrew/dev_cmd/tests.rbi +++ b/Library/Homebrew/sorbet/rbi/dsl/homebrew/dev_cmd/tests.rbi @@ -23,6 +23,9 @@ class Homebrew::DevCmd::Tests::Args < Homebrew::CLI::Args sig { returns(T::Boolean) } def generic?; end + sig { returns(T::Boolean) } + def no_parallel?; end + sig { returns(T::Boolean) } def online?; end diff --git a/Library/Homebrew/test/api/cask_spec.rb b/Library/Homebrew/test/api/cask_spec.rb index 932897dbe8..372027293f 100644 --- a/Library/Homebrew/test/api/cask_spec.rb +++ b/Library/Homebrew/test/api/cask_spec.rb @@ -54,6 +54,7 @@ RSpec.describe Homebrew::API::Cask do end before do + allow(Homebrew::API).to receive(:fetch_json_api_file).and_return([[], true]) allow_any_instance_of(Homebrew::API::Download).to receive(:fetch) allow_any_instance_of(Homebrew::API::Download).to receive(:symlink_location).and_return( TEST_FIXTURE_DIR/"cask/Casks/everything.rb", diff --git a/Library/Homebrew/test/bundle/commands/check_spec.rb b/Library/Homebrew/test/bundle/commands/check_spec.rb index 2e62f9383c..8448d7ee1b 100644 --- a/Library/Homebrew/test/bundle/commands/check_spec.rb +++ b/Library/Homebrew/test/bundle/commands/check_spec.rb @@ -12,7 +12,7 @@ require "bundle/mac_app_store_installer" require "bundle/dsl" require "bundle/skipper" -RSpec.describe Homebrew::Bundle::Commands::Check do +RSpec.describe Homebrew::Bundle::Commands::Check, :no_api do let(:do_check) do described_class.run(no_upgrade:, verbose:) end diff --git a/Library/Homebrew/test/bundle/commands/cleanup_spec.rb b/Library/Homebrew/test/bundle/commands/cleanup_spec.rb index e85f78ddc7..1793985919 100644 --- a/Library/Homebrew/test/bundle/commands/cleanup_spec.rb +++ b/Library/Homebrew/test/bundle/commands/cleanup_spec.rb @@ -4,7 +4,7 @@ require "bundle" require "bundle/commands/cleanup" RSpec.describe Homebrew::Bundle::Commands::Cleanup do - describe "read Brewfile and current installation" do + describe "read Brewfile and current installation", :no_api do before do described_class.reset! diff --git a/Library/Homebrew/test/bundle/commands/exec_spec.rb b/Library/Homebrew/test/bundle/commands/exec_spec.rb index 101ab72f05..c11b989b46 100644 --- a/Library/Homebrew/test/bundle/commands/exec_spec.rb +++ b/Library/Homebrew/test/bundle/commands/exec_spec.rb @@ -12,7 +12,7 @@ RSpec.describe Homebrew::Bundle::Commands::Exec do end end - context "when a Brewfile is found" do + context "when a Brewfile is found", :no_api do let(:brewfile_contents) { "brew 'openssl'" } before do diff --git a/Library/Homebrew/test/bundle/commands/install_spec.rb b/Library/Homebrew/test/bundle/commands/install_spec.rb index f32e3f28e3..9e855914bd 100644 --- a/Library/Homebrew/test/bundle/commands/install_spec.rb +++ b/Library/Homebrew/test/bundle/commands/install_spec.rb @@ -16,7 +16,7 @@ RSpec.describe Homebrew::Bundle::Commands::Install do end end - context "when a Brewfile is found" do + context "when a Brewfile is found", :no_api do let(:brewfile_contents) do <<~EOS tap 'phinze/cask' diff --git a/Library/Homebrew/test/cask/cask_loader/from_api_loader_spec.rb b/Library/Homebrew/test/cask/cask_loader/from_api_loader_spec.rb index f066a098a9..3362c519b6 100644 --- a/Library/Homebrew/test/cask/cask_loader/from_api_loader_spec.rb +++ b/Library/Homebrew/test/cask/cask_loader/from_api_loader_spec.rb @@ -31,10 +31,6 @@ RSpec.describe Cask::CaskLoader::FromAPILoader, :cask do end context "when using the API" do - before do - ENV.delete("HOMEBREW_NO_INSTALL_FROM_API") - end - it "returns a loader for valid token" do expect(described_class.try_new(api_token)) .to be_a(described_class) diff --git a/Library/Homebrew/test/cask/cask_loader_spec.rb b/Library/Homebrew/test/cask/cask_loader_spec.rb index 4c18828c9e..e2671408fa 100644 --- a/Library/Homebrew/test/cask/cask_loader_spec.rb +++ b/Library/Homebrew/test/cask/cask_loader_spec.rb @@ -45,10 +45,6 @@ RSpec.describe Cask::CaskLoader, :cask do end context "when using the API" do - before do - ENV.delete("HOMEBREW_NO_INSTALL_FROM_API") - end - it "warns when using the short token" do expect do expect(described_class.for("version-newest")).to be_a Cask::CaskLoader::FromAPILoader diff --git a/Library/Homebrew/test/cask/cask_spec.rb b/Library/Homebrew/test/cask/cask_spec.rb index bb499f2001..e08e8f90e4 100644 --- a/Library/Homebrew/test/cask/cask_spec.rb +++ b/Library/Homebrew/test/cask/cask_spec.rb @@ -46,13 +46,13 @@ RSpec.describe Cask::Cask, :cask do expect(c.token).to eq("caffeine") end - it "returns an instance of the Cask from a URL", :needs_utils_curl, :no_api do + it "returns an instance of the Cask from a URL", :needs_utils_curl do c = Cask::CaskLoader.load("file://#{tap_path}/Casks/local-caffeine.rb") expect(c).to be_a(described_class) expect(c.token).to eq("local-caffeine") end - it "raises an error when failing to download a Cask from a URL", :needs_utils_curl, :no_api do + it "raises an error when failing to download a Cask from a URL", :needs_utils_curl do expect do Cask::CaskLoader.load("file://#{tap_path}/Casks/notacask.rb") end.to raise_error(Cask::CaskUnavailableError) diff --git a/Library/Homebrew/test/cask_dependent_spec.rb b/Library/Homebrew/test/cask_dependent_spec.rb index 48e09d16fe..38e9da163f 100644 --- a/Library/Homebrew/test/cask_dependent_spec.rb +++ b/Library/Homebrew/test/cask_dependent_spec.rb @@ -30,7 +30,7 @@ RSpec.describe CaskDependent, :needs_macos do end end - describe "#recursive_dependencies", :integration_test do + describe "#recursive_dependencies", :integration_test, :no_api do it "is all the dependencies of the cask" do setup_test_formula "foo" setup_test_formula "bar" diff --git a/Library/Homebrew/test/cmd/deps_spec.rb b/Library/Homebrew/test/cmd/deps_spec.rb index 80edb94337..aa881002aa 100644 --- a/Library/Homebrew/test/cmd/deps_spec.rb +++ b/Library/Homebrew/test/cmd/deps_spec.rb @@ -8,7 +8,7 @@ RSpec.describe Homebrew::Cmd::Deps do it_behaves_like "parseable arguments" - it "outputs all of a Formula's dependencies and their dependencies on separate lines", :integration_test do + it "outputs all of a Formula's dependencies and their dependencies on separate lines", :integration_test, :no_api do # Included in output setup_test_formula "bar" setup_test_formula "foo" diff --git a/Library/Homebrew/test/cmd/desc_spec.rb b/Library/Homebrew/test/cmd/desc_spec.rb index 4313e56ac3..4c699e62f5 100644 --- a/Library/Homebrew/test/cmd/desc_spec.rb +++ b/Library/Homebrew/test/cmd/desc_spec.rb @@ -15,7 +15,7 @@ RSpec.describe Homebrew::Cmd::Desc do .and be_a_success end - it "errors when searching without --eval-all", :integration_test do + it "errors when searching without --eval-all", :integration_test, :no_api do setup_test_formula "testball" expect { brew "desc", "--search", "testball" } @@ -23,7 +23,7 @@ RSpec.describe Homebrew::Cmd::Desc do .and be_a_failure end - it "successfully searches with --search --eval-all", :integration_test do + it "successfully searches with --search --eval-all", :integration_test, :no_api do setup_test_formula "testball" expect { brew "desc", "--search", "--eval-all", "ball" } @@ -34,7 +34,6 @@ RSpec.describe Homebrew::Cmd::Desc do it "successfully searches without --eval-all, with API", :integration_test, :needs_network do setup_test_formula "testball" - expect { brew "desc", "--search", "testball", "HOMEBREW_NO_INSTALL_FROM_API" => nil } - .to be_a_success + expect { brew "desc", "--search", "testball" }.to be_a_success end end diff --git a/Library/Homebrew/test/cmd/leaves_spec.rb b/Library/Homebrew/test/cmd/leaves_spec.rb index 9e00a21ca1..089a032f11 100644 --- a/Library/Homebrew/test/cmd/leaves_spec.rb +++ b/Library/Homebrew/test/cmd/leaves_spec.rb @@ -31,7 +31,7 @@ RSpec.describe Homebrew::Cmd::Leaves do end end - context "when there are installed Formulae", :integration_test do + context "when there are installed Formulae", :integration_test, :no_api do it "prints all installed Formulae that are not dependencies of another installed Formula" do setup_test_formula "foo" setup_test_formula "bar" diff --git a/Library/Homebrew/test/cmd/migrate_spec.rb b/Library/Homebrew/test/cmd/migrate_spec.rb index 0e592a3f03..913bfef608 100644 --- a/Library/Homebrew/test/cmd/migrate_spec.rb +++ b/Library/Homebrew/test/cmd/migrate_spec.rb @@ -6,7 +6,7 @@ require "cmd/shared_examples/args_parse" RSpec.describe Homebrew::Cmd::Migrate do it_behaves_like "parseable arguments" - it "migrates a renamed Formula", :integration_test do + it "migrates a renamed Formula", :integration_test, :no_api do setup_test_formula "testball1" setup_test_formula "testball2" install_and_rename_coretap_formula "testball1", "testball2" diff --git a/Library/Homebrew/test/cmd/missing_spec.rb b/Library/Homebrew/test/cmd/missing_spec.rb index d1cbb37d8b..3cb7353747 100644 --- a/Library/Homebrew/test/cmd/missing_spec.rb +++ b/Library/Homebrew/test/cmd/missing_spec.rb @@ -6,7 +6,7 @@ require "cmd/shared_examples/args_parse" RSpec.describe Homebrew::Cmd::Missing do it_behaves_like "parseable arguments" - it "prints missing dependencies", :integration_test do + it "prints missing dependencies", :integration_test, :no_api do setup_test_formula "foo" setup_test_formula "bar" diff --git a/Library/Homebrew/test/cmd/search_spec.rb b/Library/Homebrew/test/cmd/search_spec.rb index 78adf8855c..6efb80fe83 100644 --- a/Library/Homebrew/test/cmd/search_spec.rb +++ b/Library/Homebrew/test/cmd/search_spec.rb @@ -6,7 +6,7 @@ require "cmd/shared_examples/args_parse" RSpec.describe Homebrew::Cmd::SearchCmd do it_behaves_like "parseable arguments" - it "finds formula in search", :integration_test do + it "finds formula in search", :integration_test, :no_api do setup_test_formula "testball" expect { brew "search", "testball" } diff --git a/Library/Homebrew/test/cmd/tap-info_spec.rb b/Library/Homebrew/test/cmd/tap-info_spec.rb index ada71038cd..78e96760da 100644 --- a/Library/Homebrew/test/cmd/tap-info_spec.rb +++ b/Library/Homebrew/test/cmd/tap-info_spec.rb @@ -16,7 +16,7 @@ RSpec.describe Homebrew::Cmd::TapInfo do end it "display brief statistics for all installed taps", :integration_test, :needs_network do - expect { brew "tap-info", "HOMEBREW_NO_INSTALL_FROM_API" => nil } + expect { brew "tap-info" } .to output(/\d+ taps?, \d+ private/).to_stdout .and not_to_output.to_stderr .and be_a_success diff --git a/Library/Homebrew/test/cmd/untap_spec.rb b/Library/Homebrew/test/cmd/untap_spec.rb index fb1d3a77b0..8100afc00e 100644 --- a/Library/Homebrew/test/cmd/untap_spec.rb +++ b/Library/Homebrew/test/cmd/untap_spec.rb @@ -18,7 +18,7 @@ RSpec.describe Homebrew::Cmd::Untap do end describe "#installed_formulae_for", :integration_test do - shared_examples "finds installed formulae in tap" do + shared_examples "finds installed formulae in tap", :no_api do def load_formula(name:, with_formula_file: false, mock_install: false) formula = if with_formula_file path = setup_test_formula(name, tap:) @@ -84,7 +84,7 @@ RSpec.describe Homebrew::Cmd::Untap do end describe "#installed_casks_for", :cask do - shared_examples "finds installed casks in tap" do + shared_examples "finds installed casks in tap", :no_api do def load_cask(token:, with_cask_file: false, mock_install: false) cask_loader = Cask::CaskLoader::FromContentLoader.new(<<~RUBY, tap:) cask '#{token}' do diff --git a/Library/Homebrew/test/cmd/uses_spec.rb b/Library/Homebrew/test/cmd/uses_spec.rb index 9cea6ade8c..85a38abbfc 100644 --- a/Library/Homebrew/test/cmd/uses_spec.rb +++ b/Library/Homebrew/test/cmd/uses_spec.rb @@ -10,7 +10,7 @@ RSpec.describe Homebrew::Cmd::Uses do it_behaves_like "parseable arguments" - it "prints the Formulae a given Formula is used by", :integration_test do + it "prints the Formulae a given Formula is used by", :integration_test, :no_api do # Included in output setup_test_formula "bar" setup_test_formula "optional", <<~RUBY @@ -46,7 +46,7 @@ RSpec.describe Homebrew::Cmd::Uses do .and be_a_success end - it "handles unavailable formula", :integration_test do + it "handles unavailable formula", :integration_test, :no_api do setup_test_formula "foo" setup_test_formula "bar" setup_test_formula "optional", <<~RUBY diff --git a/Library/Homebrew/test/compiler_selector_spec.rb b/Library/Homebrew/test/compiler_selector_spec.rb index a4fe2a9956..91e3f5358f 100644 --- a/Library/Homebrew/test/compiler_selector_spec.rb +++ b/Library/Homebrew/test/compiler_selector_spec.rb @@ -23,7 +23,7 @@ RSpec.describe CompilerSelector do end end - describe "#compiler" do + describe "#compiler", :no_api do it "defaults to cc" do expect(selector.compiler).to eq(cc) end diff --git a/Library/Homebrew/test/diagnostic_checks_spec.rb b/Library/Homebrew/test/diagnostic_checks_spec.rb index 3e1d9c0563..6249670651 100644 --- a/Library/Homebrew/test/diagnostic_checks_spec.rb +++ b/Library/Homebrew/test/diagnostic_checks_spec.rb @@ -117,7 +117,6 @@ RSpec.describe Homebrew::Diagnostic::Checks do specify "#check_for_unnecessary_core_tap" do ENV.delete("HOMEBREW_DEVELOPER") - ENV.delete("HOMEBREW_NO_INSTALL_FROM_API") expect_any_instance_of(CoreTap).to receive(:installed?).and_return(true) @@ -126,7 +125,6 @@ RSpec.describe Homebrew::Diagnostic::Checks do specify "#check_for_unnecessary_cask_tap" do ENV.delete("HOMEBREW_DEVELOPER") - ENV.delete("HOMEBREW_NO_INSTALL_FROM_API") expect_any_instance_of(CoreCaskTap).to receive(:installed?).and_return(true) diff --git a/Library/Homebrew/test/exceptions_spec.rb b/Library/Homebrew/test/exceptions_spec.rb index 27d03c3239..58bdd2fce8 100644 --- a/Library/Homebrew/test/exceptions_spec.rb +++ b/Library/Homebrew/test/exceptions_spec.rb @@ -71,7 +71,7 @@ RSpec.describe "Exception" do end context "without a dependent" do - it(:to_s) { expect(error.to_s).to eq('No available formula with the name "foo".') } + it(:to_s) { expect(error.to_s).to match(/^No available formula with the name "foo"\./) } end context "with a dependent" do @@ -80,7 +80,7 @@ RSpec.describe "Exception" do end it(:to_s) do - expect(error.to_s).to eq('No available formula with the name "foo" (dependency of foobar).') + expect(error.to_s).to match(/^No available formula with the name "foo" \(dependency of foobar\)\./) end end end diff --git a/Library/Homebrew/test/formula_auditor_spec.rb b/Library/Homebrew/test/formula_auditor_spec.rb index ce873129ba..3d842a1e5b 100644 --- a/Library/Homebrew/test/formula_auditor_spec.rb +++ b/Library/Homebrew/test/formula_auditor_spec.rb @@ -1261,7 +1261,7 @@ RSpec.describe Homebrew::FormulaAuditor do allow(File).to receive(:open).and_return("") end - specify "it warns when conflicting with non-existing formula" do + specify "it warns when conflicting with non-existing formula", :no_api do foo = formula("foo") do url "https://brew.sh/bar-1.0.tgz" @@ -1275,7 +1275,7 @@ RSpec.describe Homebrew::FormulaAuditor do .to match("Can't find conflicting formula \"bar\"") end - specify "it warns when conflicting with itself" do + specify "it warns when conflicting with itself", :no_api do foo = formula("foo") do url "https://brew.sh/bar-1.0.tgz" @@ -1290,7 +1290,7 @@ RSpec.describe Homebrew::FormulaAuditor do .to match("Formula should not conflict with itself") end - specify "it warns when another formula does not have a symmetric conflict" do + specify "it warns when another formula does not have a symmetric conflict", :no_api do stub_formula_loader formula("gcc") { url "gcc-1.0" } stub_formula_loader formula("glibc") { url "glibc-1.0" } diff --git a/Library/Homebrew/test/formulary_spec.rb b/Library/Homebrew/test/formulary_spec.rb index 3e344cad5c..64897d7c30 100644 --- a/Library/Homebrew/test/formulary_spec.rb +++ b/Library/Homebrew/test/formulary_spec.rb @@ -55,7 +55,7 @@ RSpec.describe Formulary do end describe "::factory" do - context "without the API" do + context "without the API", :no_api do before do formula_path.dirname.mkpath formula_path.write formula_content @@ -129,7 +129,7 @@ RSpec.describe Formulary do end.to raise_error(FormulaUnavailableError) end - it "returns a Formula when given a URL", :needs_utils_curl, :no_api do + it "returns a Formula when given a URL", :needs_utils_curl do formula = described_class.factory("file://#{formula_path}") expect(formula).to be_a(Formula) end @@ -398,8 +398,6 @@ RSpec.describe Formulary do end before do - ENV.delete("HOMEBREW_NO_INSTALL_FROM_API") - # avoid unnecessary network calls allow(Homebrew::API::Formula).to receive_messages(all_aliases: {}, all_renames: {}) allow(CoreTap.instance).to receive(:tap_migrations).and_return({}) @@ -645,16 +643,12 @@ RSpec.describe Formulary do end context "when given a tapped name" do - it "returns a `FromTapLoader`" do + it "returns a `FromTapLoader`", :no_api do expect(described_class.loader_for("homebrew/core/gcc")).to be_a Formulary::FromTapLoader end end - context "when not using the API" do - before do - ENV["HOMEBREW_NO_INSTALL_FROM_API"] = "1" - end - + context "when not using the API", :no_api do context "when a formula is migrated" do let(:token) { "foo" } diff --git a/Library/Homebrew/test/github_runner_matrix_spec.rb b/Library/Homebrew/test/github_runner_matrix_spec.rb index ce1c73eaaa..7379e0d7d9 100644 --- a/Library/Homebrew/test/github_runner_matrix_spec.rb +++ b/Library/Homebrew/test/github_runner_matrix_spec.rb @@ -3,17 +3,17 @@ require "github_runner_matrix" require "test/support/fixtures/testball" -RSpec.describe GitHubRunnerMatrix do +RSpec.describe GitHubRunnerMatrix, :no_api do before do allow(ENV).to receive(:fetch).with("HOMEBREW_LINUX_RUNNER").and_return("ubuntu-latest") allow(ENV).to receive(:fetch).with("HOMEBREW_MACOS_LONG_TIMEOUT", "false").and_return("false") allow(ENV).to receive(:fetch).with("HOMEBREW_MACOS_BUILD_ON_GITHUB_RUNNER", "false").and_return("false") allow(ENV).to receive(:fetch).with("GITHUB_RUN_ID").and_return("12345") - allow(ENV).to receive(:fetch).with("HOMEBREW_NO_INSTALL_FROM_API", nil).and_call_original allow(ENV).to receive(:fetch).with("HOMEBREW_EVAL_ALL", nil).and_call_original allow(ENV).to receive(:fetch).with("HOMEBREW_SIMULATE_MACOS_ON_LINUX", nil).and_call_original allow(ENV).to receive(:fetch).with("HOMEBREW_FORBID_PACKAGES_FROM_PATHS", nil).and_call_original allow(ENV).to receive(:fetch).with("HOMEBREW_DEVELOPER", nil).and_call_original + allow(ENV).to receive(:fetch).with("HOMEBREW_NO_INSTALL_FROM_API", nil).and_call_original end let(:newest_supported_macos) do diff --git a/Library/Homebrew/test/spec_helper.rb b/Library/Homebrew/test/spec_helper.rb index a40023c2c6..cc62d453c7 100644 --- a/Library/Homebrew/test/spec_helper.rb +++ b/Library/Homebrew/test/spec_helper.rb @@ -59,6 +59,7 @@ TEST_DIRECTORIES = [ CoreTap.instance.path/"Formula", HOMEBREW_CACHE, HOMEBREW_CACHE_FORMULA, + HOMEBREW_CACHE/"api", HOMEBREW_CELLAR, HOMEBREW_LOCKS, HOMEBREW_LOGS, @@ -249,6 +250,11 @@ RSpec.configure do |config| @__stderr = $stderr.clone @__stdin = $stdin.clone + # Link original API cache files to test cache directory. + Pathname("#{ENV.fetch("HOMEBREW_CACHE")}/api").glob("*.json").each do |path| + FileUtils.ln path, HOMEBREW_CACHE/"api/#{path.basename}" + end + begin if example.metadata.keys.exclude?(:focus) && !ENV.key?("HOMEBREW_VERBOSE_TESTS") $stdout.reopen(File::NULL) diff --git a/Library/Homebrew/test/support/helper/spec/shared_context/integration_test.rb b/Library/Homebrew/test/support/helper/spec/shared_context/integration_test.rb index f8f3b0f60a..e402974813 100644 --- a/Library/Homebrew/test/support/helper/spec/shared_context/integration_test.rb +++ b/Library/Homebrew/test/support/helper/spec/shared_context/integration_test.rb @@ -75,14 +75,15 @@ RSpec.shared_context "integration test" do # rubocop:disable RSpec/ContextWordin ].compact.join(File::PATH_SEPARATOR) env.merge!( - "PATH" => path, - "HOMEBREW_PATH" => path, - "HOMEBREW_BREW_FILE" => HOMEBREW_PREFIX/"bin/brew", - "HOMEBREW_INTEGRATION_TEST" => command_id, - "HOMEBREW_TEST_TMPDIR" => TEST_TMPDIR, - "HOMEBREW_DEV_CMD_RUN" => "true", - "HOMEBREW_USE_RUBY_FROM_PATH" => ENV.fetch("HOMEBREW_USE_RUBY_FROM_PATH", nil), - "GEM_HOME" => nil, + "PATH" => path, + "HOMEBREW_PATH" => path, + "HOMEBREW_BREW_FILE" => HOMEBREW_PREFIX/"bin/brew", + "HOMEBREW_INTEGRATION_TEST" => command_id, + "HOMEBREW_TEST_TMPDIR" => TEST_TMPDIR, + "HOMEBREW_DEV_CMD_RUN" => "true", + "HOMEBREW_USE_RUBY_FROM_PATH" => ENV.fetch("HOMEBREW_USE_RUBY_FROM_PATH", nil), + "HOMEBREW_NO_INSTALL_FROM_API" => ENV.fetch("HOMEBREW_NO_INSTALL_FROM_API", nil), + "GEM_HOME" => nil, ) @ruby_args ||= begin @@ -187,6 +188,7 @@ RSpec.shared_context "integration test" do # rubocop:disable RSpec/ContextWordin end formula_path = Formulary.find_formula_in_tap(name.downcase, tap).tap do |path| + path.dirname.mkpath path.write <<~RUBY class #{Formulary.class_s(name)} < Formula #{content.gsub(/^(?!$)/, " ")} diff --git a/Library/Homebrew/test/tap_spec.rb b/Library/Homebrew/test/tap_spec.rb index 8bea008043..6f60403281 100644 --- a/Library/Homebrew/test/tap_spec.rb +++ b/Library/Homebrew/test/tap_spec.rb @@ -500,7 +500,6 @@ RSpec.describe Tap do end it "includes the core tap with the api" do - ENV.delete("HOMEBREW_NO_INSTALL_FROM_API") expect(described_class.to_a).to include(CoreTap.instance) end @@ -580,7 +579,7 @@ RSpec.describe Tap do let(:cask_tap) { CoreCaskTap.instance } let(:core_tap) { CoreTap.instance } - it "returns expected renames" do + it "returns expected renames", :no_api do [ [cask_tap, "gimp", []], [core_tap, "schism-tracker", []], @@ -744,11 +743,11 @@ RSpec.describe Tap do expect(core_tap).to be_a_core_tap end - specify "forbidden operations" do + specify "forbidden operations", :no_api do expect { core_tap.uninstall }.to raise_error(RuntimeError) end - specify "files" do + specify "files", :no_api do path = HOMEBREW_TAP_DIRECTORY/"homebrew/homebrew-core" formula_file = core_tap.formula_dir/"foo.rb" core_tap.formula_dir.mkpath From d2f9677cdec98064edcf01168aa72e04f231d985 Mon Sep 17 00:00:00 2001 From: Mike McQuaid Date: Tue, 10 Jun 2025 15:55:39 +0100 Subject: [PATCH 29/34] cmd/deps: add warning when not using runtime dependencies. This should provide clarify as to why the output may differ from a formula's declared dependencies. --- Library/Homebrew/cmd/deps.rb | 55 ++++++++++++++++++-------- Library/Homebrew/test/cmd/deps_spec.rb | 2 +- 2 files changed, 40 insertions(+), 17 deletions(-) diff --git a/Library/Homebrew/cmd/deps.rb b/Library/Homebrew/cmd/deps.rb index 5aeb277dbc..06eb7c1817 100644 --- a/Library/Homebrew/cmd/deps.rb +++ b/Library/Homebrew/cmd/deps.rb @@ -18,8 +18,7 @@ module Homebrew If any version of each formula argument is installed and no other options are passed, this command displays their actual runtime dependencies (similar - to `brew linkage`), which may differ from the current versions' stated - dependencies if the installed versions are outdated. + to `brew linkage`), which may differ from a formula's declared dependencies. *Note:* `--missing` and `--skip-recommended` have precedence over `--include-*`. EOS @@ -97,21 +96,45 @@ module Homebrew Formulary.enable_factory_cache! SimulateSystem.with(os:, arch:) do - recursive = !args.direct? - installed = args.installed? || dependents(args.named.to_formulae_and_casks).all?(&:any_version_installed?) + @use_runtime_dependencies = true - @use_runtime_dependencies = installed && recursive && - !args.tree? && - !args.graph? && - !args.HEAD? && - !args.include_implicit? && - !args.include_build? && - !args.include_test? && - !args.include_optional? && - !args.skip_recommended? && - !args.missing? && - args.os.nil? && - args.arch.nil? + installed = args.installed? || dependents(args.named.to_formulae_and_casks).all?(&:any_version_installed?) + unless installed + not_using_runtime_dependencies_reason = if args.installed? + "not all the named formulae were installed" + else + "`--installed` was not passed" + end + + @use_runtime_dependencies = false + end + + %w[direct tree graph HEAD skip_recommended missing + include_implicit include_build include_test include_optional].each do |arg| + next unless args.public_send("#{arg}?") + + not_using_runtime_dependencies_reason = "--#{arg.tr("_", "-")} was passed" + + @use_runtime_dependencies = false + end + + %w[os arch].each do |arg| + next if args.public_send(arg).nil? + + not_using_runtime_dependencies_reason = "--#{arg.tr("_", "-")} was passed" + + @use_runtime_dependencies = false + end + + if !@use_runtime_dependencies && !Homebrew::EnvConfig.no_env_hints? + opoo <<~EOS + `brew deps` is not the actual runtime dependencies because #{not_using_runtime_dependencies_reason}! + This means dependencies may differ from a formula's declared dependencies. + Hide these hints with HOMEBREW_NO_ENV_HINTS (see `man brew`). + EOS + end + + recursive = !args.direct? if args.tree? || args.graph? dependents = if args.named.present? diff --git a/Library/Homebrew/test/cmd/deps_spec.rb b/Library/Homebrew/test/cmd/deps_spec.rb index 80edb94337..10f5991ecf 100644 --- a/Library/Homebrew/test/cmd/deps_spec.rb +++ b/Library/Homebrew/test/cmd/deps_spec.rb @@ -37,6 +37,6 @@ RSpec.describe Homebrew::Cmd::Deps do expect { brew "deps", "baz", "--include-test", "--missing", "--skip-recommended" } .to be_a_success .and output("bar\nfoo\ntest\n").to_stdout - .and not_to_output.to_stderr + .and output(/not the actual runtime dependencies/).to_stderr end end From 0af29dec14e21e6410db5108453a5a8db31035a6 Mon Sep 17 00:00:00 2001 From: BrewTestBot <1589480+BrewTestBot@users.noreply.github.com> Date: Tue, 10 Jun 2025 15:45:47 +0000 Subject: [PATCH 30/34] Update manpage and completions. Autogenerated by the [sponsors-maintainers-man-completions](https://github.com/Homebrew/brew/blob/HEAD/.github/workflows/sponsors-maintainers-man-completions.yml) workflow. --- completions/bash/brew | 1 + completions/fish/brew.fish | 1 + completions/zsh/_brew | 1 + docs/Manpage.md | 4 ++++ manpages/brew.1 | 3 +++ 5 files changed, 10 insertions(+) diff --git a/completions/bash/brew b/completions/bash/brew index b85bd4746c..9b11a30207 100644 --- a/completions/bash/brew +++ b/completions/bash/brew @@ -2588,6 +2588,7 @@ _brew_tests() { --fail-fast --generic --help + --no-parallel --online --only --profile diff --git a/completions/fish/brew.fish b/completions/fish/brew.fish index d6a8a66be7..04701edb8d 100644 --- a/completions/fish/brew.fish +++ b/completions/fish/brew.fish @@ -1693,6 +1693,7 @@ __fish_brew_complete_arg 'tests' -l debug -d 'Enable debugging using `ruby/debug __fish_brew_complete_arg 'tests' -l fail-fast -d 'Exit early on the first failing test' __fish_brew_complete_arg 'tests' -l generic -d 'Run only OS-agnostic tests' __fish_brew_complete_arg 'tests' -l help -d 'Show this message' +__fish_brew_complete_arg 'tests' -l no-parallel -d 'Run tests serially' __fish_brew_complete_arg 'tests' -l online -d 'Include tests that use the GitHub API and tests that use any of the taps for official external commands' __fish_brew_complete_arg 'tests' -l only -d 'Run only `test_script_spec.rb`. Appending `:line_number` will start at a specific line' __fish_brew_complete_arg 'tests' -l profile -d 'Run the test suite serially to find the n slowest tests' diff --git a/completions/zsh/_brew b/completions/zsh/_brew index 4b9ccf6820..fe82678362 100644 --- a/completions/zsh/_brew +++ b/completions/zsh/_brew @@ -2081,6 +2081,7 @@ _brew_tests() { '--fail-fast[Exit early on the first failing test]' \ '--generic[Run only OS-agnostic tests]' \ '--help[Show this message]' \ + '--no-parallel[Run tests serially]' \ '--online[Include tests that use the GitHub API and tests that use any of the taps for official external commands]' \ '(--changed)--only[Run only `test_script_spec.rb`. Appending `:line_number` will start at a specific line]' \ '--profile[Run the test suite serially to find the n slowest tests]' \ diff --git a/docs/Manpage.md b/docs/Manpage.md index f77caf47a4..ade5e545ce 100644 --- a/docs/Manpage.md +++ b/docs/Manpage.md @@ -3211,6 +3211,10 @@ Run Homebrew's unit and integration tests. : Exit early on the first failing test. +`--no-parallel` + +: Run tests serially. + `--only` : Run only `_spec.rb`. Appending `:` will start at a diff --git a/manpages/brew.1 b/manpages/brew.1 index d542a44ac4..3108a75159 100644 --- a/manpages/brew.1 +++ b/manpages/brew.1 @@ -2039,6 +2039,9 @@ Only runs tests on files that were changed from the master branch\. \fB\-\-fail\-fast\fP Exit early on the first failing test\. .TP +\fB\-\-no\-parallel\fP +Run tests serially\. +.TP \fB\-\-only\fP Run only \fB_spec\.rb\fP\&\. Appending \fB:\fP will start at a specific line\. .TP From 8d4395118cc141f376e2d0c98611292faec390af Mon Sep 17 00:00:00 2001 From: Mike McQuaid Date: Tue, 10 Jun 2025 17:28:21 +0100 Subject: [PATCH 31/34] dev-cmd/contributions: improve CSV output. Output messages to stderr when CSV output is enabled. This allows doing `brew contributions --csv > contributions.csv` to save the output to a file. --- Library/Homebrew/dev-cmd/contributions.rb | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Library/Homebrew/dev-cmd/contributions.rb b/Library/Homebrew/dev-cmd/contributions.rb index 2be6135a48..57a5fe79a3 100644 --- a/Library/Homebrew/dev-cmd/contributions.rb +++ b/Library/Homebrew/dev-cmd/contributions.rb @@ -88,16 +88,21 @@ module Homebrew contributions << "#{Utils.pluralize("time", grand_totals[username].values.sum, include_count: true)} (total)" - puts [ + contributions_string = [ "#{username} contributed", *contributions.to_sentence, "#{time_period(from:, to: args.to)}.", ].join(" ") + if args.csv? + $stderr.puts contributions_string + else + puts contributions_string + end end return unless args.csv? - puts + $stderr.puts puts generate_csv(grand_totals) end From ea8152757e4ddde54ea83eb03d6071c689b70078 Mon Sep 17 00:00:00 2001 From: Eric Knibbe Date: Tue, 10 Jun 2025 13:51:06 -0400 Subject: [PATCH 32/34] rubocops/cask/no_overrides: avoid nested `depends_on macos:` --- .../Homebrew/rubocops/cask/no_overrides.rb | 20 +++++++--- .../test/rubocops/cask/no_overrides_spec.rb | 39 +++++++++++++++++++ .../Casks/with-depends-on-macos-failure.rb | 18 ++++----- 3 files changed, 62 insertions(+), 15 deletions(-) diff --git a/Library/Homebrew/rubocops/cask/no_overrides.rb b/Library/Homebrew/rubocops/cask/no_overrides.rb index 6f313f41ed..1eeb1e1df8 100644 --- a/Library/Homebrew/rubocops/cask/no_overrides.rb +++ b/Library/Homebrew/rubocops/cask/no_overrides.rb @@ -11,14 +11,14 @@ module RuboCop # TODO: Update this list if new stanzas are added to `Cask::DSL` that call `set_unique_stanza`. OVERRIDABLE_METHODS = [ :appcast, :arch, :auto_updates, :conflicts_with, :container, - :desc, :homepage, :sha256, :url, :version + :desc, :homepage, :os, :sha256, :url, :version ].freeze - MESSAGE = "Do not use a top-level `%s` stanza as the default. " \ - "Add it to an `on_{system}` block instead. " \ - "Use `:or_older` or `:or_newer` to specify a range of macOS versions." sig { override.params(cask_block: RuboCop::Cask::AST::CaskBlock).void } def on_cask(cask_block) + message = "Do not use a top-level `%s` stanza as the default. " \ + "Add it to an `on_{system}` block instead. " \ + "Use `:or_older` or `:or_newer` to specify a range of macOS versions." cask_stanzas = cask_block.toplevel_stanzas return if (on_blocks = on_system_methods(cask_stanzas)).none? @@ -31,12 +31,14 @@ module RuboCop # Skip if the stanza outside of a block is not also in an `on_*` block. next unless stanzas_in_blocks.include?(stanza.stanza_name) - add_offense(stanza.source_range, message: format(MESSAGE, stanza: stanza.stanza_name)) + add_offense(stanza.source_range, message: format(message, stanza: stanza.stanza_name)) end end sig { params(on_system: T::Array[RuboCop::Cask::AST::Stanza]).returns(T::Set[Symbol]) } def on_system_stanzas(on_system) + message = "Do not use a `depends_on macos:` stanza inside an `on_{system}` block. " \ + "Add it once to specify the oldest macOS supported by any version in the cask." names = T.let(Set.new, T::Set[Symbol]) method_nodes = on_system.map(&:method_node) method_nodes.select(&:block_type?).each do |node| @@ -51,6 +53,14 @@ module RuboCop end next if RuboCop::Cask::Constants::ON_SYSTEM_METHODS.include?(send_node.method_name) + if send_node.method_name == :depends_on && + send_node.arguments.first.pairs.any? { |a| a.key.value == :macos } && + OnSystemConditionalsHelper::ON_SYSTEM_OPTIONS.map do |m| + :"on_#{m}" + end.include?(T.cast(node, RuboCop::AST::BlockNode).method_name) + add_offense(send_node.source_range, message:) + end + names.add(send_node.method_name) end end diff --git a/Library/Homebrew/test/rubocops/cask/no_overrides_spec.rb b/Library/Homebrew/test/rubocops/cask/no_overrides_spec.rb index 3b68c05a32..ba7de8e7b4 100644 --- a/Library/Homebrew/test/rubocops/cask/no_overrides_spec.rb +++ b/Library/Homebrew/test/rubocops/cask/no_overrides_spec.rb @@ -173,4 +173,43 @@ RSpec.describe RuboCop::Cop::Cask::NoOverrides, :config do end CASK end + + it "accepts when there is a top-level `depends_on macos:` stanza" do + expect_no_offenses <<~CASK + cask 'foo' do + version '1.2.3' + url 'https://brew.sh/foo.pkg' + + depends_on macos: ">= :sequoia" + + name 'Foo' + end + CASK + end + + it "reports an offense when `on_*` blocks contain a `depends_on macos:` stanza" do + expect_offense <<~CASK + cask 'foo' do + version '1.2.3' + + on_sequoia :or_newer do + sha256 "aaa" + url "https://brew.sh/foo-mac.dmg" + + depends_on macos: ">= :sequoia" + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not use a `depends_on macos:` stanza inside an `on_{system}` block. Add it once to specify the oldest macOS supported by any version in the cask. + end + + on_arm do + sha256 "bbb" + url "https://brew.sh/foo-arm.dmg" + + depends_on macos: ">= :sequoia" + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not use a `depends_on macos:` stanza inside an `on_{system}` block. Add it once to specify the oldest macOS supported by any version in the cask. + end + + name 'Foo' + end + CASK + end end diff --git a/Library/Homebrew/test/support/fixtures/cask/Casks/with-depends-on-macos-failure.rb b/Library/Homebrew/test/support/fixtures/cask/Casks/with-depends-on-macos-failure.rb index bbde7db9c3..a65cde70d0 100644 --- a/Library/Homebrew/test/support/fixtures/cask/Casks/with-depends-on-macos-failure.rb +++ b/Library/Homebrew/test/support/fixtures/cask/Casks/with-depends-on-macos-failure.rb @@ -1,20 +1,18 @@ cask "with-depends-on-macos-failure" do - version "1.2.3" - sha256 "67cdb8a02803ef37fdbf7e0be205863172e41a561ca446cd84f0d7ab35a99d94" - # guarantee a mismatched release - on_mojave :or_older do - depends_on macos: :catalina + on_big_sur :or_older do + version "1.2.3" + sha256 "67cdb8a02803ef37fdbf7e0be205863172e41a561ca446cd84f0d7ab35a99d94" end - on_catalina do - depends_on macos: :mojave - end - on_big_sur :or_newer do - depends_on macos: :catalina + on_ventura :or_newer do + version "1.2.3" + sha256 "67cdb8a02803ef37fdbf7e0be205863172e41a561ca446cd84f0d7ab35a99d94" end url "file://#{TEST_FIXTURE_DIR}/cask/caffeine.zip" homepage "https://brew.sh/with-depends-on-macos-failure" + depends_on macos: :monterey + app "Caffeine.app" end From 347b28796710ea11c37a6ed8bbc46e4b1c603a86 Mon Sep 17 00:00:00 2001 From: BrewTestBot <1589480+BrewTestBot@users.noreply.github.com> Date: Tue, 10 Jun 2025 21:00:09 +0000 Subject: [PATCH 33/34] Update manpage and completions. Autogenerated by the [sponsors-maintainers-man-completions](https://github.com/Homebrew/brew/blob/HEAD/.github/workflows/sponsors-maintainers-man-completions.yml) workflow. --- docs/Manpage.md | 3 +-- manpages/brew.1 | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/docs/Manpage.md b/docs/Manpage.md index ade5e545ce..082d03949d 100644 --- a/docs/Manpage.md +++ b/docs/Manpage.md @@ -397,8 +397,7 @@ required and recommended dependencies. If any version of each formula argument is installed and no other options are passed, this command displays their actual runtime dependencies (similar to -`brew linkage`), which may differ from the current versions' stated dependencies -if the installed versions are outdated. +`brew linkage`), which may differ from a formula's declared dependencies. *Note:* `--missing` and `--skip-recommended` have precedence over `--include-*`. diff --git a/manpages/brew.1 b/manpages/brew.1 index 3108a75159..a0bcbde4e4 100644 --- a/manpages/brew.1 +++ b/manpages/brew.1 @@ -241,7 +241,7 @@ Show Homebrew and system configuration info useful for debugging\. If you file a .SS "\fBdeps\fP \fR[\fIoptions\fP] \fR[\fIformula\fP|\fIcask\fP \.\.\.]" Show dependencies for \fIformula\fP\&\. When given multiple formula arguments, show the intersection of dependencies for each formula\. By default, \fBdeps\fP shows all required and recommended dependencies\. .P -If any version of each formula argument is installed and no other options are passed, this command displays their actual runtime dependencies (similar to \fBbrew linkage\fP), which may differ from the current versions\[u2019] stated dependencies if the installed versions are outdated\. +If any version of each formula argument is installed and no other options are passed, this command displays their actual runtime dependencies (similar to \fBbrew linkage\fP), which may differ from a formula\[u2019]s declared dependencies\. .P \fINote:\fP \fB\-\-missing\fP and \fB\-\-skip\-recommended\fP have precedence over \fB\-\-include\-*\fP\&\. .TP From 837b28ba796961d47faa53b763d92d15e49c42a6 Mon Sep 17 00:00:00 2001 From: Mike McQuaid Date: Wed, 11 Jun 2025 08:38:32 +0100 Subject: [PATCH 34/34] cmd/update: attempt migration from `master` to `main` branch. This should allow any repositories that change from `master` to `main` to be automatically migrated by `brew update` without requiring manual intervention or displaying errors to the user. --- Library/Homebrew/cmd/update.sh | 60 +++++++++++++++++++++++----------- 1 file changed, 41 insertions(+), 19 deletions(-) diff --git a/Library/Homebrew/cmd/update.sh b/Library/Homebrew/cmd/update.sh index efb3796146..81439dbe21 100644 --- a/Library/Homebrew/cmd/update.sh +++ b/Library/Homebrew/cmd/update.sh @@ -725,31 +725,53 @@ EOS local tmp_failure_file="${DIR}/.git/TMP_FETCH_FAILURES" rm -f "${tmp_failure_file}" - if [[ -n "${HOMEBREW_UPDATE_AUTO}" ]] + if ! git fetch --tags --force "${QUIET_ARGS[@]}" origin \ + "refs/heads/${UPSTREAM_BRANCH_DIR}:refs/remotes/origin/${UPSTREAM_BRANCH_DIR}" 2>>"${tmp_failure_file}" then - git fetch --tags --force "${QUIET_ARGS[@]}" origin \ - "refs/heads/${UPSTREAM_BRANCH_DIR}:refs/remotes/origin/${UPSTREAM_BRANCH_DIR}" 2>/dev/null - else - # Capture stderr to tmp_failure_file - if ! git fetch --tags --force "${QUIET_ARGS[@]}" origin \ - "refs/heads/${UPSTREAM_BRANCH_DIR}:refs/remotes/origin/${UPSTREAM_BRANCH_DIR}" 2>>"${tmp_failure_file}" + if [[ -f "${tmp_failure_file}" ]] then - # Reprint fetch errors to stderr - [[ -f "${tmp_failure_file}" ]] && cat "${tmp_failure_file}" 1>&2 - - if [[ "${UPSTREAM_SHA_HTTP_CODE}" == "404" ]] + local git_errors + git_errors="$(cat "${tmp_failure_file}")" + if [[ "${git_errors}" == "fatal: couldn't find remote ref refs/heads/master" ]] then - TAP="${DIR#"${HOMEBREW_LIBRARY}"/Taps/}" - echo "${TAP} does not exist! Run \`brew untap ${TAP}\` to remove it." >>"${update_failed_file}" - else - echo "Fetching ${DIR} failed!" >>"${update_failed_file}" - - if [[ -f "${tmp_failure_file}" ]] && - [[ "$(cat "${tmp_failure_file}")" == "fatal: couldn't find remote ref refs/heads/${UPSTREAM_BRANCH_DIR}" ]] + # Attempt migration from master to main branch. + if git fetch --tags --force "${QUIET_ARGS[@]}" origin \ + "refs/heads/main:refs/remotes/origin/main" 2>>"${tmp_failure_file}" then - echo "${DIR}" >>"${missing_remote_ref_dirs_file}" + rm -f "${DIR}/.git/refs/remotes/origin/HEAD" "${DIR}/.git/refs/remotes/origin/master" + UPSTREAM_BRANCH_DIR="$(upstream_branch)" + declare UPSTREAM_BRANCH"${TAP_VAR}"="${UPSTREAM_BRANCH_DIR}" + git branch -m master main "${QUIET_ARGS[@]}" + git branch -u origin/main main "${QUIET_ARGS[@]}" + rm -f "${tmp_failure_file}" + exit fi fi + + rm -f "${tmp_failure_file}" + fi + + # Don't output errors if HOMEBREW_UPDATE_AUTO is set. + if [[ -n "${HOMEBREW_UPDATE_AUTO}" ]] + then + exit + fi + + # Reprint fetch errors to stderr + [[ -n "${git_errors}" ]] && echo "${git_errors}" 1>&2 + + if [[ "${UPSTREAM_SHA_HTTP_CODE}" == "404" ]] + then + TAP="${DIR#"${HOMEBREW_LIBRARY}"/Taps/}" + echo "${TAP} does not exist! Run \`brew untap ${TAP}\` to remove it." >>"${update_failed_file}" + else + echo "Fetching ${DIR} failed!" >>"${update_failed_file}" + + if [[ -f "${tmp_failure_file}" ]] && + [[ "$(cat "${tmp_failure_file}")" == "fatal: couldn't find remote ref refs/heads/${UPSTREAM_BRANCH_DIR}" ]] + then + echo "${DIR}" >>"${missing_remote_ref_dirs_file}" + fi fi fi