mirror of
https://github.com/Homebrew/brew.git
synced 2025-07-14 16:09:03 +08:00
Fix loading casks/formulae from relative paths.
This commit is contained in:
parent
977ac20b2b
commit
3da0f8c4a6
@ -207,9 +207,9 @@ module Cask
|
||||
def self.try_new(ref, warn: false)
|
||||
ref = ref.to_s
|
||||
|
||||
return unless ref.match?(HOMEBREW_TAP_CASK_REGEX)
|
||||
return unless (token_tap_type = CaskLoader.tap_cask_token_type(ref, warn: warn))
|
||||
|
||||
token, tap, = CaskLoader.tap_cask_token_type(ref, warn: warn)
|
||||
token, tap, = token_tap_type
|
||||
new("#{tap}/#{token}")
|
||||
end
|
||||
|
||||
@ -529,9 +529,12 @@ module Cask
|
||||
self.for(ref, warn: warn).load(config: config)
|
||||
end
|
||||
|
||||
sig { params(tapped_token: String, warn: T::Boolean).returns(T.nilable([String, Tap, T.nilable(Symbol)])) }
|
||||
def self.tap_cask_token_type(tapped_token, warn:)
|
||||
user, repo, token = tapped_token.split("/", 3).map(&:downcase)
|
||||
tap = Tap.fetch(user, repo)
|
||||
return unless (tap_with_token = Tap.with_cask_token(tapped_token))
|
||||
|
||||
tap, token = tap_with_token
|
||||
|
||||
type = nil
|
||||
|
||||
if (new_token = tap.cask_renames[token].presence)
|
||||
@ -550,7 +553,9 @@ module Cask
|
||||
opoo "Tap migration for #{tapped_token} points to itself, stopping recursion."
|
||||
else
|
||||
old_token = tap.core_cask_tap? ? token : tapped_token
|
||||
token, tap, = tap_cask_token_type(new_tapped_token, warn: false)
|
||||
return unless (token_tap_type = tap_cask_token_type(new_tapped_token, warn: false))
|
||||
|
||||
token, tap, = token_tap_type
|
||||
new_token = new_tap.core_cask_tap? ? token : "#{tap}/#{token}"
|
||||
type = :migration
|
||||
end
|
||||
|
@ -142,8 +142,8 @@ on_request: true)
|
||||
return unless @cask.conflicts_with
|
||||
|
||||
@cask.conflicts_with[:cask].each do |conflicting_cask|
|
||||
if (match = conflicting_cask.match(HOMEBREW_TAP_CASK_REGEX))
|
||||
conflicting_cask_tap = Tap.fetch(match[1], match[2])
|
||||
if (conflicting_cask_tap_with_token = Tap.with_cask_token(conflicting_cask))
|
||||
conflicting_cask_tap, = conflicting_cask_tap_with_token
|
||||
next unless conflicting_cask_tap.installed?
|
||||
end
|
||||
|
||||
|
@ -175,11 +175,13 @@ module Homebrew
|
||||
end
|
||||
|
||||
args.named.each do |name|
|
||||
next if File.exist?(name)
|
||||
next unless name =~ HOMEBREW_TAP_FORMULA_REGEX
|
||||
if (tap_with_name = Tap.with_formula_name(name))
|
||||
tap, = tap_with_name
|
||||
elsif (tap_with_token = Tap.with_cask_token(name))
|
||||
tap, = tap_with_token
|
||||
end
|
||||
|
||||
tap = Tap.fetch(Regexp.last_match(1), Regexp.last_match(2))
|
||||
tap.ensure_installed!
|
||||
tap&.ensure_installed!
|
||||
end
|
||||
|
||||
if args.ignore_dependencies?
|
||||
|
@ -19,7 +19,9 @@ class Dependency
|
||||
@name = name
|
||||
@tags = tags
|
||||
|
||||
@tap = Tap.fetch(Regexp.last_match(1), Regexp.last_match(2)) if name =~ HOMEBREW_TAP_FORMULA_REGEX
|
||||
return unless (tap_with_name = Tap.with_formula_name(name))
|
||||
|
||||
@tap, = tap_with_name
|
||||
end
|
||||
|
||||
def to_s
|
||||
|
@ -34,9 +34,8 @@ module Homebrew
|
||||
def self.extract
|
||||
args = extract_args.parse
|
||||
|
||||
if (match = args.named.first.match(HOMEBREW_TAP_FORMULA_REGEX))
|
||||
name = match[3].downcase
|
||||
source_tap = Tap.fetch(match[1], match[2])
|
||||
if (tap_with_name = args.named.first&.then { Tap.with_formula_name(_1) })
|
||||
source_tap, name = tap_with_name
|
||||
else
|
||||
name = args.named.first.downcase
|
||||
source_tap = CoreTap.instance
|
||||
|
@ -721,15 +721,15 @@ module Formulary
|
||||
}
|
||||
def self.try_new(ref, from: T.unsafe(nil), warn: false)
|
||||
ref = ref.to_s
|
||||
return unless (name = ref[HOMEBREW_TAP_FORMULA_REGEX, :name])
|
||||
|
||||
alias_name = name
|
||||
return unless (name_tap_type = Formulary.tap_formula_name_type(ref, warn: warn))
|
||||
|
||||
name, tap, type = Formulary.tap_formula_name_type(ref, warn: warn)
|
||||
name, tap, type = name_tap_type
|
||||
path = Formulary.find_formula_in_tap(name, tap)
|
||||
|
||||
options = if type == :alias
|
||||
{ alias_name: alias_name.downcase }
|
||||
# TODO: Simplify this by making `tap_formula_name_type` return the alias name.
|
||||
{ alias_name: T.must(ref[HOMEBREW_TAP_FORMULA_REGEX, :name]).downcase }
|
||||
else
|
||||
{}
|
||||
end
|
||||
@ -893,7 +893,9 @@ module Formulary
|
||||
|
||||
ref = "#{CoreTap.instance}/#{name}"
|
||||
|
||||
name, tap, type = Formulary.tap_formula_name_type(ref, warn: warn)
|
||||
return unless (name_tap_type = Formulary.tap_formula_name_type(ref, warn: warn))
|
||||
|
||||
name, tap, type = name_tap_type
|
||||
|
||||
options = if type == :alias
|
||||
{ alias_name: alias_name.downcase }
|
||||
@ -1127,9 +1129,12 @@ module Formulary
|
||||
loader_for(ref).path
|
||||
end
|
||||
|
||||
sig { params(tapped_name: String, warn: T::Boolean).returns(T.nilable([String, Tap, T.nilable(Symbol)])) }
|
||||
def self.tap_formula_name_type(tapped_name, warn:)
|
||||
user, repo, name = tapped_name.split("/", 3).map(&:downcase)
|
||||
tap = Tap.fetch(user, repo)
|
||||
return unless (tap_with_name = Tap.with_formula_name(tapped_name))
|
||||
|
||||
tap, name = tap_with_name
|
||||
|
||||
type = nil
|
||||
|
||||
# FIXME: Remove the need to do this here.
|
||||
@ -1138,7 +1143,7 @@ module Formulary
|
||||
if (possible_alias = tap.alias_table[alias_table_key].presence)
|
||||
# FIXME: Remove the need to split the name and instead make
|
||||
# the alias table only contain short names.
|
||||
name = possible_alias.split("/").last
|
||||
name = T.must(possible_alias.split("/").last)
|
||||
type = :alias
|
||||
elsif (new_name = tap.formula_renames[name].presence)
|
||||
old_name = tap.core_tap? ? name : tapped_name
|
||||
@ -1156,7 +1161,10 @@ module Formulary
|
||||
opoo "Tap migration for #{tapped_name} points to itself, stopping recursion."
|
||||
else
|
||||
old_name = tap.core_tap? ? name : tapped_name
|
||||
name, tap, = tap_formula_name_type(new_tapped_name, warn: false)
|
||||
return unless (name_tap_type = tap_formula_name_type(new_tapped_name, warn: false))
|
||||
|
||||
name, tap, = name_tap_type
|
||||
|
||||
new_name = new_tap.core_tap? ? name : "#{tap}/#{name}"
|
||||
type = :migration
|
||||
end
|
||||
|
@ -65,6 +65,38 @@ class Tap
|
||||
fetch(match[:user], match[:repo])
|
||||
end
|
||||
|
||||
# @private
|
||||
sig { params(name: String).returns(T.nilable([T.attached_class, String])) }
|
||||
def self.with_formula_name(name)
|
||||
return unless (match = name.match(HOMEBREW_TAP_FORMULA_REGEX))
|
||||
|
||||
user = T.must(match[:user])
|
||||
repo = T.must(match[:repo])
|
||||
name = T.must(match[:name])
|
||||
|
||||
# Relative paths are not taps.
|
||||
return if [user, repo].intersect?([".", ".."])
|
||||
|
||||
tap = fetch(user, repo)
|
||||
[tap, name.downcase]
|
||||
end
|
||||
|
||||
# @private
|
||||
sig { params(token: String).returns(T.nilable([T.attached_class, String])) }
|
||||
def self.with_cask_token(token)
|
||||
return unless (match = token.match(HOMEBREW_TAP_CASK_REGEX))
|
||||
|
||||
user = T.must(match[:user])
|
||||
repo = T.must(match[:repo])
|
||||
token = T.must(match[:token])
|
||||
|
||||
# Relative paths are not taps.
|
||||
return if [user, repo].intersect?([".", ".."])
|
||||
|
||||
tap = fetch(user, repo)
|
||||
[tap, token.downcase]
|
||||
end
|
||||
|
||||
sig { returns(CoreCaskTap) }
|
||||
def self.default_cask_tap
|
||||
odisabled "`Tap.default_cask_tap`", "`CoreCaskTap.instance`"
|
||||
|
@ -535,6 +535,22 @@ RSpec.describe Formulary do
|
||||
end
|
||||
|
||||
describe "::loader_for" do
|
||||
context "when given a relative path with two slashes" do
|
||||
it "returns a `FromPathLoader`" do
|
||||
mktmpdir.cd do
|
||||
FileUtils.mkdir "Formula"
|
||||
FileUtils.touch "Formula/gcc.rb"
|
||||
expect(described_class.loader_for("./Formula/gcc.rb")).to be_a Formulary::FromPathLoader
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when given a tapped name" do
|
||||
it "returns a `FromTapLoader`" do
|
||||
expect(described_class.loader_for("homebrew/core/gcc")).to be_a Formulary::FromTapLoader
|
||||
end
|
||||
end
|
||||
|
||||
context "when not using the API" do
|
||||
before do
|
||||
ENV["HOMEBREW_NO_INSTALL_FROM_API"] = "1"
|
||||
|
@ -599,4 +599,24 @@ RSpec.describe Tap do
|
||||
expect(described_class.fetch("my", "tap-with-@-symbol").repo_var_suffix).to eq "_MY_HOMEBREW_TAP_WITH___SYMBOL"
|
||||
end
|
||||
end
|
||||
|
||||
describe "::with_formula_name" do
|
||||
it "returns the tap and formula name when given a full name" do
|
||||
expect(described_class.with_formula_name("homebrew/core/gcc")).to eq [CoreTap.instance, "gcc"]
|
||||
end
|
||||
|
||||
it "returns nil when given a relative path" do
|
||||
expect(described_class.with_formula_name("./Formula/gcc.rb")).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
describe "::with_cask_token" do
|
||||
it "returns the tap and cask token when given a full token" do
|
||||
expect(described_class.with_cask_token("homebrew/cask/alfred")).to eq [CoreCaskTap.instance, "alfred"]
|
||||
end
|
||||
|
||||
it "returns nil when given a relative path" do
|
||||
expect(described_class.with_cask_token("./Casks/alfred.rb")).to be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
Loading…
x
Reference in New Issue
Block a user