From df0fe8a802352befd8f3e3dd5bd6b7742da7eb45 Mon Sep 17 00:00:00 2001 From: Mike McQuaid Date: Mon, 24 Mar 2025 17:34:35 +0000 Subject: [PATCH] Add `version_file:` DSL to `Brewfile` This allows writing to e.g. `.ruby-version` files directly from the `Brewfile`, making it easy to keep these versions in sync. --- Library/Homebrew/bundle.rb | 28 +++++++++++++++++++ Library/Homebrew/bundle/brew_installer.rb | 14 ++++++++++ Library/Homebrew/bundle/commands/exec.rb | 13 +-------- .../test/bundle/commands/exec_spec.rb | 1 + docs/Brew-Bundle-and-Brewfile.md | 2 ++ 5 files changed, 46 insertions(+), 12 deletions(-) diff --git a/Library/Homebrew/bundle.rb b/Library/Homebrew/bundle.rb index d4ce509cac..726d70e9cf 100644 --- a/Library/Homebrew/bundle.rb +++ b/Library/Homebrew/bundle.rb @@ -82,6 +82,34 @@ module Homebrew 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 5b0783f163..cf5112e53b 100644 --- a/Library/Homebrew/bundle/brew_installer.rb +++ b/Library/Homebrew/bundle/brew_installer.rb @@ -27,6 +27,7 @@ module Homebrew @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 @@ module Homebrew 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 c0a55f7035..8fc9007bd9 100644 --- a/Library/Homebrew/bundle/commands/exec.rb +++ b/Library/Homebrew/bundle/commands/exec.rb @@ -108,18 +108,7 @@ module Homebrew 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 1d127fc303..21c8b8fc48 100644 --- a/Library/Homebrew/test/bundle/commands/exec_spec.rb +++ b/Library/Homebrew/test/bundle/commands/exec_spec.rb @@ -29,6 +29,7 @@ RSpec.describe Homebrew::Bundle::Commands::Exec do 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 11d2a59c81..0351ed3b7b 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?