Various sharding fixes
- Load paths with no API when needed (e.g. for `brew edit`) - Use no API mode for `brew log` as it's needed there - Define sharding format for homebrew-cask and homebrew-core inside `Tap` methods - Create new formulae/casks in location defined by these `Tap` methods - Fix a bug in Formulary that made sharded formulae lookup less efficient (and possibly broke it for core and some API usage) - Fix various other hardcoded Formula/Cask directory assumptions Co-authored-by: Bo Anderson <mail@boanderson.me>
This commit is contained in:
parent
4877de52d3
commit
b3c33d34ab
@ -381,6 +381,8 @@ module Cask
|
||||
sig { void }
|
||||
def audit_token_conflicts
|
||||
return unless token_conflicts?
|
||||
|
||||
Homebrew.with_no_api_env do
|
||||
return unless core_formula_names.include?(cask.token)
|
||||
|
||||
add_error(
|
||||
@ -388,6 +390,7 @@ module Cask
|
||||
strict_only: true,
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
sig { void }
|
||||
def audit_token_valid
|
||||
@ -846,7 +849,10 @@ module Cask
|
||||
|
||||
sig { returns(String) }
|
||||
def core_formula_url
|
||||
"#{core_tap.default_remote}/blob/HEAD/Formula/#{cask.token}.rb"
|
||||
formula_path = Formulary.core_path(cask.token)
|
||||
.to_s
|
||||
.delete_prefix(core_tap.path.to_s)
|
||||
"#{core_tap.default_remote}/blob/HEAD/Formula/#{formula_path}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -439,7 +439,7 @@ module Cask
|
||||
end
|
||||
|
||||
def self.default_path(token)
|
||||
CoreCaskTap.instance.cask_dir/"#{token.to_s.downcase}.rb"
|
||||
find_cask_in_tap(token.to_s.downcase, CoreCaskTap.instance)
|
||||
end
|
||||
|
||||
def self.tap_paths(token, warn: true)
|
||||
@ -455,7 +455,8 @@ module Cask
|
||||
def self.find_cask_in_tap(token, tap)
|
||||
filename = "#{token}.rb"
|
||||
|
||||
Tap.cask_files_by_name(tap).fetch(filename, tap.cask_dir/filename)
|
||||
Tap.cask_files_by_name(tap)
|
||||
.fetch(token, tap.cask_dir/filename)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -227,7 +227,8 @@ module Homebrew
|
||||
sig { params(only: T.nilable(Symbol), recurse_tap: T::Boolean).returns(T::Array[Pathname]) }
|
||||
def to_paths(only: parent&.only_formula_or_cask, recurse_tap: false)
|
||||
@to_paths ||= {}
|
||||
@to_paths[only] ||= downcased_unique_named.flat_map do |name|
|
||||
@to_paths[only] ||= Homebrew.with_no_api_env_if_needed(@without_api) do
|
||||
downcased_unique_named.flat_map do |name|
|
||||
path = Pathname(name)
|
||||
if File.exist?(name)
|
||||
path
|
||||
@ -262,6 +263,7 @@ module Homebrew
|
||||
end
|
||||
end.uniq.freeze
|
||||
end
|
||||
end
|
||||
|
||||
sig { returns(T::Array[Keg]) }
|
||||
def to_default_kegs
|
||||
|
||||
@ -29,7 +29,7 @@ module Homebrew
|
||||
conflicts "-1", "--max-count"
|
||||
conflicts "--formula", "--cask"
|
||||
|
||||
named_args [:formula, :cask], max: 1
|
||||
named_args [:formula, :cask], max: 1, without_api: true
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@ -96,7 +96,7 @@ module Homebrew
|
||||
cask_tap = Tap.fetch(args.tap || "homebrew/cask")
|
||||
raise TapUnavailableError, cask_tap.name unless cask_tap.installed?
|
||||
|
||||
cask_path = Cask::CaskLoader.path("#{cask_tap}/#{token}")
|
||||
cask_path = cask_tap.new_cask_path(token)
|
||||
cask_path.dirname.mkpath unless cask_path.dirname.exist?
|
||||
raise Cask::CaskAlreadyCreatedError, token if cask_path.exist?
|
||||
|
||||
|
||||
@ -114,7 +114,7 @@ module Homebrew
|
||||
|
||||
repo = source_tap.path
|
||||
pattern = if source_tap.core_tap?
|
||||
[repo/"Formula/#{name}.rb"]
|
||||
[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"]
|
||||
|
||||
@ -110,7 +110,7 @@ module Homebrew
|
||||
end
|
||||
|
||||
def self.get_package(tap, subject_name, subject_path, content)
|
||||
if subject_path.dirname == tap.cask_dir
|
||||
if subject_path.to_s.start_with?("#{tap.cask_dir}/")
|
||||
cask = begin
|
||||
Cask::CaskLoader.load(content.dup)
|
||||
rescue Cask::CaskUnavailableError
|
||||
@ -130,7 +130,7 @@ module Homebrew
|
||||
subject_path = Pathname(subject_path)
|
||||
tap = Tap.from_path(subject_path)
|
||||
subject_name = subject_path.basename.to_s.chomp(".rb")
|
||||
is_cask = subject_path.dirname == tap.cask_dir
|
||||
is_cask = subject_path.to_s.start_with?("#{tap.cask_dir}/")
|
||||
name = is_cask ? "cask" : "formula"
|
||||
|
||||
new_package = get_package(tap, subject_name, subject_path, new_contents)
|
||||
@ -241,8 +241,8 @@ module Homebrew
|
||||
files.each do |file|
|
||||
files_to_commits[file] ||= []
|
||||
files_to_commits[file] << commit
|
||||
tap_file = tap.path/file
|
||||
if (tap_file.dirname == tap.formula_dir || tap_file.dirname == tap.cask_dir) &&
|
||||
tap_file = (tap.path/file).to_s
|
||||
if (tap_file.start_with?("#{tap.formula_dir}/") || tap_file.start_with?("#{tap.cask_dir}/")) &&
|
||||
File.extname(file) == ".rb"
|
||||
next
|
||||
end
|
||||
|
||||
@ -45,7 +45,7 @@ module Homebrew
|
||||
def update_path
|
||||
return if @name.nil? || @tap.nil?
|
||||
|
||||
@path = Formulary.path "#{@tap}/#{@name}"
|
||||
@path = @tap.new_formula_path(@name)
|
||||
end
|
||||
|
||||
def fetch?
|
||||
|
||||
@ -49,7 +49,7 @@ homebrew-formula-path() {
|
||||
local formula_path
|
||||
formula_path="$(
|
||||
shopt -s nullglob
|
||||
echo "${HOMEBREW_REPOSITORY}/Library/Taps"/*/*/{Formula/,HomebrewFormula/,}"${formula}.rb"
|
||||
echo "${HOMEBREW_REPOSITORY}/Library/Taps"/*/*/{Formula/,HomebrewFormula/,Formula/*/,}"${formula}.rb"
|
||||
)"
|
||||
[[ -n "${formula_path}" ]] && formula_exists="1"
|
||||
fi
|
||||
|
||||
@ -1003,10 +1003,15 @@ module Formulary
|
||||
end.select(&:file?)
|
||||
end
|
||||
|
||||
sig { params(name: String, tap: Tap).returns(Pathname) }
|
||||
def self.find_formula_in_tap(name, tap)
|
||||
filename = name.dup
|
||||
filename << ".rb" unless filename.end_with?(".rb")
|
||||
filename = if name.end_with?(".rb")
|
||||
name
|
||||
else
|
||||
"#{name}.rb"
|
||||
end
|
||||
|
||||
Tap.formula_files_by_name(tap).fetch(filename, tap.formula_dir/filename)
|
||||
Tap.formula_files_by_name(tap)
|
||||
.fetch(name, tap.formula_dir/filename)
|
||||
end
|
||||
end
|
||||
|
||||
@ -31,7 +31,7 @@ module Readall
|
||||
failed = true
|
||||
end
|
||||
|
||||
if (formula_dir/"#{f.basename}.rb").exist?
|
||||
if formula_dir.glob("**/#{f.basename}.rb").any?(&:exist?)
|
||||
onoe "Formula duplicating alias: #{f}"
|
||||
failed = true
|
||||
end
|
||||
|
||||
@ -500,12 +500,22 @@ class Tap
|
||||
@potential_formula_dirs ||= [path/"Formula", path/"HomebrewFormula", path].freeze
|
||||
end
|
||||
|
||||
sig { params(name: String).returns(Pathname) }
|
||||
def new_formula_path(name)
|
||||
formula_dir/"#{name.downcase}.rb"
|
||||
end
|
||||
|
||||
# Path to the directory of all {Cask} files for this {Tap}.
|
||||
sig { returns(Pathname) }
|
||||
def cask_dir
|
||||
@cask_dir ||= path/"Casks"
|
||||
end
|
||||
|
||||
sig { params(token: String).returns(Pathname) }
|
||||
def new_cask_path(token)
|
||||
cask_dir/"#{token.downcase}.rb"
|
||||
end
|
||||
|
||||
def contents
|
||||
contents = []
|
||||
|
||||
@ -555,7 +565,7 @@ class 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
|
||||
hash[file.basename(".rb").to_s] ||= file
|
||||
end
|
||||
end
|
||||
|
||||
@ -584,7 +594,7 @@ class 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
|
||||
hash[file.basename(".rb").to_s] ||= file
|
||||
end
|
||||
end
|
||||
|
||||
@ -984,6 +994,19 @@ class CoreTap < AbstractCoreTap
|
||||
end
|
||||
end
|
||||
|
||||
sig { params(name: String).returns(Pathname) }
|
||||
def new_formula_path(name)
|
||||
formula_subdir = if name.start_with?("lib")
|
||||
"lib"
|
||||
else
|
||||
name[0].to_s
|
||||
end
|
||||
|
||||
return super unless (formula_dir/formula_subdir).directory?
|
||||
|
||||
formula_dir/formula_subdir/"#{name.downcase}.rb"
|
||||
end
|
||||
|
||||
# @private
|
||||
sig { returns(Pathname) }
|
||||
def alias_dir
|
||||
@ -1108,6 +1131,15 @@ class CoreCaskTap < AbstractCoreTap
|
||||
true
|
||||
end
|
||||
|
||||
sig { params(token: String).returns(Pathname) }
|
||||
def new_cask_path(token)
|
||||
cask_subdir = token[0].to_s
|
||||
|
||||
return super unless (cask_dir/cask_subdir).directory?
|
||||
|
||||
cask_dir/cask_subdir/"#{token.downcase}.rb"
|
||||
end
|
||||
|
||||
sig { override.returns(T::Array[Pathname]) }
|
||||
def cask_files
|
||||
return super if Homebrew::EnvConfig.no_install_from_api? || installed?
|
||||
|
||||
@ -333,7 +333,7 @@ describe Homebrew::Cleanup do
|
||||
FileUtils.touch testball
|
||||
FileUtils.touch testball_resource
|
||||
(HOMEBREW_CELLAR/"testball"/"0.0.1").mkpath
|
||||
FileUtils.touch(CoreTap.instance.formula_dir/"testball.rb")
|
||||
FileUtils.touch(CoreTap.instance.new_formula_path("testball"))
|
||||
end
|
||||
|
||||
it "cleans up file if outdated" do
|
||||
|
||||
@ -4,7 +4,7 @@ require "cmd/shared_examples/args_parse"
|
||||
|
||||
describe "brew create" do
|
||||
let(:url) { "file://#{TEST_FIXTURE_DIR}/tarballs/testball-0.1.tbz" }
|
||||
let(:formula_file) { CoreTap.new.formula_dir/"testball.rb" }
|
||||
let(:formula_file) { CoreTap.new.new_formula_path("testball") }
|
||||
|
||||
it_behaves_like "parseable arguments"
|
||||
|
||||
|
||||
@ -82,7 +82,7 @@ describe FormulaInstaller do
|
||||
ENV["HOMEBREW_DEVELOPER"] = "1"
|
||||
|
||||
dep_name = "homebrew-test-cyclic"
|
||||
dep_path = CoreTap.new.formula_dir/"#{dep_name}.rb"
|
||||
dep_path = CoreTap.new.new_formula_path(dep_name)
|
||||
dep_path.write <<~RUBY
|
||||
class #{Formulary.class_s(dep_name)} < Formula
|
||||
url "foo"
|
||||
@ -105,7 +105,7 @@ describe FormulaInstaller do
|
||||
|
||||
formula1_name = "homebrew-test-formula1"
|
||||
formula2_name = "homebrew-test-formula2"
|
||||
formula1_path = CoreTap.new.formula_dir/"#{formula1_name}.rb"
|
||||
formula1_path = CoreTap.new.new_formula_path(formula1_name)
|
||||
formula1_path.write <<~RUBY
|
||||
class #{Formulary.class_s(formula1_name)} < Formula
|
||||
url "foo"
|
||||
@ -116,7 +116,7 @@ describe FormulaInstaller do
|
||||
Formulary.cache.delete(formula1_path)
|
||||
formula1 = Formulary.factory(formula1_name)
|
||||
|
||||
formula2_path = CoreTap.new.formula_dir/"#{formula2_name}.rb"
|
||||
formula2_path = CoreTap.new.new_formula_path(formula2_name)
|
||||
formula2_path.write <<~RUBY
|
||||
class #{Formulary.class_s(formula2_name)} < Formula
|
||||
url "foo"
|
||||
@ -135,7 +135,7 @@ describe FormulaInstaller do
|
||||
|
||||
it "raises on pinned dependency" do
|
||||
dep_name = "homebrew-test-dependency"
|
||||
dep_path = CoreTap.new.formula_dir/"#{dep_name}.rb"
|
||||
dep_path = CoreTap.new.new_formula_path(dep_name)
|
||||
dep_path.write <<~RUBY
|
||||
class #{Formulary.class_s(dep_name)} < Formula
|
||||
url "foo"
|
||||
|
||||
@ -429,7 +429,7 @@ describe Formula do
|
||||
|
||||
example "alias paths with tab with non alias source path" do
|
||||
alias_path = (CoreTap.instance.alias_dir/"another_name")
|
||||
source_path = (CoreTap.instance.formula_dir/"another_other_name")
|
||||
source_path = CoreTap.instance.new_formula_path("another_other_name")
|
||||
|
||||
f = formula alias_path: alias_path do
|
||||
url "foo-1.0"
|
||||
@ -940,7 +940,7 @@ describe Formula do
|
||||
end
|
||||
|
||||
describe "#to_hash_with_variations", :needs_macos do
|
||||
let(:formula_path) { CoreTap.new.formula_dir/"foo-variations.rb" }
|
||||
let(:formula_path) { CoreTap.new.new_formula_path("foo-variations") }
|
||||
let(:formula_content) do
|
||||
<<~RUBY
|
||||
class FooVariations < Formula
|
||||
|
||||
@ -6,7 +6,7 @@ require "utils/bottles"
|
||||
|
||||
describe Formulary do
|
||||
let(:formula_name) { "testball_bottle" }
|
||||
let(:formula_path) { CoreTap.new.formula_dir/"#{formula_name}.rb" }
|
||||
let(:formula_path) { CoreTap.new.new_formula_path(formula_name) }
|
||||
let(:formula_content) do
|
||||
<<~RUBY
|
||||
class #{described_class.class_s(formula_name)} < Formula
|
||||
@ -84,7 +84,11 @@ describe Formulary do
|
||||
before { CoreTap.instance.clear_cache }
|
||||
|
||||
let(:formula_name) { "testball_sharded" }
|
||||
let(:formula_path) { CoreTap.new.formula_dir/formula_name[0]/"#{formula_name}.rb" }
|
||||
let(:formula_path) do
|
||||
core_tap = CoreTap.new
|
||||
(core_tap.formula_dir/formula_name[0]).mkpath
|
||||
core_tap.new_formula_path(formula_name)
|
||||
end
|
||||
|
||||
it "returns a Formula" do
|
||||
expect(described_class.factory(formula_name)).to be_a(Formula)
|
||||
|
||||
@ -4,9 +4,9 @@ shared_examples "formulae exist" do |array|
|
||||
array.each do |f|
|
||||
it "#{f} formula exists" do
|
||||
core_tap = Pathname("#{HOMEBREW_LIBRARY_PATH}/../Taps/homebrew/homebrew-core")
|
||||
formula_path = core_tap/"Formula/#{f}.rb"
|
||||
formula_paths = core_tap.glob("Formula/**/#{f}.rb")
|
||||
alias_path = core_tap/"Aliases/#{f}"
|
||||
expect(formula_path.exist? || alias_path.exist?).to be true
|
||||
expect(formula_paths.any?(&:exist?) || alias_path.exist?).to be true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user