Add cask support to brew unpack command

Co-authored-by: p-linnane <105994585+p-linnane@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot] 2025-08-28 23:36:49 +00:00 committed by Bevan Kay
parent 63fee348f7
commit a9cd0c4b5d
No known key found for this signature in database
GPG Key ID: C55CB024B5314B57
2 changed files with 84 additions and 24 deletions

View File

@ -5,6 +5,8 @@ require "abstract_command"
require "fileutils" require "fileutils"
require "stringio" require "stringio"
require "formula" require "formula"
require "cask/download"
require "unpack_strategy"
module Homebrew module Homebrew
module DevCmd module DevCmd
@ -13,7 +15,7 @@ module Homebrew
cmd_args do cmd_args do
description <<~EOS description <<~EOS
Unpack the source files for <formula> into subdirectories of the current Unpack the source files for <formula> and binaries for <cask> into subdirectories of the current
working directory. working directory.
EOS EOS
flag "--destdir=", flag "--destdir=",
@ -25,15 +27,22 @@ module Homebrew
"patches for the software." "patches for the software."
switch "-f", "--force", switch "-f", "--force",
description: "Overwrite the destination directory if it already exists." description: "Overwrite the destination directory if it already exists."
switch "--formula", "--formulae",
description: "Treat all named arguments as formulae."
switch "--cask", "--casks",
description: "Treat all named arguments as casks."
conflicts "--git", "--patch" conflicts "--git", "--patch"
conflicts "--formula", "--cask"
conflicts "--cask", "--patch"
conflicts "--cask", "--git"
named_args :formula, min: 1 named_args [:formula, :cask], min: 1
end end
sig { override.void } sig { override.void }
def run def run
formulae = args.named.to_formulae formulae_and_casks = args.named.to_formulae_and_casks
if (dir = args.destdir) if (dir = args.destdir)
unpack_dir = Pathname.new(dir).expand_path unpack_dir = Pathname.new(dir).expand_path
@ -44,33 +53,75 @@ module Homebrew
odie "Cannot write to #{unpack_dir}" unless unpack_dir.writable? odie "Cannot write to #{unpack_dir}" unless unpack_dir.writable?
formulae.each do |f| formulae_and_casks.each do |formula_or_cask|
stage_dir = unpack_dir/"#{f.name}-#{f.version}" case formula_or_cask
when Formula
if stage_dir.exist? unpack_formula(formula_or_cask, unpack_dir)
odie "Destination #{stage_dir} already exists!" unless args.force? when Cask::Cask
unpack_cask(formula_or_cask, unpack_dir)
rm_rf stage_dir
end end
end
end
oh1 "Unpacking #{Formatter.identifier(f.full_name)} to: #{stage_dir}" private
# show messages about tar sig { params(formula: Formula, unpack_dir: Pathname).void }
with_env VERBOSE: "1" do def unpack_formula(formula, unpack_dir)
f.brew do stage_dir = unpack_dir/"#{formula.name}-#{formula.version}"
f.patch if args.patch?
cp_r getwd, stage_dir, preserve: true if stage_dir.exist?
end odie "Destination #{stage_dir} already exists!" unless args.force?
rm_rf stage_dir
end
oh1 "Unpacking #{Formatter.identifier(formula.full_name)} to: #{stage_dir}"
# show messages about tar
with_env VERBOSE: "1" do
formula.brew do
formula.patch if args.patch?
cp_r getwd, stage_dir, preserve: true
end end
end
next unless args.git? return unless args.git?
ohai "Setting up Git repository" ohai "Setting up Git repository"
cd(stage_dir) do cd(stage_dir) do
system "git", "init", "-q" system "git", "init", "-q"
system "git", "add", "-A" system "git", "add", "-A"
system "git", "commit", "-q", "-m", "brew-unpack" system "git", "commit", "-q", "-m", "brew-unpack"
end end
end
sig { params(cask: Cask::Cask, unpack_dir: Pathname).void }
def unpack_cask(cask, unpack_dir)
stage_dir = unpack_dir/"#{cask.token}-#{cask.version}"
if stage_dir.exist?
odie "Destination #{stage_dir} already exists!" unless args.force?
rm_rf stage_dir
end
oh1 "Unpacking #{Formatter.identifier(cask.full_name)} to: #{stage_dir}"
# Download the cask
download = Cask::Download.new(cask, quarantine: false)
downloaded_path = download.fetch(quiet: false)
# Extract to destination
stage_dir.mkpath
UnpackStrategy.detect(downloaded_path).extract_nestedly(to: stage_dir, verbose: true)
return unless args.git?
ohai "Setting up Git repository"
cd(stage_dir) do
system "git", "init", "-q"
system "git", "add", "-A"
system "git", "commit", "-q", "-m", "brew-unpack"
end end
end end
end end

View File

@ -16,4 +16,13 @@ RSpec.describe Homebrew::DevCmd::Unpack do
expect(path/"testball-0.1").to be_a_directory expect(path/"testball-0.1").to be_a_directory
end end
end end
it "unpacks a given Cask's archive", :integration_test do
mktmpdir do |path|
expect { brew "unpack", "local-caffeine", "--destdir=#{path}", "--cask" }
.to be_a_success
expect(path/"local-caffeine-1.2.3").to be_a_directory
end
end
end end