Merge pull request #5887 from kiendang/extract-all-taps
brew extract from all taps
This commit is contained in:
commit
373c0242fe
@ -81,7 +81,8 @@ module Homebrew
|
||||
|
||||
Look through repository history to find the most recent version of <formula> and
|
||||
create a copy in <tap>`/Formula/`<formula>`@`<version>`.rb`. If the tap is not
|
||||
installed yet, attempt to install/clone the tap before continuing.
|
||||
installed yet, attempt to install/clone the tap before continuing. To extract
|
||||
a <formula> from a tap that is not homebrew/core use <user>/<repo>/<formula>.
|
||||
EOS
|
||||
|
||||
flag "--version=",
|
||||
@ -97,47 +98,70 @@ 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 = if source_tap.core_tap?
|
||||
[repo/"Formula/#{name}.rb"]
|
||||
else
|
||||
# A formula can technically live in the root directory of a tap or in any of its subdirectories
|
||||
[repo/"#{name}.rb", repo/"**/#{name}.rb"]
|
||||
end
|
||||
|
||||
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)
|
||||
# Search in the root directory of <repo> as well as recursively in all of its subdirectories
|
||||
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,
|
||||
|
||||
@ -4,7 +4,11 @@ module Git
|
||||
module_function
|
||||
|
||||
def last_revision_commit_of_file(repo, file, before_commit: nil)
|
||||
args = [before_commit.nil? ? "--skip=1" : before_commit.split("..").first]
|
||||
args = if before_commit.nil?
|
||||
["--skip=1"]
|
||||
else
|
||||
[before_commit.split("..").first]
|
||||
end
|
||||
|
||||
out, = Open3.capture3(
|
||||
HOMEBREW_SHIMS_PATH/"scm/git", "-C", repo,
|
||||
@ -14,6 +18,28 @@ module Git
|
||||
out.chomp
|
||||
end
|
||||
|
||||
def last_revision_commit_of_files(repo, files, before_commit: nil)
|
||||
args = if before_commit.nil?
|
||||
["--skip=1"]
|
||||
else
|
||||
[before_commit.split("..").first]
|
||||
end
|
||||
|
||||
# git log output format:
|
||||
# <commit_hash>
|
||||
# <file_path1>
|
||||
# <file_path2>
|
||||
# ...
|
||||
# return [<commit_hash>, [file_path1, file_path2, ...]]
|
||||
out, = Open3.capture3(
|
||||
HOMEBREW_SHIMS_PATH/"scm/git", "-C", repo, "log",
|
||||
"--pretty=format:%h", "--abbrev=7", "--max-count=1",
|
||||
"--diff-filter=d", "--name-only", *args, "--", *files
|
||||
)
|
||||
rev, *paths = out.chomp.split(/\n/).reject(&:empty?)
|
||||
[rev, paths]
|
||||
end
|
||||
|
||||
def last_revision_of_file(repo, file, before_commit: nil)
|
||||
relative_file = Pathname(file).relative_path_from(repo)
|
||||
|
||||
|
||||
@ -782,7 +782,8 @@ Homebrew repository for editing if no *`formula`* is provided.
|
||||
|
||||
Look through repository history to find the most recent version of *`formula`* and
|
||||
create a copy in *`tap`*`/Formula/`*`formula`*`@`*`version`*`.rb`. If the tap is not
|
||||
installed yet, attempt to install/clone the tap before continuing.
|
||||
installed yet, attempt to install/clone the tap before continuing. To extract a
|
||||
*`formula`* from a tap that is not homebrew/core use *`user`*/*`repo`*/*`formula`*.
|
||||
|
||||
* `--version`:
|
||||
Extract the provided *`version`* of *`formula`* instead of the most recent.
|
||||
|
||||
@ -981,7 +981,7 @@ Generate the new formula in the provided tap, specified as \fIuser\fR\fB/\fR\fIr
|
||||
Open a formula in the editor set by \fBEDITOR\fR or \fBHOMEBREW_EDITOR\fR, or open the Homebrew repository for editing if no \fIformula\fR is provided\.
|
||||
.
|
||||
.SS "\fBextract\fR [\fIoptions\fR] \fIformula\fR \fItap\fR"
|
||||
Look through repository history to find the most recent version of \fIformula\fR and create a copy in \fItap\fR\fB/Formula/\fR\fIformula\fR\fB@\fR\fIversion\fR\fB\.rb\fR\. If the tap is not installed yet, attempt to install/clone the tap before continuing\.
|
||||
Look through repository history to find the most recent version of \fIformula\fR and create a copy in \fItap\fR\fB/Formula/\fR\fIformula\fR\fB@\fR\fIversion\fR\fB\.rb\fR\. If the tap is not installed yet, attempt to install/clone the tap before continuing\. To extract a \fIformula\fR from a tap that is not homebrew/core use \fIuser\fR/\fIrepo\fR/\fIformula\fR\.
|
||||
.
|
||||
.TP
|
||||
\fB\-\-version\fR
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user