Class: Homebrew::DevCmd::Extract Private
- Inherits:
-
AbstractCommand
- Object
- AbstractCommand
- Homebrew::DevCmd::Extract
- Defined in:
- dev-cmd/extract.rb,
sorbet/rbi/dsl/homebrew/dev_cmd/extract.rbi
This class is part of a private API. This class may only be used in the Homebrew/brew repository. Third parties should avoid using this class if possible, as it may be removed or changed without warning.
Defined Under Namespace
Classes: Args
Constant Summary collapse
- BOTTLE_BLOCK_REGEX =
This constant is part of a private API. This constant may only be used in the Homebrew/brew repository. Third parties should avoid using this constant if possible, as it may be removed or changed without warning.
/ bottle (?:do.+?end|:[a-z]+)\n\n/m
Instance Method Summary collapse
- #args ⇒ Homebrew::DevCmd::Extract::Args private
- #run ⇒ void private
Methods inherited from AbstractCommand
command, command_name, dev_cmd?, #initialize, parser, ruby_cmd?
Constructor Details
This class inherits a constructor from Homebrew::AbstractCommand
Instance Method Details
#args ⇒ Homebrew::DevCmd::Extract::Args
This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.
10 |
# File 'sorbet/rbi/dsl/homebrew/dev_cmd/extract.rbi', line 10 def args; end |
#run ⇒ void
This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.
This method returns an undefined value.
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 |
# File 'dev-cmd/extract.rb', line 36 def run if (tap_with_name = args.named.first&.then { Tap.with_formula_name(_1) }) source_tap, name = tap_with_name else name = args.named.fetch(0).downcase source_tap = CoreTap.instance end raise TapFormulaUnavailableError.new(source_tap, name) unless source_tap.installed? destination_tap = Tap.fetch(args.named.fetch(1)) unless Homebrew::EnvConfig.developer? odie "Cannot extract formula to homebrew/core!" if destination_tap.core_tap? odie "Cannot extract formula to homebrew/cask!" if destination_tap.core_cask_tap? odie "Cannot extract formula to the same tap!" if destination_tap == source_tap end destination_tap.install unless destination_tap.installed? repo = source_tap.path start_rev = args.git_revision || "HEAD" pattern = if source_tap.core_tap? [source_tap.new_formula_path(name), repo/"Formula/#{name}.rb"].uniq 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 version_segments = Gem::Version.new(version).segments if Gem::Version.correct?(version) rev = T.let(nil, T.nilable(String)) test_formula = T.let(nil, T.nilable(Formula)) result = "" loop do rev = rev.nil? ? start_rev : "#{rev}~1" rev, (path,) = Utils::Git.last_revision_commit_of_files(repo, pattern, before_commit: rev) if rev.nil? && source_tap.shallow? odie <<~EOS Could not find #{name} but #{source_tap} is a shallow clone! Try again after running: git -C "#{source_tap.path}" fetch --unshallow EOS elsif rev.nil? odie "Could not find #{name}! The formula or version may not have existed." end file = repo/path result = Utils::Git.last_revision_of_file(repo, file, before_commit: rev) if result.empty? 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 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_formula_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 # Search in the root directory of `repository` as well as recursively in all of its subdirectories. files = if start_rev == "HEAD" Dir[repo/"{,**/}"].filter_map do |dir| Pathname.glob("#{dir}/#{name}.rb").find(&:file?) end else [] end if files.empty? ohai "Searching repository history" rev, (path,) = Utils::Git.last_revision_commit_of_files(repo, pattern, before_commit: start_rev) odie "Could not find #{name}! The formula or version may not have existed." if rev.nil? file = repo/path version = T.must(formula_at_revision(repo, name, file, rev)).version result = Utils::Git.last_revision_of_file(repo, file) else file = files.fetch(0).realpath rev = T.let("HEAD", T.nilable(String)) version = Formulary.factory(file).version result = File.read(file) end end # The class name has to be renamed to match the new filename, # e.g. Foo version 1.2.3 becomes FooAT123 and resides in Foo@1.2.3.rb. class_name = Formulary.class_s(name) # The version can only contain digits with decimals in between. version_string = version.to_s .sub(/\D*(.+?)\D*$/, "\\1") .gsub(/\D+/, ".") # Remove any existing version suffixes, as a new one will be added later. name.sub!(/\b@(.*)\z\b/i, "") versioned_name = Formulary.class_s("#{name}@#{version_string}") result.sub!("class #{class_name} < Formula", "class #{versioned_name} < Formula") # Remove bottle blocks, as they won't work. result.sub!(BOTTLE_BLOCK_REGEX, "") path = destination_tap.path/"Formula/#{name}@#{version_string}.rb" if path.exist? unless args.force? odie <<~EOS Destination formula already exists: #{path} To overwrite it and continue anyways, run: brew extract --force --version=#{version} #{name} #{destination_tap.name} EOS end odebug "Overwriting existing formula at #{path}" path.delete end ohai "Writing formula for #{name} at #{version} from revision #{rev} to:", path path.dirname.mkpath path.write result end |