From 3c09ab0d06f117c45adc4c230c7a57fcd04ce6a6 Mon Sep 17 00:00:00 2001 From: Figroc Chen Date: Sun, 1 Dec 2019 22:26:03 +0800 Subject: [PATCH] extract: semver aware --- Library/Homebrew/dev-cmd/extract.rb | 20 ++++++++++++---- Library/Homebrew/test/dev-cmd/extract_spec.rb | 23 +++++++++++++++---- 2 files changed, 34 insertions(+), 9 deletions(-) diff --git a/Library/Homebrew/dev-cmd/extract.rb b/Library/Homebrew/dev-cmd/extract.rb index 65ecef960e..a5a8443cd9 100644 --- a/Library/Homebrew/dev-cmd/extract.rb +++ b/Library/Homebrew/dev-cmd/extract.rb @@ -125,24 +125,34 @@ module Homebrew if args.version ohai "Searching repository history" version = args.version - rev = "HEAD" + version_segments = Gem::Version.new(version).segments if Gem::Version.correct?(version) + rev = nil test_formula = nil result = "" loop do - rev, (path,) = Git.last_revision_commit_of_files(repo, pattern, before_commit: "#{rev}~1") + rev = rev.nil? ? "HEAD" : "#{rev}~1" + rev, (path,) = Git.last_revision_commit_of_files(repo, pattern, before_commit: rev) 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? - odebug "Skipping revision #{rev} - file is empty at this revision" if ARGV.debug? + odebug "Skipping revision #{rev} - file is empty at this revision" next end test_formula = formula_at_revision(repo, name, file, rev) break if test_formula.nil? || test_formula.version == version - odebug "Trying #{test_formula.version} from revision #{rev} against desired #{version}" if ARGV.debug? + if version_segments && Gem::Version.correct?(test_formula.version) + test_formula_version_segments = Gem::Version.new(test_formula.version).segments + if version_segments.length < test_formula_version_segments.length + odebug "Apply semantic versioning with #{test_formual_version_segments}" + break if version_segments == test_formula_version_segments.first(version_segments.length) + end + end + + odebug "Trying #{test_formula.version} from revision #{rev} against desired #{version}" end odie "Could not find #{name}! The formula or version may not have existed." if test_formula.nil? else @@ -181,7 +191,7 @@ module Homebrew brew extract --force --version=#{version} #{name} #{destination_tap.name} EOS end - odebug "Overwriting existing formula at #{path}" if ARGV.debug? + odebug "Overwriting existing formula at #{path}" path.delete end ohai "Writing formula for #{name} from revision #{rev} to #{path}" diff --git a/Library/Homebrew/test/dev-cmd/extract_spec.rb b/Library/Homebrew/test/dev-cmd/extract_spec.rb index 169f078073..a34d6f844e 100644 --- a/Library/Homebrew/test/dev-cmd/extract_spec.rb +++ b/Library/Homebrew/test/dev-cmd/extract_spec.rb @@ -7,7 +7,7 @@ describe "Homebrew.extract_args" do end describe "brew extract", :integration_test do - it "retrieves the specified version of formula, defaulting to most recent" do + let!(:target) do path = Tap::TAP_DIRECTORY/"homebrew/homebrew-foo" (path/"Formula").mkpath target = Tap.from_path(path) @@ -23,12 +23,27 @@ describe "brew extract", :integration_test do system "git", "add", "--all" system "git", "commit", "-m", "testball 0.2" end + { name: target.name, path: path } + end - expect { brew "extract", "testball", target.name, "--version=0.1" } + it "retrieves the most recent version of formula" do + expect { brew "extract", "testball", target[:name] } .to be_a_success + expect(target[:path]/"Formula/testball@0.2.rb").to exist + expect(Formulary.factory(target[:path]/"Formula/testball@0.2.rb").version).to be == "0.2" + end - expect(path/"Formula/testball@0.1.rb").to exist + it "retrieves the specified version of formula" do + expect { brew "extract", "testball", target[:name], "--version=0.1" } + .to be_a_success + expect(target[:path]/"Formula/testball@0.1.rb").to exist + expect(Formulary.factory(target[:path]/"Formula/testball@0.1.rb").version).to be == "0.1" + end - expect(Formulary.factory(path/"Formula/testball@0.1.rb").version).to be == "0.1" + it "retrieves the compatible version of formula" do + expect { brew "extract", "testball", target[:name], "--version=0", "--debug" } + .to be_a_success + expect(target[:path]/"Formula/testball@0.rb").to exist + expect(Formulary.factory(target[:path]/"Formula/testball@0.rb").version).to be == "0.2" end end