Merge pull request #14783 from MikeMcQuaid/official_tap_formula_cask_subdirs
Support loading formulae/casks from subdirectories
This commit is contained in:
commit
bb4d518c0b
@ -167,7 +167,9 @@ module Cask
|
|||||||
|
|
||||||
def initialize(tapped_name)
|
def initialize(tapped_name)
|
||||||
user, repo, token = tapped_name.split("/", 3)
|
user, repo, token = tapped_name.split("/", 3)
|
||||||
super Tap.fetch(user, repo).cask_dir/"#{token}.rb"
|
tap = Tap.fetch(user, repo)
|
||||||
|
cask = CaskLoader.find_cask_in_tap(token, tap)
|
||||||
|
super cask
|
||||||
end
|
end
|
||||||
|
|
||||||
def load(config:)
|
def load(config:)
|
||||||
@ -421,8 +423,15 @@ module Cask
|
|||||||
end
|
end
|
||||||
|
|
||||||
def self.tap_paths(token)
|
def self.tap_paths(token)
|
||||||
Tap.map { |t| t.cask_dir/"#{token.to_s.downcase}.rb" }
|
Tap.map do |tap|
|
||||||
.select(&:exist?)
|
find_cask_in_tap(token.to_s.downcase, tap)
|
||||||
|
end.select(&:exist?)
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.find_cask_in_tap(token, tap)
|
||||||
|
filename = "#{token}.rb"
|
||||||
|
|
||||||
|
Tap.cask_files_by_name(tap).fetch(filename, tap.cask_dir/filename)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -50,17 +50,14 @@ module Homebrew
|
|||||||
tap_count = 0
|
tap_count = 0
|
||||||
formula_count = 0
|
formula_count = 0
|
||||||
command_count = 0
|
command_count = 0
|
||||||
pinned_count = 0
|
|
||||||
private_count = 0
|
private_count = 0
|
||||||
Tap.each do |tap|
|
Tap.each do |tap|
|
||||||
tap_count += 1
|
tap_count += 1
|
||||||
formula_count += tap.formula_files.size
|
formula_count += tap.formula_files.size
|
||||||
command_count += tap.command_files.size
|
command_count += tap.command_files.size
|
||||||
pinned_count += 1 if tap.pinned?
|
|
||||||
private_count += 1 if tap.private?
|
private_count += 1 if tap.private?
|
||||||
end
|
end
|
||||||
info = "#{tap_count} #{"tap".pluralize(tap_count)}"
|
info = "#{tap_count} #{"tap".pluralize(tap_count)}"
|
||||||
info += ", #{pinned_count} pinned"
|
|
||||||
info += ", #{private_count} private"
|
info += ", #{private_count} private"
|
||||||
info += ", #{formula_count} #{"formula".pluralize(formula_count)}"
|
info += ", #{formula_count} #{"formula".pluralize(formula_count)}"
|
||||||
info += ", #{command_count} #{"command".pluralize(command_count)}"
|
info += ", #{command_count} #{"command".pluralize(command_count)}"
|
||||||
|
|||||||
@ -516,15 +516,14 @@ module Formulary
|
|||||||
def formula_name_path(tapped_name, warn: true)
|
def formula_name_path(tapped_name, warn: true)
|
||||||
user, repo, name = tapped_name.split("/", 3).map(&:downcase)
|
user, repo, name = tapped_name.split("/", 3).map(&:downcase)
|
||||||
@tap = Tap.fetch user, repo
|
@tap = Tap.fetch user, repo
|
||||||
formula_dir = @tap.formula_dir || @tap.path
|
path = find_formula_from_name(name)
|
||||||
path = formula_dir/"#{name}.rb"
|
|
||||||
|
|
||||||
unless path.file?
|
unless path.file?
|
||||||
if (possible_alias = @tap.alias_dir/name).file?
|
if (possible_alias = @tap.alias_dir/name).file?
|
||||||
path = possible_alias.resolved_path
|
path = possible_alias.resolved_path
|
||||||
name = path.basename(".rb").to_s
|
name = path.basename(".rb").to_s
|
||||||
elsif (new_name = @tap.formula_renames[name]) &&
|
elsif (new_name = @tap.formula_renames[name]) &&
|
||||||
(new_path = formula_dir/"#{new_name}.rb").file?
|
(new_path = find_formula_from_name(new_name)).file?
|
||||||
old_name = name
|
old_name = name
|
||||||
path = new_path
|
path = new_path
|
||||||
name = new_name
|
name = new_name
|
||||||
@ -562,6 +561,12 @@ module Formulary
|
|||||||
e.issues_url = tap.issues_url || tap.to_s
|
e.issues_url = tap.issues_url || tap.to_s
|
||||||
raise
|
raise
|
||||||
end
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def find_formula_from_name(name)
|
||||||
|
Formulary.find_formula_in_tap(name, @tap)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Pseudo-loader which will raise a {FormulaUnavailableError} when trying to load the corresponding formula.
|
# Pseudo-loader which will raise a {FormulaUnavailableError} when trying to load the corresponding formula.
|
||||||
@ -800,22 +805,28 @@ module Formulary
|
|||||||
end
|
end
|
||||||
|
|
||||||
def self.core_path(name)
|
def self.core_path(name)
|
||||||
CoreTap.instance.formula_dir/"#{name.to_s.downcase}.rb"
|
find_formula_in_tap(name.to_s.downcase, CoreTap.instance)
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.core_alias_path(name)
|
def self.core_alias_path(name)
|
||||||
CoreTap.instance.alias_dir/name.to_s.downcase
|
CoreTap.instance.alias_dir/name.to_s.downcase
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.tap_paths(name, taps = Dir[HOMEBREW_LIBRARY/"Taps/*/*/"])
|
def self.tap_paths(name, taps = Tap)
|
||||||
name = name.to_s.downcase
|
name = name.to_s.downcase
|
||||||
taps.map do |tap|
|
taps.map do |tap|
|
||||||
Pathname.glob([
|
formula_path = find_formula_in_tap(name, tap)
|
||||||
"#{tap}Formula/#{name}.rb",
|
|
||||||
"#{tap}HomebrewFormula/#{name}.rb",
|
alias_path = tap.alias_dir/name
|
||||||
"#{tap}#{name}.rb",
|
next alias_path if !formula_path.exist? && alias_path.exist?
|
||||||
"#{tap}Aliases/#{name}",
|
|
||||||
]).find(&:file?)
|
formula_path
|
||||||
end.compact
|
end.select(&:file?)
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.find_formula_in_tap(name, tap)
|
||||||
|
filename = "#{name}.rb"
|
||||||
|
|
||||||
|
Tap.formula_files_by_name(tap).fetch(filename, tap.formula_dir/filename)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
# typed: false
|
# typed: true
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require "commands"
|
require "commands"
|
||||||
@ -416,7 +416,6 @@ class Tap
|
|||||||
abv = path.abv
|
abv = path.abv
|
||||||
formatted_contents = contents.presence&.to_sentence&.dup&.prepend(" ")
|
formatted_contents = contents.presence&.to_sentence&.dup&.prepend(" ")
|
||||||
|
|
||||||
unpin if pinned?
|
|
||||||
CacheStoreDatabase.use(:descriptions) do |db|
|
CacheStoreDatabase.use(:descriptions) do |db|
|
||||||
DescriptionCacheStore.new(db)
|
DescriptionCacheStore.new(db)
|
||||||
.delete_from_formula_names!(formula_names)
|
.delete_from_formula_names!(formula_names)
|
||||||
@ -451,15 +450,23 @@ class Tap
|
|||||||
end
|
end
|
||||||
|
|
||||||
# Path to the directory of all {Formula} files for this {Tap}.
|
# Path to the directory of all {Formula} files for this {Tap}.
|
||||||
|
sig { returns(Pathname) }
|
||||||
def formula_dir
|
def formula_dir
|
||||||
@formula_dir ||= potential_formula_dirs.find(&:directory?) || (path/"Formula")
|
# Official formulae taps always use this directory, saves time to hardcode.
|
||||||
|
@formula_dir ||= if official?
|
||||||
|
path/"Formula"
|
||||||
|
else
|
||||||
|
potential_formula_dirs.find(&:directory?) || (path/"Formula")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { returns(T::Array[Pathname]) }
|
||||||
def potential_formula_dirs
|
def potential_formula_dirs
|
||||||
@potential_formula_dirs ||= [path/"Formula", path/"HomebrewFormula", path].freeze
|
@potential_formula_dirs ||= [path/"Formula", path/"HomebrewFormula", path].freeze
|
||||||
end
|
end
|
||||||
|
|
||||||
# Path to the directory of all {Cask} files for this {Tap}.
|
# Path to the directory of all {Cask} files for this {Tap}.
|
||||||
|
sig { returns(Pathname) }
|
||||||
def cask_dir
|
def cask_dir
|
||||||
@cask_dir ||= path/"Casks"
|
@cask_dir ||= path/"Casks"
|
||||||
end
|
end
|
||||||
@ -483,15 +490,35 @@ class Tap
|
|||||||
end
|
end
|
||||||
|
|
||||||
# An array of all {Formula} files of this {Tap}.
|
# An array of all {Formula} files of this {Tap}.
|
||||||
|
sig { returns(T::Array[Pathname]) }
|
||||||
def formula_files
|
def formula_files
|
||||||
@formula_files ||= if formula_dir.directory?
|
@formula_files ||= if formula_dir.directory?
|
||||||
formula_dir.children.select(&method(:ruby_file?))
|
# TODO: odeprecate the non-official/old logic with a new minor release somehow?
|
||||||
|
if official?
|
||||||
|
formula_dir.find
|
||||||
|
else
|
||||||
|
formula_dir.children
|
||||||
|
end.select(&method(:ruby_file?))
|
||||||
else
|
else
|
||||||
[]
|
[]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# A cached hash of {Formula} basenames to {Formula} file pathnames for a {Tap}
|
||||||
|
sig { params(tap: Tap).returns(T::Hash[String, Pathname]) }
|
||||||
|
def self.formula_files_by_name(tap)
|
||||||
|
cache_key = "formula_files_by_name_#{tap}"
|
||||||
|
cache.fetch(cache_key) do |key|
|
||||||
|
cache[key] = tap.formula_files.each_with_object({}) do |file, hash|
|
||||||
|
# If there's more than one file with the same basename: intentionally
|
||||||
|
# ignore the later ones here.
|
||||||
|
hash[file.basename.to_s] ||= file
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# An array of all versioned {Formula} files of this {Tap}.
|
# An array of all versioned {Formula} files of this {Tap}.
|
||||||
|
sig { returns(T::Array[Pathname]) }
|
||||||
def versioned_formula_files
|
def versioned_formula_files
|
||||||
@versioned_formula_files ||= formula_files.select do |file|
|
@versioned_formula_files ||= formula_files.select do |file|
|
||||||
file.basename(".rb").to_s =~ /@[\d.]+$/
|
file.basename(".rb").to_s =~ /@[\d.]+$/
|
||||||
@ -499,16 +526,37 @@ class Tap
|
|||||||
end
|
end
|
||||||
|
|
||||||
# An array of all {Cask} files of this {Tap}.
|
# An array of all {Cask} files of this {Tap}.
|
||||||
|
sig { returns(T::Array[Pathname]) }
|
||||||
def cask_files
|
def cask_files
|
||||||
@cask_files ||= if cask_dir.directory?
|
@cask_files ||= if cask_dir.directory?
|
||||||
cask_dir.children.select(&method(:ruby_file?))
|
# TODO: odeprecate the non-official/old logic with a new minor release somehow?
|
||||||
|
if official?
|
||||||
|
cask_dir.find
|
||||||
|
else
|
||||||
|
cask_dir.children
|
||||||
|
end.select(&method(:ruby_file?))
|
||||||
else
|
else
|
||||||
[]
|
[]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# A cached hash of {Cask} basenames to {Cask} file pathnames for a {Tap}
|
||||||
|
sig { params(tap: Tap).returns(T::Hash[String, Pathname]) }
|
||||||
|
def self.cask_files_by_name(tap)
|
||||||
|
cache_key = "cask_files_by_name_#{tap}"
|
||||||
|
|
||||||
|
cache.fetch(cache_key) do |key|
|
||||||
|
cache[key] = tap.cask_files.each_with_object({}) do |file, hash|
|
||||||
|
# If there's more than one file with the same basename: intentionally
|
||||||
|
# ignore the later ones here.
|
||||||
|
hash[file.basename.to_s] ||= file
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# returns true if the file has a Ruby extension
|
# returns true if the file has a Ruby extension
|
||||||
# @private
|
# @private
|
||||||
|
sig { params(file: Pathname).returns(T::Boolean) }
|
||||||
def ruby_file?(file)
|
def ruby_file?(file)
|
||||||
file.extname == ".rb"
|
file.extname == ".rb"
|
||||||
end
|
end
|
||||||
@ -516,45 +564,56 @@ class Tap
|
|||||||
# return true if given path would present a {Formula} file in this {Tap}.
|
# return true if given path would present a {Formula} file in this {Tap}.
|
||||||
# accepts both absolute path and relative path (relative to this {Tap}'s path)
|
# accepts both absolute path and relative path (relative to this {Tap}'s path)
|
||||||
# @private
|
# @private
|
||||||
|
sig { params(file: T.any(String, Pathname)).returns(T::Boolean) }
|
||||||
def formula_file?(file)
|
def formula_file?(file)
|
||||||
file = Pathname.new(file) unless file.is_a? Pathname
|
file = Pathname.new(file) unless file.is_a? Pathname
|
||||||
file = file.expand_path(path)
|
file = file.expand_path(path)
|
||||||
ruby_file?(file) && file.parent == formula_dir
|
return false unless ruby_file?(file)
|
||||||
|
|
||||||
|
file.to_s.start_with?("#{formula_dir}/")
|
||||||
end
|
end
|
||||||
|
|
||||||
# return true if given path would present a {Cask} file in this {Tap}.
|
# return true if given path would present a {Cask} file in this {Tap}.
|
||||||
# accepts both absolute path and relative path (relative to this {Tap}'s path)
|
# accepts both absolute path and relative path (relative to this {Tap}'s path)
|
||||||
# @private
|
# @private
|
||||||
|
sig { params(file: T.any(String, Pathname)).returns(T::Boolean) }
|
||||||
def cask_file?(file)
|
def cask_file?(file)
|
||||||
file = Pathname.new(file) unless file.is_a? Pathname
|
file = Pathname.new(file) unless file.is_a? Pathname
|
||||||
file = file.expand_path(path)
|
file = file.expand_path(path)
|
||||||
ruby_file?(file) && file.parent == cask_dir
|
return false unless ruby_file?(file)
|
||||||
|
|
||||||
|
file.to_s.start_with?("#{cask_dir}/")
|
||||||
end
|
end
|
||||||
|
|
||||||
# An array of all {Formula} names of this {Tap}.
|
# An array of all {Formula} names of this {Tap}.
|
||||||
|
sig { returns(T::Array[String]) }
|
||||||
def formula_names
|
def formula_names
|
||||||
@formula_names ||= formula_files.map(&method(:formula_file_to_name))
|
@formula_names ||= formula_files.map(&method(:formula_file_to_name))
|
||||||
end
|
end
|
||||||
|
|
||||||
# An array of all {Cask} tokens of this {Tap}.
|
# An array of all {Cask} tokens of this {Tap}.
|
||||||
|
sig { returns(T::Array[String]) }
|
||||||
def cask_tokens
|
def cask_tokens
|
||||||
@cask_tokens ||= cask_files.map(&method(:formula_file_to_name))
|
@cask_tokens ||= cask_files.map(&method(:formula_file_to_name))
|
||||||
end
|
end
|
||||||
|
|
||||||
# path to the directory of all alias files for this {Tap}.
|
# path to the directory of all alias files for this {Tap}.
|
||||||
# @private
|
# @private
|
||||||
|
sig { returns(Pathname) }
|
||||||
def alias_dir
|
def alias_dir
|
||||||
@alias_dir ||= path/"Aliases"
|
@alias_dir ||= path/"Aliases"
|
||||||
end
|
end
|
||||||
|
|
||||||
# an array of all alias files of this {Tap}.
|
# an array of all alias files of this {Tap}.
|
||||||
# @private
|
# @private
|
||||||
|
sig { returns(T::Array[Pathname]) }
|
||||||
def alias_files
|
def alias_files
|
||||||
@alias_files ||= Pathname.glob("#{alias_dir}/*").select(&:file?)
|
@alias_files ||= Pathname.glob("#{alias_dir}/*").select(&:file?)
|
||||||
end
|
end
|
||||||
|
|
||||||
# an array of all aliases of this {Tap}.
|
# an array of all aliases of this {Tap}.
|
||||||
# @private
|
# @private
|
||||||
|
sig { returns(T::Array[String]) }
|
||||||
def aliases
|
def aliases
|
||||||
@aliases ||= alias_files.map { |f| alias_file_to_name(f) }
|
@aliases ||= alias_files.map { |f| alias_file_to_name(f) }
|
||||||
end
|
end
|
||||||
@ -584,11 +643,13 @@ class Tap
|
|||||||
@alias_reverse_table
|
@alias_reverse_table
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { returns(Pathname) }
|
||||||
def command_dir
|
def command_dir
|
||||||
@command_dir ||= path/"cmd"
|
@command_dir ||= path/"cmd"
|
||||||
end
|
end
|
||||||
|
|
||||||
# An array of all commands files of this {Tap}.
|
# An array of all commands files of this {Tap}.
|
||||||
|
sig { returns(T::Array[Pathname]) }
|
||||||
def command_files
|
def command_files
|
||||||
@command_files ||= if command_dir.directory?
|
@command_files ||= if command_dir.directory?
|
||||||
Commands.find_commands(command_dir)
|
Commands.find_commands(command_dir)
|
||||||
@ -597,19 +658,7 @@ class Tap
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# path to the pin record for this {Tap}.
|
sig { returns(Hash) }
|
||||||
# @private
|
|
||||||
def pinned_symlink_path
|
|
||||||
HOMEBREW_LIBRARY/"PinnedTaps/#{name}"
|
|
||||||
end
|
|
||||||
|
|
||||||
# True if this {Tap} has been pinned.
|
|
||||||
def pinned?
|
|
||||||
return @pinned if instance_variable_defined?(:@pinned)
|
|
||||||
|
|
||||||
@pinned = pinned_symlink_path.directory?
|
|
||||||
end
|
|
||||||
|
|
||||||
def to_hash
|
def to_hash
|
||||||
hash = {
|
hash = {
|
||||||
"name" => name,
|
"name" => name,
|
||||||
@ -635,6 +684,7 @@ class Tap
|
|||||||
end
|
end
|
||||||
|
|
||||||
# Hash with tap formula renames.
|
# Hash with tap formula renames.
|
||||||
|
sig { returns(Hash) }
|
||||||
def formula_renames
|
def formula_renames
|
||||||
@formula_renames ||= if (rename_file = path/HOMEBREW_TAP_FORMULA_RENAMES_FILE).file?
|
@formula_renames ||= if (rename_file = path/HOMEBREW_TAP_FORMULA_RENAMES_FILE).file?
|
||||||
JSON.parse(rename_file.read)
|
JSON.parse(rename_file.read)
|
||||||
@ -644,6 +694,7 @@ class Tap
|
|||||||
end
|
end
|
||||||
|
|
||||||
# Hash with tap migrations.
|
# Hash with tap migrations.
|
||||||
|
sig { returns(Hash) }
|
||||||
def tap_migrations
|
def tap_migrations
|
||||||
@tap_migrations ||= if (migration_file = path/HOMEBREW_TAP_MIGRATIONS_FILE).file?
|
@tap_migrations ||= if (migration_file = path/HOMEBREW_TAP_MIGRATIONS_FILE).file?
|
||||||
JSON.parse(migration_file.read)
|
JSON.parse(migration_file.read)
|
||||||
@ -665,18 +716,19 @@ class Tap
|
|||||||
end
|
end
|
||||||
|
|
||||||
# Hash with pypi formula mappings
|
# Hash with pypi formula mappings
|
||||||
sig { returns(Hash) }
|
|
||||||
def pypi_formula_mappings
|
def pypi_formula_mappings
|
||||||
@pypi_formula_mappings = read_formula_list path/HOMEBREW_TAP_PYPI_FORMULA_MAPPINGS
|
@pypi_formula_mappings = read_formula_list path/HOMEBREW_TAP_PYPI_FORMULA_MAPPINGS
|
||||||
end
|
end
|
||||||
|
|
||||||
# @private
|
# @private
|
||||||
|
sig { returns(T::Boolean) }
|
||||||
def should_report_analytics?
|
def should_report_analytics?
|
||||||
return Homebrew::EnvConfig.install_from_api? && official? unless installed?
|
return Homebrew::EnvConfig.install_from_api? && official? unless installed?
|
||||||
|
|
||||||
!private?
|
!private?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(other: T.nilable(T.any(String, Tap))).returns(T::Boolean) }
|
||||||
def ==(other)
|
def ==(other)
|
||||||
other = Tap.fetch(other) if other.is_a?(String)
|
other = Tap.fetch(other) if other.is_a?(String)
|
||||||
self.class == other.class && name == other.name
|
self.class == other.class && name == other.name
|
||||||
@ -695,6 +747,7 @@ class Tap
|
|||||||
end
|
end
|
||||||
|
|
||||||
# An array of all installed {Tap} names.
|
# An array of all installed {Tap} names.
|
||||||
|
sig { returns(T::Array[String]) }
|
||||||
def self.names
|
def self.names
|
||||||
map(&:name).sort
|
map(&:name).sort
|
||||||
end
|
end
|
||||||
@ -712,11 +765,13 @@ class Tap
|
|||||||
end
|
end
|
||||||
|
|
||||||
# @private
|
# @private
|
||||||
|
sig { params(file: Pathname).returns(String) }
|
||||||
def formula_file_to_name(file)
|
def formula_file_to_name(file)
|
||||||
"#{name}/#{file.basename(".rb")}"
|
"#{name}/#{file.basename(".rb")}"
|
||||||
end
|
end
|
||||||
|
|
||||||
# @private
|
# @private
|
||||||
|
sig { params(file: Pathname).returns(String) }
|
||||||
def alias_file_to_name(file)
|
def alias_file_to_name(file)
|
||||||
"#{name}/#{file.basename}"
|
"#{name}/#{file.basename}"
|
||||||
end
|
end
|
||||||
@ -796,10 +851,12 @@ class CoreTap < Tap
|
|||||||
super "Homebrew", "core"
|
super "Homebrew", "core"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { returns(CoreTap) }
|
||||||
def self.instance
|
def self.instance
|
||||||
@instance ||= new
|
@instance ||= new
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { void }
|
||||||
def self.ensure_installed!
|
def self.ensure_installed!
|
||||||
return if instance.installed?
|
return if instance.installed?
|
||||||
return if Homebrew::EnvConfig.install_from_api?
|
return if Homebrew::EnvConfig.install_from_api?
|
||||||
@ -811,6 +868,7 @@ class CoreTap < Tap
|
|||||||
instance.install
|
instance.install
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { returns(String) }
|
||||||
def remote
|
def remote
|
||||||
super if installed? || !Homebrew::EnvConfig.install_from_api?
|
super if installed? || !Homebrew::EnvConfig.install_from_api?
|
||||||
|
|
||||||
@ -840,24 +898,6 @@ class CoreTap < Tap
|
|||||||
super
|
super
|
||||||
end
|
end
|
||||||
|
|
||||||
# @private
|
|
||||||
sig { void }
|
|
||||||
def pin
|
|
||||||
raise "Tap#pin is not available for CoreTap"
|
|
||||||
end
|
|
||||||
|
|
||||||
# @private
|
|
||||||
sig { void }
|
|
||||||
def unpin
|
|
||||||
raise "Tap#unpin is not available for CoreTap"
|
|
||||||
end
|
|
||||||
|
|
||||||
# @private
|
|
||||||
sig { returns(T::Boolean) }
|
|
||||||
def pinned?
|
|
||||||
false
|
|
||||||
end
|
|
||||||
|
|
||||||
# @private
|
# @private
|
||||||
sig { returns(T::Boolean) }
|
sig { returns(T::Boolean) }
|
||||||
def core_tap?
|
def core_tap?
|
||||||
@ -871,6 +911,7 @@ class CoreTap < Tap
|
|||||||
end
|
end
|
||||||
|
|
||||||
# @private
|
# @private
|
||||||
|
sig { returns(Pathname) }
|
||||||
def formula_dir
|
def formula_dir
|
||||||
@formula_dir ||= begin
|
@formula_dir ||= begin
|
||||||
self.class.ensure_installed!
|
self.class.ensure_installed!
|
||||||
@ -879,6 +920,7 @@ class CoreTap < Tap
|
|||||||
end
|
end
|
||||||
|
|
||||||
# @private
|
# @private
|
||||||
|
sig { returns(Pathname) }
|
||||||
def alias_dir
|
def alias_dir
|
||||||
@alias_dir ||= begin
|
@alias_dir ||= begin
|
||||||
self.class.ensure_installed!
|
self.class.ensure_installed!
|
||||||
@ -887,6 +929,7 @@ class CoreTap < Tap
|
|||||||
end
|
end
|
||||||
|
|
||||||
# @private
|
# @private
|
||||||
|
sig { returns(Hash) }
|
||||||
def formula_renames
|
def formula_renames
|
||||||
@formula_renames ||= begin
|
@formula_renames ||= begin
|
||||||
self.class.ensure_installed!
|
self.class.ensure_installed!
|
||||||
@ -895,6 +938,7 @@ class CoreTap < Tap
|
|||||||
end
|
end
|
||||||
|
|
||||||
# @private
|
# @private
|
||||||
|
sig { returns(Hash) }
|
||||||
def tap_migrations
|
def tap_migrations
|
||||||
@tap_migrations ||= begin
|
@tap_migrations ||= begin
|
||||||
self.class.ensure_installed!
|
self.class.ensure_installed!
|
||||||
@ -903,6 +947,7 @@ class CoreTap < Tap
|
|||||||
end
|
end
|
||||||
|
|
||||||
# @private
|
# @private
|
||||||
|
sig { returns(Hash) }
|
||||||
def audit_exceptions
|
def audit_exceptions
|
||||||
@audit_exceptions ||= begin
|
@audit_exceptions ||= begin
|
||||||
self.class.ensure_installed!
|
self.class.ensure_installed!
|
||||||
@ -911,6 +956,7 @@ class CoreTap < Tap
|
|||||||
end
|
end
|
||||||
|
|
||||||
# @private
|
# @private
|
||||||
|
sig { returns(Hash) }
|
||||||
def style_exceptions
|
def style_exceptions
|
||||||
@style_exceptions ||= begin
|
@style_exceptions ||= begin
|
||||||
self.class.ensure_installed!
|
self.class.ensure_installed!
|
||||||
@ -919,6 +965,7 @@ class CoreTap < Tap
|
|||||||
end
|
end
|
||||||
|
|
||||||
# @private
|
# @private
|
||||||
|
sig { returns(Hash) }
|
||||||
def pypi_formula_mappings
|
def pypi_formula_mappings
|
||||||
@pypi_formula_mappings ||= begin
|
@pypi_formula_mappings ||= begin
|
||||||
self.class.ensure_installed!
|
self.class.ensure_installed!
|
||||||
@ -927,16 +974,19 @@ class CoreTap < Tap
|
|||||||
end
|
end
|
||||||
|
|
||||||
# @private
|
# @private
|
||||||
|
sig { params(file: Pathname).returns(String) }
|
||||||
def formula_file_to_name(file)
|
def formula_file_to_name(file)
|
||||||
file.basename(".rb").to_s
|
file.basename(".rb").to_s
|
||||||
end
|
end
|
||||||
|
|
||||||
# @private
|
# @private
|
||||||
|
sig { params(file: Pathname).returns(String) }
|
||||||
def alias_file_to_name(file)
|
def alias_file_to_name(file)
|
||||||
file.basename.to_s
|
file.basename.to_s
|
||||||
end
|
end
|
||||||
|
|
||||||
# @private
|
# @private
|
||||||
|
sig { returns(T::Array[String]) }
|
||||||
def aliases
|
def aliases
|
||||||
return super if installed? || !Homebrew::EnvConfig.install_from_api?
|
return super if installed? || !Homebrew::EnvConfig.install_from_api?
|
||||||
|
|
||||||
@ -944,6 +994,7 @@ class CoreTap < Tap
|
|||||||
end
|
end
|
||||||
|
|
||||||
# @private
|
# @private
|
||||||
|
sig { returns(T::Array[String]) }
|
||||||
def formula_names
|
def formula_names
|
||||||
return super if installed? || !Homebrew::EnvConfig.install_from_api?
|
return super if installed? || !Homebrew::EnvConfig.install_from_api?
|
||||||
|
|
||||||
@ -953,8 +1004,11 @@ end
|
|||||||
|
|
||||||
# Permanent configuration per {Tap} using `git-config(1)`.
|
# Permanent configuration per {Tap} using `git-config(1)`.
|
||||||
class TapConfig
|
class TapConfig
|
||||||
|
extend T::Sig
|
||||||
|
|
||||||
attr_reader :tap
|
attr_reader :tap
|
||||||
|
|
||||||
|
sig { params(tap: Tap).void }
|
||||||
def initialize(tap)
|
def initialize(tap)
|
||||||
@tap = tap
|
@tap = tap
|
||||||
end
|
end
|
||||||
|
|||||||
@ -0,0 +1,35 @@
|
|||||||
|
# typed: false
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
describe Cask::CaskLoader::FromTapLoader do
|
||||||
|
let(:cask_name) { "testball" }
|
||||||
|
let(:cask_full_name) { "homebrew/cask/#{cask_name}" }
|
||||||
|
let(:cask_path) { Tap.default_cask_tap.cask_dir/"#{cask_name}.rb" }
|
||||||
|
|
||||||
|
describe "#load" do
|
||||||
|
before do
|
||||||
|
cask_path.parent.mkpath
|
||||||
|
cask_path.write <<~RUBY
|
||||||
|
cask '#{cask_name}' do
|
||||||
|
url 'https://brew.sh/'
|
||||||
|
end
|
||||||
|
RUBY
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns a Cask" do
|
||||||
|
expect(described_class.new(cask_full_name).load(config: nil)).to be_a(Cask::Cask)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "raises an error if the Cask cannot be found" do
|
||||||
|
expect { described_class.new("foo/bar/baz").load(config: nil) }.to raise_error(Cask::CaskUnavailableError)
|
||||||
|
end
|
||||||
|
|
||||||
|
context "with sharded Cask directory" do
|
||||||
|
let(:cask_path) { Tap.default_cask_tap.cask_dir/cask_name[0]/"#{cask_name}.rb" }
|
||||||
|
|
||||||
|
it "returns a Cask" do
|
||||||
|
expect(described_class.new(cask_full_name).load(config: nil)).to be_a(Cask::Cask)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@ -81,6 +81,21 @@ describe Formulary do
|
|||||||
}.to raise_error(ArgumentError)
|
}.to raise_error(ArgumentError)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context "with sharded Formula directory" do
|
||||||
|
before { CoreTap.instance.clear_cache }
|
||||||
|
|
||||||
|
let(:formula_name) { "testball_sharded" }
|
||||||
|
let(:formula_path) { CoreTap.new.formula_dir/formula_name[0]/"#{formula_name}.rb" }
|
||||||
|
|
||||||
|
it "returns a Formula" do
|
||||||
|
expect(described_class.factory(formula_name)).to be_a(Formula)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns a Formula when given a fully qualified name" do
|
||||||
|
expect(described_class.factory("homebrew/core/#{formula_name}")).to be_a(Formula)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
context "when the Formula has the wrong class" do
|
context "when the Formula has the wrong class" do
|
||||||
let(:formula_name) { "giraffe" }
|
let(:formula_name) { "giraffe" }
|
||||||
let(:formula_content) do
|
let(:formula_content) do
|
||||||
@ -171,7 +186,7 @@ describe Formulary do
|
|||||||
context "when loading from Tap" do
|
context "when loading from Tap" do
|
||||||
let(:tap) { Tap.new("homebrew", "foo") }
|
let(:tap) { Tap.new("homebrew", "foo") }
|
||||||
let(:another_tap) { Tap.new("homebrew", "bar") }
|
let(:another_tap) { Tap.new("homebrew", "bar") }
|
||||||
let(:formula_path) { tap.path/"#{formula_name}.rb" }
|
let(:formula_path) { tap.path/"Formula/#{formula_name}.rb" }
|
||||||
|
|
||||||
it "returns a Formula when given a name" do
|
it "returns a Formula when given a name" do
|
||||||
expect(described_class.factory(formula_name)).to be_a(Formula)
|
expect(described_class.factory(formula_name)).to be_a(Formula)
|
||||||
@ -195,8 +210,8 @@ describe Formulary do
|
|||||||
end
|
end
|
||||||
|
|
||||||
it "raises an error if a Formula is in multiple Taps" do
|
it "raises an error if a Formula is in multiple Taps" do
|
||||||
another_tap.path.mkpath
|
(another_tap.path/"Formula").mkpath
|
||||||
(another_tap.path/"#{formula_name}.rb").write formula_content
|
(another_tap.path/"Formula/#{formula_name}.rb").write formula_content
|
||||||
|
|
||||||
expect {
|
expect {
|
||||||
described_class.factory(formula_name)
|
described_class.factory(formula_name)
|
||||||
|
|||||||
@ -61,8 +61,8 @@ describe Homebrew::MissingFormula do
|
|||||||
|
|
||||||
before do
|
before do
|
||||||
tap_path = Tap::TAP_DIRECTORY/"homebrew/homebrew-foo"
|
tap_path = Tap::TAP_DIRECTORY/"homebrew/homebrew-foo"
|
||||||
tap_path.mkpath
|
(tap_path/"Formula").mkpath
|
||||||
(tap_path/"deleted-formula.rb").write "placeholder"
|
(tap_path/"Formula/deleted-formula.rb").write "placeholder"
|
||||||
ENV.delete "GIT_AUTHOR_DATE"
|
ENV.delete "GIT_AUTHOR_DATE"
|
||||||
ENV.delete "GIT_COMMITTER_DATE"
|
ENV.delete "GIT_COMMITTER_DATE"
|
||||||
|
|
||||||
@ -70,7 +70,7 @@ describe Homebrew::MissingFormula do
|
|||||||
system "git", "init"
|
system "git", "init"
|
||||||
system "git", "add", "--all"
|
system "git", "add", "--all"
|
||||||
system "git", "commit", "-m", "initial state"
|
system "git", "commit", "-m", "initial state"
|
||||||
system "git", "rm", "deleted-formula.rb"
|
system "git", "rm", "Formula/deleted-formula.rb"
|
||||||
system "git", "commit", "-m", "delete formula 'deleted-formula'"
|
system "git", "commit", "-m", "delete formula 'deleted-formula'"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -528,15 +528,12 @@ describe Tap do
|
|||||||
expect(core_tap.name).to eq("homebrew/core")
|
expect(core_tap.name).to eq("homebrew/core")
|
||||||
expect(core_tap.command_files).to eq([])
|
expect(core_tap.command_files).to eq([])
|
||||||
expect(core_tap).to be_installed
|
expect(core_tap).to be_installed
|
||||||
expect(core_tap).not_to be_pinned
|
|
||||||
expect(core_tap).to be_official
|
expect(core_tap).to be_official
|
||||||
expect(core_tap).to be_a_core_tap
|
expect(core_tap).to be_a_core_tap
|
||||||
end
|
end
|
||||||
|
|
||||||
specify "forbidden operations" do
|
specify "forbidden operations" do
|
||||||
expect { core_tap.uninstall }.to raise_error(RuntimeError)
|
expect { core_tap.uninstall }.to raise_error(RuntimeError)
|
||||||
expect { core_tap.pin }.to raise_error(RuntimeError)
|
|
||||||
expect { core_tap.unpin }.to raise_error(RuntimeError)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
specify "files" do
|
specify "files" do
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user