diff --git a/Library/Homebrew/bundle.rb b/Library/Homebrew/bundle.rb index d4ce509cac7f7..726d70e9cf86f 100644 --- a/Library/Homebrew/bundle.rb +++ b/Library/Homebrew/bundle.rb @@ -82,6 +82,34 @@ def exchange_uid_if_needed!(&block) return_value end + + def formula_versions_from_env + @formula_versions_from_env ||= begin + formula_versions = {} + + ENV.each do |key, value| + match = key.match(/^HOMEBREW_BUNDLE_EXEC_FORMULA_VERSION_(.+)$/) + next if match.blank? + + formula_name = match[1] + next if formula_name.blank? + + ENV.delete(key) + formula_versions[formula_name.downcase] = value + end + + formula_versions + end + end + + sig { void } + def reset! + @mas_installed = nil + @vscode_installed = nil + @whalebrew_installed = nil + @cask_installed = nil + @formula_versions_from_env = nil + end end end end diff --git a/Library/Homebrew/bundle/brew_installer.rb b/Library/Homebrew/bundle/brew_installer.rb index 5b0783f1630da..cf5112e53bbc2 100644 --- a/Library/Homebrew/bundle/brew_installer.rb +++ b/Library/Homebrew/bundle/brew_installer.rb @@ -27,6 +27,7 @@ def initialize(name, options = {}) @start_service = options.fetch(:start_service, @restart_service) @link = options.fetch(:link, nil) @postinstall = options.fetch(:postinstall, nil) + @version_file = options.fetch(:version_file, nil) @changed = nil end @@ -57,6 +58,19 @@ def install(preinstall: true, no_upgrade: false, verbose: false, force: false) postinstall_result = postinstall_change_state!(verbose:) result &&= postinstall_result + + if result && @version_file.present? + # Use the version from the environment if it hasn't changed. + version = if !changed? && (env_version = Bundle.formula_versions_from_env[@name]) + env_version + else + Formula[@full_name].version.to_s + end + version_path = Pathname.new(@version_file) + version_path.write("#{version}\n") + + puts "Wrote #{@name} version #{version} to #{@version_file}" if verbose + end end result diff --git a/Library/Homebrew/bundle/commands/exec.rb b/Library/Homebrew/bundle/commands/exec.rb index c0a55f70354e7..8fc9007bd9354 100644 --- a/Library/Homebrew/bundle/commands/exec.rb +++ b/Library/Homebrew/bundle/commands/exec.rb @@ -108,18 +108,7 @@ def self.run(*args, global: false, file: nil, subcommand: "") end # Replace the formula versions from the environment variables - formula_versions = {} - ENV.each do |key, value| - match = key.match(/^HOMEBREW_BUNDLE_EXEC_FORMULA_VERSION_(.+)$/) - next if match.blank? - - formula_name = match[1] - next if formula_name.blank? - - ENV.delete(key) - formula_versions[formula_name.downcase] = value - end - formula_versions.each do |formula_name, formula_version| + Bundle.formula_versions_from_env.each do |formula_name, formula_version| ENV.each do |key, value| opt = %r{/opt/#{formula_name}([/:$])} next unless value.match(opt) diff --git a/Library/Homebrew/test/bundle/commands/exec_spec.rb b/Library/Homebrew/test/bundle/commands/exec_spec.rb index 1d127fc303762..21c8b8fc48793 100644 --- a/Library/Homebrew/test/bundle/commands/exec_spec.rb +++ b/Library/Homebrew/test/bundle/commands/exec_spec.rb @@ -29,6 +29,7 @@ context "with valid command setup" do before do allow(described_class).to receive(:exec).and_return(nil) + Homebrew::Bundle.reset! end it "does not raise an error" do diff --git a/docs/Brew-Bundle-and-Brewfile.md b/docs/Brew-Bundle-and-Brewfile.md index 11d2a59c81f08..0351ed3b7bff4 100644 --- a/docs/Brew-Bundle-and-Brewfile.md +++ b/docs/Brew-Bundle-and-Brewfile.md @@ -40,6 +40,8 @@ brew "mysql@5.6", restart_service: :changed, link: true, conflicts_with: ["mysql # 'brew install' and run a command if installer or upgraded. brew "postgresql@16", postinstall: "${HOMEBREW_PREFIX}/opt/postgresql@16/bin/postgres -D ${HOMEBREW_PREFIX}/var/postgresql@16" +# 'brew install' and write the installed version to the '.ruby-version' file. +brew "ruby", version_file: ".ruby-version" # install only on specified OS brew "gnupg" if OS.mac? brew "glibc" if OS.linux?