brew extract from all taps
This commit is contained in:
parent
db42dd0420
commit
6be6bba0be
@ -97,47 +97,64 @@ module Homebrew
|
||||
# Expect exactly two named arguments: formula and tap
|
||||
raise UsageError if ARGV.named.length != 2
|
||||
|
||||
if ARGV.named.first !~ HOMEBREW_TAP_FORMULA_REGEX
|
||||
name = ARGV.named.first.downcase
|
||||
source_tap = CoreTap.instance
|
||||
else
|
||||
name = Regexp.last_match(3).downcase
|
||||
source_tap = Tap.fetch(Regexp.last_match(1), Regexp.last_match(2))
|
||||
raise TapFormulaUnavailableError.new(source_tap, name) unless source_tap.installed?
|
||||
end
|
||||
|
||||
destination_tap = Tap.fetch(ARGV.named.second)
|
||||
odie "Cannot extract formula to homebrew/core!" if destination_tap.core_tap?
|
||||
odie "Cannot extract formula to the same tap!" if destination_tap == source_tap
|
||||
destination_tap.install unless destination_tap.installed?
|
||||
|
||||
name = ARGV.named.first.downcase
|
||||
repo = CoreTap.instance.path
|
||||
# Formulae can technically live in "<repo>/<formula>.rb" or
|
||||
# "<repo>/Formula/<formula>.rb", but explicitly use the latter for now
|
||||
# since that is how the core tap is structured.
|
||||
file = repo/"Formula/#{name}.rb"
|
||||
repo = source_tap.path
|
||||
pattern = source_tap.core_tap? ? repo/"Formula/#{name}.rb" : repo/"{,**/}#{name}.rb"
|
||||
|
||||
if args.version
|
||||
ohai "Searching repository history"
|
||||
version = args.version
|
||||
rev = "HEAD"
|
||||
test_formula = nil
|
||||
result = ""
|
||||
loop do
|
||||
loop do
|
||||
rev = Git.last_revision_commit_of_file(repo, file, before_commit: "#{rev}~1")
|
||||
break if rev.empty?
|
||||
break unless Git.last_revision_of_file(repo, file, before_commit: rev).empty?
|
||||
rev, (path,) = Git.last_revision_commit_of_files(repo, pattern, before_commit: "#{rev}~1")
|
||||
odie "Could not find #{name}! The formula or version may not have existed." if rev.nil?
|
||||
|
||||
file = repo/path
|
||||
result = Git.last_revision_of_file(repo, file, before_commit: rev)
|
||||
if result.empty?
|
||||
ohai "Skipping revision #{rev} - file is empty at this revision" if ARGV.debug?
|
||||
next
|
||||
end
|
||||
|
||||
test_formula = formula_at_revision(repo, name, file, rev)
|
||||
break if test_formula.nil? || test_formula.version == version
|
||||
|
||||
ohai "Trying #{test_formula.version} from revision #{rev} against desired #{version}" if ARGV.debug?
|
||||
end
|
||||
odie "Could not find #{name}! The formula or version may not have existed." if test_formula.nil?
|
||||
result = Git.last_revision_of_file(repo, file, before_commit: rev)
|
||||
elsif File.exist?(file)
|
||||
rev = "HEAD"
|
||||
version = Formulary.factory(file).version
|
||||
result = File.read(file)
|
||||
else
|
||||
ohai "Searching repository history"
|
||||
rev = Git.last_revision_commit_of_file(repo, file)
|
||||
version = formula_at_revision(repo, name, file, rev).version
|
||||
odie "Could not find #{name}! The formula or version may not have existed." if rev.empty?
|
||||
result = Git.last_revision_of_file(repo, file)
|
||||
files = Dir[repo/"{,**/}"].map do |dir|
|
||||
Pathname.glob(["#{dir}/#{name}.rb"]).find(&:file?)
|
||||
end.compact
|
||||
|
||||
if files.empty?
|
||||
ohai "Searching repository history"
|
||||
rev, (path,) = Git.last_revision_commit_of_files(repo, pattern)
|
||||
odie "Could not find #{name}! The formula or version may not have existed." if rev.nil?
|
||||
file = repo/path
|
||||
version = formula_at_revision(repo, name, file, rev).version
|
||||
result = Git.last_revision_of_file(repo, file)
|
||||
else
|
||||
file = files.first.realpath
|
||||
rev = "HEAD"
|
||||
version = Formulary.factory(file).version
|
||||
result = File.read(file)
|
||||
end
|
||||
end
|
||||
|
||||
# The class name has to be renamed to match the new filename,
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
describe "brew extract", :integration_test do
|
||||
it "retrieves the specified version of formula, defaulting to most recent" do
|
||||
it "retrieves the specified version of formula from core tap, defaulting to most recent" do
|
||||
path = Tap::TAP_DIRECTORY/"homebrew/homebrew-foo"
|
||||
(path/"Formula").mkpath
|
||||
target = Tap.from_path(path)
|
||||
@ -29,4 +29,69 @@ describe "brew extract", :integration_test do
|
||||
|
||||
expect(Formulary.factory(path/"Formula/testball@0.1.rb").version).to be == "0.1"
|
||||
end
|
||||
|
||||
it "retrieves the specified version of formula from a tap other than core, defaulting to most recent" do
|
||||
destination = Tap::TAP_DIRECTORY/"homebrew/homebrew-foo"
|
||||
(destination/"Formula").mkpath
|
||||
destination_tap = Tap.from_path(destination)
|
||||
|
||||
source = Tap::TAP_DIRECTORY/"homebrew/homebrew-bar"
|
||||
source.mkpath
|
||||
source_tap = Tap.from_path(source)
|
||||
|
||||
tarball = if OS.linux?
|
||||
TEST_FIXTURE_DIR/"tarballs/testball-0.1-linux.tbz"
|
||||
else
|
||||
TEST_FIXTURE_DIR/"tarballs/testball-0.1.tbz"
|
||||
end
|
||||
|
||||
content = <<~RUBY
|
||||
desc "Some test"
|
||||
homepage "https://brew.sh/testball"
|
||||
url "file://#{tarball}"
|
||||
sha256 "#{tarball.sha256}"
|
||||
|
||||
option "with-foo", "Build with foo"
|
||||
|
||||
def install
|
||||
(prefix/"foo"/"test").write("test") if build.with? "foo"
|
||||
prefix.install Dir["*"]
|
||||
(buildpath/"test.c").write \
|
||||
"#include <stdio.h>\\nint main(){return printf(\\"test\\");}"
|
||||
bin.mkpath
|
||||
system ENV.cc, "test.c", "-o", bin/"test"
|
||||
end
|
||||
RUBY
|
||||
|
||||
formula_file = source_tap.path/"testball.rb"
|
||||
formula_file.write <<~RUBY
|
||||
class Testball < Formula
|
||||
#{content}
|
||||
end
|
||||
RUBY
|
||||
|
||||
source_tap.path.cd do
|
||||
system "git", "init"
|
||||
system "git", "add", "--all"
|
||||
system "git", "commit", "-m", "testball 0.1"
|
||||
contents = File.read(formula_file)
|
||||
contents.gsub!("testball-0.1", "testball-0.2")
|
||||
File.write(formula_file, contents)
|
||||
system "git", "add", "--all"
|
||||
system "git", "commit", "-m", "testball 0.2"
|
||||
end
|
||||
expect { brew "extract", "homebrew/bar/testball", destination_tap.name }
|
||||
.to be_a_success
|
||||
|
||||
expect(destination/"Formula/testball@0.2.rb").to exist
|
||||
|
||||
expect(Formulary.factory(destination/"Formula/testball@0.2.rb").version).to be == "0.2"
|
||||
|
||||
expect { brew "extract", "homebrew/bar/testball", destination_tap.name, "--version=0.1" }
|
||||
.to be_a_success
|
||||
|
||||
expect(destination/"Formula/testball@0.1.rb").to exist
|
||||
|
||||
expect(Formulary.factory(destination/"Formula/testball@0.1.rb").version).to be == "0.1"
|
||||
end
|
||||
end
|
||||
|
||||
@ -14,6 +14,19 @@ module Git
|
||||
out.chomp
|
||||
end
|
||||
|
||||
def last_revision_commit_of_files(repo, file, before_commit: nil)
|
||||
args = [before_commit.nil? ? "--skip=1" : before_commit.split("..").first]
|
||||
|
||||
cmd = [
|
||||
HOMEBREW_SHIMS_PATH/"scm/git", "-C", repo,
|
||||
"log", "--format=%h", "--abbrev=7", "--max-count=1", "--name-only",
|
||||
*args, "--", file
|
||||
]
|
||||
out, = Open3.capture3(cmd.join(" "))
|
||||
rev, *files = out.chomp.split(/\n/).reject(&:empty?)
|
||||
[rev, files]
|
||||
end
|
||||
|
||||
def last_revision_of_file(repo, file, before_commit: nil)
|
||||
relative_file = Pathname(file).relative_path_from(repo)
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user