Support Cask renames when installing/dumping

This adds support for Cask old tokens used for renames of Casks.

We'll now correctly check these at installation time to avoid repeatedly
installing renamed Casks and dump them in the Brewfile. We also use this
logic to avoid cleaning up renamed Casks.
This commit is contained in:
Mike McQuaid 2025-07-10 08:05:36 +00:00 committed by GitHub
parent 700d67a85e
commit e8bfa23877
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 68 additions and 7 deletions

View File

@ -8,6 +8,7 @@ module Homebrew
@casks = nil
@cask_names = nil
@cask_hash = nil
@cask_oldnames = nil
end
def self.cask_names
@ -38,6 +39,25 @@ module Homebrew
end.join("\n")
end
def self.cask_oldnames
return @cask_oldnames if @cask_oldnames
@cask_oldnames = {}
casks.each do |c|
oldnames = c.old_tokens
next if oldnames.blank?
oldnames.each do |oldname|
@cask_oldnames[oldname] = c.full_name
if c.full_name.include? "/" # tap cask
tap_name = c.full_name.rpartition("/").first
@cask_oldnames["#{tap_name}/#{oldname}"] = c.full_name
end
end
end
@cask_oldnames
end
def self.formula_dependencies(cask_list)
return [] unless Bundle.cask_installed?
return [] if cask_list.blank?

View File

@ -87,12 +87,25 @@ module Homebrew
!cask_upgradable?(cask)
end
def self.cask_in_array?(cask, array)
return true if array.include?(cask)
return true if array.include?(cask.split("/").last)
require "bundle/cask_dumper"
old_names = Homebrew::Bundle::CaskDumper.cask_oldnames
old_name = old_names[cask]
old_name ||= old_names[cask.split("/").last]
return true if old_name && array.include?(old_name)
false
end
def self.cask_installed?(cask)
installed_casks.include? cask
cask_in_array?(cask, installed_casks)
end
def self.cask_upgradable?(cask)
outdated_casks.include? cask
cask_in_array?(cask, outdated_casks)
end
def self.installed_casks

View File

@ -128,9 +128,10 @@ module Homebrew
kept_formulae = @dsl.entries.select { |e| e.type == :brew }.map(&:name)
kept_formulae += Homebrew::Bundle::CaskDumper.formula_dependencies(kept_casks)
kept_formulae.map! do |f|
Homebrew::Bundle::FormulaDumper.formula_aliases[f] ||
Homebrew::Bundle::FormulaDumper.formula_oldnames[f] ||
f
Homebrew::Bundle::FormulaDumper.formula_aliases.fetch(
f,
Homebrew::Bundle::FormulaDumper.formula_oldnames.fetch(f, f),
)
end
kept_formulae + recursive_dependencies(Homebrew::Bundle::FormulaDumper.formulae, kept_formulae)
@ -142,7 +143,11 @@ module Homebrew
return @kept_casks if @kept_casks
@dsl ||= Brewfile.read(global:, file:)
@kept_casks = @dsl.entries.select { |e| e.type == :cask }.map(&:name)
kept_casks = @dsl.entries.select { |e| e.type == :cask }.flat_map(&:name)
kept_casks.map! do |c|
Homebrew::Bundle::CaskDumper.cask_oldnames.fetch(c, c)
end
@kept_casks = kept_casks
end
private_class_method def self.recursive_dependencies(current_formulae, formulae_names, top_level: true)

View File

@ -95,6 +95,27 @@ RSpec.describe Homebrew::Bundle::CaskDumper do
end
end
describe "#cask_oldnames" do
before do
described_class.reset!
end
it "returns an empty string when no casks are installed" do
expect(dumper.cask_oldnames).to eql({})
end
it "returns a hash with installed casks old names" do
foo = instance_double(Cask::Cask, to_s: "foo", old_tokens: ["oldfoo"], full_name: "qux/quuz/foo")
bar = instance_double(Cask::Cask, to_s: "bar", old_tokens: [], full_name: "bar")
allow(Cask::Caskroom).to receive(:casks).and_return([foo, bar])
allow(Homebrew::Bundle).to receive(:cask_installed?).and_return(true)
expect(dumper.cask_oldnames).to eql({
"qux/quuz/oldfoo" => "qux/quuz/foo",
"oldfoo" => "qux/quuz/foo",
})
end
end
describe "#formula_dependencies" do
context "when the given casks don't have formula dependencies" do
before do

View File

@ -38,7 +38,9 @@ RSpec.describe Homebrew::Bundle::Commands::Cleanup do
end
it "computes which casks to uninstall" do
allow(Homebrew::Bundle::CaskDumper).to receive(:casks).and_return(%w[123 456])
cask_123 = instance_double(Cask::Cask, to_s: "123", old_tokens: [])
cask_456 = instance_double(Cask::Cask, to_s: "456", old_tokens: [])
allow(Homebrew::Bundle::CaskDumper).to receive(:casks).and_return([cask_123, cask_456])
expect(described_class.casks_to_uninstall).to eql(%w[456])
end