diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index f3f4078ce5027..12c6f8444b8f3 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -24,7 +24,7 @@ jobs: restore-keys: ${{ runner.os }}-rubygems- - name: Install Bundler RubyGems - run: brew install-bundler-gems + run: brew install-bundler-gems --groups=sorbet - name: Install shellcheck run: brew install shellcheck @@ -60,7 +60,7 @@ jobs: restore-keys: ${{ runner.os }}-rubygems- - name: Install Bundler RubyGems - run: brew install-bundler-gems + run: brew install-bundler-gems --groups=sorbet - run: brew doctor @@ -152,7 +152,7 @@ jobs: # Can't cache this because we need to check that it doesn't fail the # "uncommitted RubyGems" step with a cold cache. - name: Install Bundler RubyGems - run: brew install-bundler-gems + run: brew install-bundler-gems --groups=sorbet - name: Check for uncommitted RubyGems run: git diff --stat --exit-code Library/Homebrew/vendor/bundle/ruby @@ -206,7 +206,7 @@ jobs: restore-keys: ${{ runner.os }}-rubygems- - name: Install Bundler RubyGems - run: brew install-bundler-gems + run: brew install-bundler-gems --groups=sorbet - name: Create parallel test log directory run: mkdir tests @@ -265,7 +265,7 @@ jobs: # Can't cache this because we need to check that it doesn't fail the # "uncommitted RubyGems" step with a cold cache. - name: Install Bundler RubyGems - run: brew install-bundler-gems + run: brew install-bundler-gems --groups=sorbet - name: Check for uncommitted RubyGems run: git diff --stat --exit-code Library/Homebrew/vendor/bundle/ruby diff --git a/Library/Homebrew/.bundle/config b/Library/Homebrew/.bundle/config index 24c48a4c9df4d..e2c528e14d425 100644 --- a/Library/Homebrew/.bundle/config +++ b/Library/Homebrew/.bundle/config @@ -2,6 +2,7 @@ BUNDLE_BIN: "false" BUNDLE_CLEAN: "true" BUNDLE_DISABLE_SHARED_GEMS: "true" +BUNDLE_FORGET_CLI_OPTIONS: "true" BUNDLE_JOBS: "4" BUNDLE_PATH: "vendor/bundle" BUNDLE_RETRY: "3" diff --git a/Library/Homebrew/.rubocop_todo.yml b/Library/Homebrew/.rubocop_todo.yml index dc0b0f6ba9f7d..ad5c59bac70ba 100644 --- a/Library/Homebrew/.rubocop_todo.yml +++ b/Library/Homebrew/.rubocop_todo.yml @@ -8,6 +8,7 @@ Style/Documentation: - "cask/macos.rb" - "cli/args.rb" - "cli/parser.rb" + - "default_prefix.rb" - "global.rb" - "keg_relocate.rb" - "os/linux/global.rb" diff --git a/Library/Homebrew/Gemfile b/Library/Homebrew/Gemfile index 5c755eab6b1d5..70c9b44ba22aa 100644 --- a/Library/Homebrew/Gemfile +++ b/Library/Homebrew/Gemfile @@ -13,17 +13,20 @@ gem "rspec", require: false gem "rspec-github", require: false gem "rspec-its", require: false gem "rspec-retry", require: false -gem "rspec-sorbet", require: false gem "rspec-wait", require: false gem "rubocop", require: false gem "rubocop-ast", require: false gem "simplecov", require: false gem "simplecov-cobertura", require: false -gem "sorbet", require: false -gem "sorbet-runtime", require: false -gem "tapioca", require: false gem "warning", require: false +group :sorbet, optional: true do + gem "rspec-sorbet", require: false + gem "sorbet", require: false + gem "sorbet-runtime", require: false + gem "tapioca", require: false +end + # vendored gems gem "activesupport" gem "concurrent-ruby" diff --git a/Library/Homebrew/cli/args.rbi b/Library/Homebrew/cli/args.rbi index 69ff5360b8024..9b4429dd77a2e 100644 --- a/Library/Homebrew/cli/args.rbi +++ b/Library/Homebrew/cli/args.rbi @@ -275,6 +275,9 @@ module Homebrew sig { returns(T.nilable(String)) } def screen_saverdir; end + + sig { returns(T.nilable(T::Array[String])) } + def groups; end end end end diff --git a/Library/Homebrew/config.rbi b/Library/Homebrew/config.rbi new file mode 100644 index 0000000000000..2cab9bf6d521a --- /dev/null +++ b/Library/Homebrew/config.rbi @@ -0,0 +1,6 @@ +# typed: strict + +module EnvVar + sig { params(env: String).returns(String) } + def self.[](env); end +end diff --git a/Library/Homebrew/default_prefix.rb b/Library/Homebrew/default_prefix.rb new file mode 100644 index 0000000000000..4e2f6f1ee4284 --- /dev/null +++ b/Library/Homebrew/default_prefix.rb @@ -0,0 +1,12 @@ +# typed: true +# frozen_string_literal: true + +module Homebrew + DEFAULT_PREFIX, DEFAULT_REPOSITORY = if OS.mac? && Hardware::CPU.arm? + [HOMEBREW_MACOS_ARM_DEFAULT_PREFIX, HOMEBREW_MACOS_ARM_DEFAULT_REPOSITORY] + elsif OS.linux? && !EnvConfig.force_homebrew_on_linux? + [HOMEBREW_LINUX_DEFAULT_PREFIX, HOMEBREW_LINUX_DEFAULT_REPOSITORY] + else + [HOMEBREW_DEFAULT_PREFIX, HOMEBREW_DEFAULT_REPOSITORY] + end.freeze +end diff --git a/Library/Homebrew/dev-cmd/install-bundler-gems.rb b/Library/Homebrew/dev-cmd/install-bundler-gems.rb index 73ba1f7f49402..a5dd4d015be91 100644 --- a/Library/Homebrew/dev-cmd/install-bundler-gems.rb +++ b/Library/Homebrew/dev-cmd/install-bundler-gems.rb @@ -15,14 +15,19 @@ def install_bundler_gems_args description <<~EOS Install Homebrew's Bundler gems. EOS + comma_array "--groups=", + description: "Installs the specified comma-separated list of gem groups (default: last used)." named_args :none end end def install_bundler_gems - install_bundler_gems_args.parse + args = install_bundler_gems_args.parse - Homebrew.install_bundler_gems! + # Clear previous settings. We want to fully replace - not append. + Homebrew::Settings.delete(:gemgroups) if args.groups + + Homebrew.install_bundler_gems!(groups: args.groups || []) end end diff --git a/Library/Homebrew/dev-cmd/tests.rb b/Library/Homebrew/dev-cmd/tests.rb index 3638033b45456..f35117e56e951 100644 --- a/Library/Homebrew/dev-cmd/tests.rb +++ b/Library/Homebrew/dev-cmd/tests.rb @@ -39,15 +39,17 @@ def tests_args def tests args = tests_args.parse - Homebrew.install_bundler_gems! + Homebrew.install_bundler_gems!(groups: ["sorbet"]) require "byebug" if args.byebug? HOMEBREW_LIBRARY_PATH.cd do # Cleanup any unwanted user configuration. - allowed_test_env = [ - "HOMEBREW_GITHUB_API_TOKEN", - "HOMEBREW_TEMP", + allowed_test_env = %w[ + HOMEBREW_GITHUB_API_TOKEN + HOMEBREW_CACHE + HOMEBREW_LOGS + HOMEBREW_TEMP ] Homebrew::EnvConfig::ENVS.keys.map(&:to_s).each do |env| next if allowed_test_env.include?(env) diff --git a/Library/Homebrew/dev-cmd/typecheck.rb b/Library/Homebrew/dev-cmd/typecheck.rb index 6826b4188402d..daa595491e682 100644 --- a/Library/Homebrew/dev-cmd/typecheck.rb +++ b/Library/Homebrew/dev-cmd/typecheck.rb @@ -51,7 +51,7 @@ def typecheck args = typecheck_args.parse - Homebrew.install_bundler_gems! + Homebrew.install_bundler_gems!(groups: ["sorbet"]) HOMEBREW_LIBRARY_PATH.cd do if args.update? diff --git a/Library/Homebrew/dev-cmd/vendor-gems.rb b/Library/Homebrew/dev-cmd/vendor-gems.rb index 56e1de3a48d3d..6a8b62f5a85dc 100644 --- a/Library/Homebrew/dev-cmd/vendor-gems.rb +++ b/Library/Homebrew/dev-cmd/vendor-gems.rb @@ -29,6 +29,8 @@ def vendor_gems Homebrew.install_bundler! + ENV["BUNDLE_WITH"] = "sorbet" + ohai "cd #{HOMEBREW_LIBRARY_PATH}" HOMEBREW_LIBRARY_PATH.cd do if args.update diff --git a/Library/Homebrew/diagnostic.rb b/Library/Homebrew/diagnostic.rb index b8d45ae666f0e..683a2a5bd094a 100644 --- a/Library/Homebrew/diagnostic.rb +++ b/Library/Homebrew/diagnostic.rb @@ -149,7 +149,9 @@ def examine_git_origin(repository_path, desired_origin) def broken_tap(tap) return unless Utils::Git.available? - return unless HOMEBREW_REPOSITORY.git? + + repo = HOMEBREW_REPOSITORY.dup.extend(GitRepositoryExtension) + return unless repo.git? message = <<~EOS #{tap.full_name} was not tapped properly! Run: @@ -161,7 +163,7 @@ def broken_tap(tap) tap_head = tap.git_head return message if tap_head.blank? - return if tap_head != HOMEBREW_REPOSITORY.git_head + return if tap_head != repo.git_head message end @@ -574,7 +576,8 @@ def check_git_newline_settings end def check_brew_git_origin - examine_git_origin(HOMEBREW_REPOSITORY, Homebrew::EnvConfig.brew_git_remote) + repo = HOMEBREW_REPOSITORY.dup.extend(GitRepositoryExtension) + examine_git_origin(repo, Homebrew::EnvConfig.brew_git_remote) end def check_coretap_integrity diff --git a/Library/Homebrew/global.rb b/Library/Homebrew/global.rb index d668dac471d6a..15454796e1a4c 100644 --- a/Library/Homebrew/global.rb +++ b/Library/Homebrew/global.rb @@ -1,22 +1,16 @@ # typed: false # frozen_string_literal: true -require_relative "load_path" +require_relative "startup" require "English" require "fileutils" require "json" require "json/add/exception" -require "pathname" require "ostruct" require "pp" require "forwardable" -require "rbconfig" - -RUBY_PATH = Pathname.new(RbConfig.ruby).freeze -RUBY_BIN = RUBY_PATH.dirname.freeze - # Only require "core_ext" here to ensure we're only requiring the minimum of # what we need. require "active_support/core_ext/object/blank" @@ -72,27 +66,15 @@ %r[https://github\.com/([\w-]+)/([\w-]+)?/(?:pull/(\d+)|commit/[0-9a-fA-F]{4,40})].freeze HOMEBREW_BOTTLES_EXTNAME_REGEX = /\.([a-z0-9_]+)\.bottle\.(?:(\d+)\.)?tar\.gz$/.freeze -require "utils/sorbet" - require "env_config" require "compat/early" unless Homebrew::EnvConfig.no_compat? require "os" require "messages" +require "default_prefix" module Homebrew extend FileUtils - remove_const :DEFAULT_PREFIX if defined?(DEFAULT_PREFIX) - remove_const :DEFAULT_REPOSITORY if defined?(DEFAULT_REPOSITORY) - - DEFAULT_PREFIX, DEFAULT_REPOSITORY = if OS.mac? && Hardware::CPU.arm? - [HOMEBREW_MACOS_ARM_DEFAULT_PREFIX, HOMEBREW_MACOS_ARM_DEFAULT_REPOSITORY] - elsif OS.linux? && !EnvConfig.force_homebrew_on_linux? - [HOMEBREW_LINUX_DEFAULT_PREFIX, HOMEBREW_LINUX_DEFAULT_REPOSITORY] - else - [HOMEBREW_DEFAULT_PREFIX, HOMEBREW_DEFAULT_REPOSITORY] - end.freeze - DEFAULT_CELLAR = "#{DEFAULT_PREFIX}/Cellar" DEFAULT_MACOS_CELLAR = "#{HOMEBREW_DEFAULT_PREFIX}/Cellar" DEFAULT_MACOS_ARM_CELLAR = "#{HOMEBREW_MACOS_ARM_DEFAULT_PREFIX}/Cellar" @@ -124,8 +106,8 @@ def auditing? end end -require "config" require "context" +require "extend/git_repository" require "extend/pathname" require "extend/predicable" require "extend/module" diff --git a/Library/Homebrew/rubocops.rb b/Library/Homebrew/rubocops.rb index 3190abc5863b2..3e5daa64c331e 100644 --- a/Library/Homebrew/rubocops.rb +++ b/Library/Homebrew/rubocops.rb @@ -1,40 +1,6 @@ # typed: strict # frozen_string_literal: true -require_relative "load_path" +require_relative "standalone" -require "active_support/core_ext/array/conversions" - -require "utils/sorbet" - -require "rubocop-performance" -require "rubocop-rails" -require "rubocop-rspec" -require "rubocop-sorbet" - -require "rubocops/io_read" -require "rubocops/shell_commands" - -require "rubocops/formula_desc" -require "rubocops/components_order" -require "rubocops/components_redundancy" -require "rubocops/dependency_order" -require "rubocops/homepage" -require "rubocops/text" -require "rubocops/caveats" -require "rubocops/checksum" -require "rubocops/patches" -require "rubocops/conflicts" -require "rubocops/options" -require "rubocops/urls" -require "rubocops/lines" -require "rubocops/livecheck" -require "rubocops/class" -require "rubocops/uses_from_macos" -require "rubocops/files" -require "rubocops/keg_only" -require "rubocops/version" -require "rubocops/deprecate_disable" -require "rubocops/bottle" - -require "rubocops/rubocop-cask" +require "rubocops/all" diff --git a/Library/Homebrew/rubocops/all.rb b/Library/Homebrew/rubocops/all.rb new file mode 100644 index 0000000000000..40bf1eab43681 --- /dev/null +++ b/Library/Homebrew/rubocops/all.rb @@ -0,0 +1,36 @@ +# typed: strict +# frozen_string_literal: true + +require "active_support/core_ext/array/conversions" + +require "rubocop-performance" +require "rubocop-rails" +require "rubocop-rspec" +require "rubocop-sorbet" + +require_relative "io_read" +require_relative "shell_commands" + +require_relative "formula_desc" +require_relative "components_order" +require_relative "components_redundancy" +require_relative "dependency_order" +require_relative "homepage" +require_relative "text" +require_relative "caveats" +require_relative "checksum" +require_relative "patches" +require_relative "conflicts" +require_relative "options" +require_relative "urls" +require_relative "lines" +require_relative "livecheck" +require_relative "class" +require_relative "uses_from_macos" +require_relative "files" +require_relative "keg_only" +require_relative "version" +require_relative "deprecate_disable" +require_relative "bottle" + +require_relative "rubocop-cask" diff --git a/Library/Homebrew/rubocops/rubocop-cask.rb b/Library/Homebrew/rubocops/rubocop-cask.rb index 3e0a2c457865b..4dac4d062fc6c 100644 --- a/Library/Homebrew/rubocops/rubocop-cask.rb +++ b/Library/Homebrew/rubocops/rubocop-cask.rb @@ -3,17 +3,17 @@ require "rubocop" -require "rubocops/cask/constants/stanza" +require_relative "cask/constants/stanza" -require "rubocops/cask/ast/stanza" -require "rubocops/cask/ast/cask_header" -require "rubocops/cask/ast/cask_block" -require "rubocops/cask/extend/string" -require "rubocops/cask/extend/node" -require "rubocops/cask/mixin/cask_help" -require "rubocops/cask/mixin/on_homepage_stanza" -require "rubocops/cask/desc" -require "rubocops/cask/homepage_url_trailing_slash" -require "rubocops/cask/no_dsl_version" -require "rubocops/cask/stanza_order" -require "rubocops/cask/stanza_grouping" +require_relative "cask/ast/stanza" +require_relative "cask/ast/cask_header" +require_relative "cask/ast/cask_block" +require_relative "cask/extend/string" +require_relative "cask/extend/node" +require_relative "cask/mixin/cask_help" +require_relative "cask/mixin/on_homepage_stanza" +require_relative "cask/desc" +require_relative "cask/homepage_url_trailing_slash" +require_relative "cask/no_dsl_version" +require_relative "cask/stanza_order" +require_relative "cask/stanza_grouping" diff --git a/Library/Homebrew/settings.rb b/Library/Homebrew/settings.rb index 8a58e94199fe0..f04820eef2c06 100644 --- a/Library/Homebrew/settings.rb +++ b/Library/Homebrew/settings.rb @@ -1,26 +1,25 @@ # typed: true # frozen_string_literal: true -require "system_command" +require "utils/popen" module Homebrew # Helper functions for reading and writing settings. # # @api private module Settings - extend T::Sig - include SystemCommand::Mixin - module_function - sig { params(setting: T.any(String, Symbol), repo: Pathname).returns(T.nilable(String)) } def read(setting, repo: HOMEBREW_REPOSITORY) return unless (repo/".git/config").exist? - system_command("git", args: ["config", "--get", "homebrew.#{setting}"], chdir: repo).stdout.chomp.presence + value = Utils.popen_read("git", "-C", repo.to_s, "config", "--get", "homebrew.#{setting}").chomp + + return if value.strip.empty? + + value end - sig { params(setting: T.any(String, Symbol), value: T.any(String, T::Boolean), repo: Pathname).void } def write(setting, value, repo: HOMEBREW_REPOSITORY) return unless (repo/".git/config").exist? @@ -28,16 +27,15 @@ def write(setting, value, repo: HOMEBREW_REPOSITORY) return if read(setting, repo: repo) == value - system_command! "git", args: ["config", "--replace-all", "homebrew.#{setting}", value], chdir: repo + Kernel.system("git", "-C", repo.to_s, "config", "--replace-all", "homebrew.#{setting}", value, exception: true) end - sig { params(setting: T.any(String, Symbol), repo: Pathname).void } def delete(setting, repo: HOMEBREW_REPOSITORY) return unless (repo/".git/config").exist? return if read(setting, repo: repo).blank? - system_command! "git", args: ["config", "--unset-all", "homebrew.#{setting}"], chdir: repo + Kernel.system("git", "-C", repo.to_s, "config", "--unset-all", "homebrew.#{setting}", exception: true) end end end diff --git a/Library/Homebrew/settings.rbi b/Library/Homebrew/settings.rbi index 289622fd41958..d902c06acb7c8 100644 --- a/Library/Homebrew/settings.rbi +++ b/Library/Homebrew/settings.rbi @@ -3,5 +3,14 @@ module Homebrew module Settings include Kernel + + sig { params(setting: T.any(String, Symbol), repo: Pathname).returns(T.nilable(String)) } + def read(setting, repo: HOMEBREW_REPOSITORY); end + + sig { params(setting: T.any(String, Symbol), value: T.any(String, T::Boolean), repo: Pathname).void } + def write(setting, value, repo: HOMEBREW_REPOSITORY); end + + sig { params(setting: T.any(String, Symbol), repo: Pathname).void } + def delete(setting, repo: HOMEBREW_REPOSITORY); end end end diff --git a/Library/Homebrew/standalone.rb b/Library/Homebrew/standalone.rb new file mode 100644 index 0000000000000..cb540077a1a29 --- /dev/null +++ b/Library/Homebrew/standalone.rb @@ -0,0 +1,7 @@ +# typed: true +# frozen_string_literal: true + +# This file should be the first `require` in all entrypoints outside the `brew` environment. + +require_relative "standalone/load_path" +require_relative "standalone/sorbet" diff --git a/Library/Homebrew/load_path.rb b/Library/Homebrew/standalone/load_path.rb similarity index 82% rename from Library/Homebrew/load_path.rb rename to Library/Homebrew/standalone/load_path.rb index a5c65fb680876..ff7daed613d06 100644 --- a/Library/Homebrew/load_path.rb +++ b/Library/Homebrew/standalone/load_path.rb @@ -3,13 +3,13 @@ require "pathname" -HOMEBREW_LIBRARY_PATH = Pathname(__dir__).realpath.freeze +HOMEBREW_LIBRARY_PATH = Pathname(__dir__).parent.realpath.freeze -require_relative "utils/gems" +require_relative "../utils/gems" Homebrew.setup_gem_environment!(setup_path: false) $LOAD_PATH.push HOMEBREW_LIBRARY_PATH.to_s unless $LOAD_PATH.include?(HOMEBREW_LIBRARY_PATH.to_s) -require_relative "vendor/bundle/bundler/setup" +require_relative "../vendor/bundle/bundler/setup" $LOAD_PATH.uniq! # Block any gem loading by bypassing rubygem's `require`. @@ -21,5 +21,3 @@ Kernel.send(:define_method, :require, Kernel.instance_method(:gem_original_require)) Kernel.send(:private, :require) end - -require_relative "homebrew_bootsnap" diff --git a/Library/Homebrew/standalone/sorbet.rb b/Library/Homebrew/standalone/sorbet.rb new file mode 100644 index 0000000000000..8576c7ad0ddd0 --- /dev/null +++ b/Library/Homebrew/standalone/sorbet.rb @@ -0,0 +1,11 @@ +# typed: true +# frozen_string_literal: true + +# Explicitly prevent `sorbet-runtime` from being loaded. +def gem(name, *) + raise Gem::LoadError if name == "sorbet-runtime" + + super +end + +require "sorbet-runtime-stub" diff --git a/Library/Homebrew/startup.rb b/Library/Homebrew/startup.rb new file mode 100644 index 0000000000000..d08f5420cf765 --- /dev/null +++ b/Library/Homebrew/startup.rb @@ -0,0 +1,10 @@ +# typed: true +# frozen_string_literal: true + +# This file should be the first `require` in all entrypoints of `brew`. + +require_relative "standalone/load_path" +require_relative "startup/ruby_path" +require "startup/config" +require_relative "startup/bootsnap" +require_relative "startup/sorbet" diff --git a/Library/Homebrew/homebrew_bootsnap.rb b/Library/Homebrew/startup/bootsnap.rb similarity index 100% rename from Library/Homebrew/homebrew_bootsnap.rb rename to Library/Homebrew/startup/bootsnap.rb diff --git a/Library/Homebrew/config.rb b/Library/Homebrew/startup/config.rb similarity index 90% rename from Library/Homebrew/config.rb rename to Library/Homebrew/startup/config.rb index 4369b95616ad4..29d3088bff4f6 100644 --- a/Library/Homebrew/config.rb +++ b/Library/Homebrew/startup/config.rb @@ -12,9 +12,6 @@ class MissingEnvironmentVariables < RuntimeError; end # # @api private module EnvVar - extend T::Sig - - sig { params(env: String).returns(String) } def self.[](env) raise MissingEnvironmentVariables, "#{env} was not exported!" unless ENV[env] @@ -22,15 +19,11 @@ def self.[](env) end end -require "extend/git_repository" - # Where we link under HOMEBREW_PREFIX = Pathname(EnvVar["HOMEBREW_PREFIX"]).freeze # Where `.git` is found -HOMEBREW_REPOSITORY = Pathname(EnvVar["HOMEBREW_REPOSITORY"]) - .extend(GitRepositoryExtension) - .freeze +HOMEBREW_REPOSITORY = Pathname(EnvVar["HOMEBREW_REPOSITORY"]).freeze # Where we store most of Homebrew, taps, and various metadata HOMEBREW_LIBRARY = Pathname(EnvVar["HOMEBREW_LIBRARY"]).freeze diff --git a/Library/Homebrew/startup/ruby_path.rb b/Library/Homebrew/startup/ruby_path.rb new file mode 100644 index 0000000000000..e9a7a634fbda2 --- /dev/null +++ b/Library/Homebrew/startup/ruby_path.rb @@ -0,0 +1,7 @@ +# typed: true +# frozen_string_literal: true + +require "rbconfig" + +RUBY_PATH = Pathname.new(RbConfig.ruby).freeze +RUBY_BIN = RUBY_PATH.dirname.freeze diff --git a/Library/Homebrew/startup/sorbet.rb b/Library/Homebrew/startup/sorbet.rb new file mode 100644 index 0000000000000..6005bbe088589 --- /dev/null +++ b/Library/Homebrew/startup/sorbet.rb @@ -0,0 +1,10 @@ +# typed: true +# frozen_string_literal: true + +if ENV["HOMEBREW_SORBET_RUNTIME"] + # This is only supported under the brew environment. + Homebrew.install_bundler_gems!(groups: ["sorbet"]) + require "sorbet-runtime" +else + require "standalone/sorbet" +end diff --git a/Library/Homebrew/style.rb b/Library/Homebrew/style.rb index bba9ead69881a..c802ad087c0b6 100644 --- a/Library/Homebrew/style.rb +++ b/Library/Homebrew/style.rb @@ -85,7 +85,7 @@ def run_rubocop(files, output_type, require "rubocop" end - require "rubocops" + require "rubocops/all" args = %w[ --force-exclusion diff --git a/Library/Homebrew/system_config.rb b/Library/Homebrew/system_config.rb index 14f16388ca4f9..8912abf2fc14a 100644 --- a/Library/Homebrew/system_config.rb +++ b/Library/Homebrew/system_config.rb @@ -32,19 +32,24 @@ def clang_build end end + sig { returns(Pathname) } + def homebrew_repo + HOMEBREW_REPOSITORY.dup.extend(GitRepositoryExtension) + end + sig { returns(String) } def head - HOMEBREW_REPOSITORY.git_head || "(none)" + homebrew_repo.git_head || "(none)" end sig { returns(String) } def last_commit - HOMEBREW_REPOSITORY.git_last_commit || "never" + homebrew_repo.git_last_commit || "never" end sig { returns(String) } def origin - HOMEBREW_REPOSITORY.git_origin || "(none)" + homebrew_repo.git_origin || "(none)" end sig { returns(String) } diff --git a/Library/Homebrew/tap_constants.rb b/Library/Homebrew/tap_constants.rb index 10e167b2a2895..b9edb7afebc43 100644 --- a/Library/Homebrew/tap_constants.rb +++ b/Library/Homebrew/tap_constants.rb @@ -1,8 +1,6 @@ # typed: true # frozen_string_literal: true -require "config" - # Match taps' formulae, e.g. `someuser/sometap/someformula` HOMEBREW_TAP_FORMULA_REGEX = %r{^([\w-]+)/([\w-]+)/([\w+-.@]+)$}.freeze # Match taps' casks, e.g. `someuser/sometap/somecask` diff --git a/Library/Homebrew/test/cmd/home_spec.rb b/Library/Homebrew/test/cmd/home_spec.rb index 57c6eb70b0f51..063846c3346f3 100644 --- a/Library/Homebrew/test/cmd/home_spec.rb +++ b/Library/Homebrew/test/cmd/home_spec.rb @@ -2,7 +2,6 @@ # frozen_string_literal: true require "cmd/shared_examples/args_parse" -require "support/lib/config" describe "brew home" do let(:testballhome_homepage) { diff --git a/Library/Homebrew/test/support/lib/default_prefix.rb b/Library/Homebrew/test/support/lib/default_prefix.rb new file mode 100644 index 0000000000000..e912bd4831520 --- /dev/null +++ b/Library/Homebrew/test/support/lib/default_prefix.rb @@ -0,0 +1,8 @@ +# typed: true +# frozen_string_literal: true + +module Homebrew + # For testing's sake always assume the default prefix + DEFAULT_PREFIX = HOMEBREW_PREFIX.to_s.freeze + DEFAULT_REPOSITORY = HOMEBREW_REPOSITORY.to_s.freeze +end diff --git a/Library/Homebrew/test/support/lib/config.rb b/Library/Homebrew/test/support/lib/startup/config.rb similarity index 84% rename from Library/Homebrew/test/support/lib/config.rb rename to Library/Homebrew/test/support/lib/startup/config.rb index 9e11210c39f95..ea9aad2897b4a 100644 --- a/Library/Homebrew/test/support/lib/config.rb +++ b/Library/Homebrew/test/support/lib/startup/config.rb @@ -3,8 +3,6 @@ raise "HOMEBREW_BREW_FILE was not exported! Please call bin/brew directly!" unless ENV["HOMEBREW_BREW_FILE"] -require "pathname" - HOMEBREW_BREW_FILE = Pathname.new(ENV["HOMEBREW_BREW_FILE"]).freeze TEST_TMPDIR = ENV.fetch("HOMEBREW_TEST_TMPDIR") do |k| @@ -23,11 +21,9 @@ # Where external data that has been incorporated into Homebrew is stored HOMEBREW_DATA_PATH = (HOMEBREW_LIBRARY_PATH/"data").freeze -require "extend/git_repository" - # Paths redirected to a temporary directory and wiped at the end of the test run HOMEBREW_PREFIX = (Pathname(TEST_TMPDIR)/"prefix").freeze -HOMEBREW_REPOSITORY = HOMEBREW_PREFIX.dup.extend(GitRepositoryExtension).freeze +HOMEBREW_REPOSITORY = HOMEBREW_PREFIX.dup.freeze HOMEBREW_LIBRARY = (HOMEBREW_REPOSITORY/"Library").freeze HOMEBREW_CACHE = (HOMEBREW_PREFIX.parent/"cache").freeze HOMEBREW_CACHE_FORMULA = (HOMEBREW_PREFIX.parent/"formula_cache").freeze @@ -52,12 +48,3 @@ TEST_SHA1 = "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef" TEST_SHA256 = "deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef" - -# For testing's sake always assume the default prefix -module Homebrew - remove_const :DEFAULT_PREFIX if defined?(DEFAULT_PREFIX) - DEFAULT_PREFIX = HOMEBREW_PREFIX.to_s.freeze - - remove_const :DEFAULT_REPOSITORY if defined?(DEFAULT_REPOSITORY) - DEFAULT_REPOSITORY = HOMEBREW_REPOSITORY.to_s.freeze -end diff --git a/Library/Homebrew/utils/gems.rb b/Library/Homebrew/utils/gems.rb index bc2337834c4c6..0eaada3c8e477 100644 --- a/Library/Homebrew/utils/gems.rb +++ b/Library/Homebrew/utils/gems.rb @@ -52,7 +52,7 @@ def odie_if_defined(message) def setup_gem_environment!(gem_home: nil, gem_bindir: nil, setup_path: true) # Match where our bundler gems are. - gem_home ||= "#{ENV["HOMEBREW_LIBRARY"]}/Homebrew/vendor/bundle/ruby/#{RbConfig::CONFIG["ruby_version"]}" + gem_home ||= "#{HOMEBREW_LIBRARY_PATH}/vendor/bundle/ruby/#{RbConfig::CONFIG["ruby_version"]}" Gem.paths = { "GEM_HOME" => gem_home, "GEM_PATH" => gem_home, @@ -128,23 +128,34 @@ def install_bundler! ) end - def install_bundler_gems!(only_warn_on_failure: false, setup_path: true) + def install_bundler_gems!(only_warn_on_failure: false, setup_path: true, groups: []) old_path = ENV["PATH"] old_gem_path = ENV["GEM_PATH"] old_gem_home = ENV["GEM_HOME"] old_bundle_gemfile = ENV["BUNDLE_GEMFILE"] + old_bundle_with = ENV["BUNDLE_WITH"] install_bundler! + require "settings" + + # Combine the passed groups with the ones stored in settings + groups |= (Homebrew::Settings.read(:gemgroups)&.split(";") || []) + groups.sort! + ENV["BUNDLE_GEMFILE"] = File.join(ENV.fetch("HOMEBREW_LIBRARY"), "Homebrew", "Gemfile") - @bundle_installed ||= begin + ENV["BUNDLE_WITH"] = groups.join(" ") + + if @bundle_installed_groups != groups bundle = File.join(find_in_path("bundle"), "bundle") bundle_check_output = `#{bundle} check 2>&1` bundle_check_failed = !$CHILD_STATUS.success? # for some reason sometimes the exit code lies so check the output too. - if bundle_check_failed || bundle_check_output.include?("Install missing gems") - unless system bundle, "install" + bundle_installed = if bundle_check_failed || bundle_check_output.include?("Install missing gems") + if system bundle, "install" + true + else message = <<~EOS failed to run `#{bundle} install`! EOS @@ -153,10 +164,16 @@ def install_bundler_gems!(only_warn_on_failure: false, setup_path: true) else odie_if_defined message end + false end else true end + + if bundle_installed + Homebrew::Settings.write(:gemgroups, groups.join(";")) + @bundle_installed_groups = groups + end end setup_gem_environment! @@ -167,6 +184,7 @@ def install_bundler_gems!(only_warn_on_failure: false, setup_path: true) ENV["GEM_PATH"] = old_gem_path ENV["GEM_HOME"] = old_gem_home ENV["BUNDLE_GEMFILE"] = old_bundle_gemfile + ENV["BUNDLE_WITH"] = old_bundle_with end end end diff --git a/Library/Homebrew/utils/gems.rbi b/Library/Homebrew/utils/gems.rbi index 55bdcc1114cd9..746bceef1d4bb 100644 --- a/Library/Homebrew/utils/gems.rbi +++ b/Library/Homebrew/utils/gems.rbi @@ -22,6 +22,6 @@ module Homebrew sig { void } def install_bundler!; end - sig { params(only_warn_on_failure: T::Boolean, setup_path: T::Boolean).void } - def install_bundler_gems!(only_warn_on_failure: false, setup_path: false); end + sig { params(only_warn_on_failure: T::Boolean, setup_path: T::Boolean, groups: T::Array[String]).void } + def install_bundler_gems!(only_warn_on_failure: false, setup_path: false, groups: []); end end diff --git a/Library/Homebrew/utils/rubocop.rb b/Library/Homebrew/utils/rubocop.rb index ae6050ddd0f38..35db8717bdd47 100755 --- a/Library/Homebrew/utils/rubocop.rb +++ b/Library/Homebrew/utils/rubocop.rb @@ -2,9 +2,7 @@ # typed: false # frozen_string_literal: true -require_relative "gems" -Homebrew.setup_gem_environment! - +require_relative "../standalone" require_relative "../warnings" Warnings.ignore :parser_syntax do diff --git a/Library/Homebrew/utils/sorbet.rb b/Library/Homebrew/utils/sorbet.rb deleted file mode 100644 index aaf7f223fd5f7..0000000000000 --- a/Library/Homebrew/utils/sorbet.rb +++ /dev/null @@ -1,16 +0,0 @@ -# typed: true -# frozen_string_literal: true - -if ENV["HOMEBREW_SORBET_RUNTIME"] - Homebrew.install_bundler_gems! - require "sorbet-runtime" -else - # Explicitly prevent `sorbet-runtime` from being loaded. - def gem(name, *) - raise Gem::LoadError if name == "sorbet-runtime" - - super - end - - require "sorbet-runtime-stub" -end