diff --git a/Library/Homebrew/cask/cask_loader.rb b/Library/Homebrew/cask/cask_loader.rb index faa8b63edc..f088dcf339 100644 --- a/Library/Homebrew/cask/cask_loader.rb +++ b/Library/Homebrew/cask/cask_loader.rb @@ -125,7 +125,9 @@ module Cask @content = path.read(encoding: "UTF-8") @config = config - return FromAPILoader.new(token, from_json: JSON.parse(@content)).load(config:) if path.extname == ".json" + if path.extname == ".json" + return FromAPILoader.new(token, from_json: JSON.parse(@content), path:).load(config:) + end begin instance_eval(content, path).tap do |cask| @@ -278,10 +280,11 @@ module Cask new("#{tap}/#{token}") end - sig { params(token: String, from_json: Hash).void } - def initialize(token, from_json: T.unsafe(nil)) + sig { params(token: String, from_json: Hash, path: T.nilable(Pathname)).void } + def initialize(token, from_json: T.unsafe(nil), path: nil) @token = token.sub(%r{^homebrew/(?:homebrew-)?cask/}i, "") - @path = CaskLoader.default_path(@token) + @sourcefile_path = path + @path = path || CaskLoader.default_path(@token) @from_json = from_json end @@ -290,6 +293,7 @@ module Cask cask_options = { loaded_from_api: true, + sourcefile_path: @sourcefile_path, source: JSON.pretty_generate(json_cask), config:, loader: self, diff --git a/Library/Homebrew/cli/named_args.rb b/Library/Homebrew/cli/named_args.rb index 834e073aa3..c92693a87e 100644 --- a/Library/Homebrew/cli/named_args.rb +++ b/Library/Homebrew/cli/named_args.rb @@ -103,6 +103,28 @@ module Homebrew .map(&:freeze).freeze end + # Returns formulae and casks after validating that a tap is present for each of them. + def to_formulae_and_casks_with_taps + formulae_and_casks_with_taps, formulae_and_casks_without_taps = + to_formulae_and_casks.partition do |formula_or_cask| + T.cast(formula_or_cask, T.any(Formula, Cask::Cask)).tap&.installed? + end + + return formulae_and_casks_with_taps if formulae_and_casks_without_taps.blank? + + types = [] + types << "formulae" if formulae_and_casks_without_taps.any?(Formula) + types << "casks" if formulae_and_casks_without_taps.any?(Cask::Cask) + + odie <<~ERROR + These #{types.join(" and ")} are not in any locally installed taps! + + #{formulae_and_casks_without_taps.sort_by(&:to_s).join("\n ")} + + You may need to run `brew tap` to install additional taps. + ERROR + end + def to_formulae_and_casks_and_unavailable(only: parent&.only_formula_or_cask, method: nil) @to_formulae_casks_unknowns ||= {} @to_formulae_casks_unknowns[method] = downcased_unique_named.map do |name| diff --git a/Library/Homebrew/dev-cmd/audit.rb b/Library/Homebrew/dev-cmd/audit.rb index 4932d492d2..63e5fdee88 100644 --- a/Library/Homebrew/dev-cmd/audit.rb +++ b/Library/Homebrew/dev-cmd/audit.rb @@ -153,7 +153,7 @@ module Homebrew "brew audit [name ...]" end - args.named.to_formulae_and_casks + args.named.to_formulae_and_casks_with_taps .partition { |formula_or_cask| formula_or_cask.is_a?(Formula) } end end diff --git a/Library/Homebrew/dev-cmd/bump.rb b/Library/Homebrew/dev-cmd/bump.rb index 538d69ed3a..879ffdce5f 100644 --- a/Library/Homebrew/dev-cmd/bump.rb +++ b/Library/Homebrew/dev-cmd/bump.rb @@ -74,13 +74,7 @@ module Homebrew casks = args.formula? ? [] : Cask::Caskroom.casks formulae + casks elsif args.named.present? - if args.formula? - args.named.to_formulae - elsif args.cask? - args.named.to_casks - else - args.named.to_formulae_and_casks - end + args.named.to_formulae_and_casks_with_taps end formulae_and_casks = formulae_and_casks&.sort_by do |formula_or_cask| diff --git a/Library/Homebrew/dev-cmd/livecheck.rb b/Library/Homebrew/dev-cmd/livecheck.rb index a97c856f70..017f1a9d29 100644 --- a/Library/Homebrew/dev-cmd/livecheck.rb +++ b/Library/Homebrew/dev-cmd/livecheck.rb @@ -73,13 +73,7 @@ module Homebrew casks = args.formula? ? [] : Cask::Cask.all(eval_all: args.eval_all?) formulae + casks elsif args.named.present? - if args.formula? - args.named.to_formulae - elsif args.cask? - args.named.to_casks - else - args.named.to_formulae_and_casks - end + args.named.to_formulae_and_casks_with_taps elsif File.exist?(watchlist_path) begin names = Pathname.new(watchlist_path).read.lines diff --git a/Library/Homebrew/test/cask/cask_loader/from_path_loader_spec.rb b/Library/Homebrew/test/cask/cask_loader/from_path_loader_spec.rb index fccd5b580b..0322a42ba3 100644 --- a/Library/Homebrew/test/cask/cask_loader/from_path_loader_spec.rb +++ b/Library/Homebrew/test/cask/cask_loader/from_path_loader_spec.rb @@ -42,5 +42,14 @@ RSpec.describe Cask::CaskLoader::FromPathLoader do /invalid 'depends_on macos' value: unknown or unsupported macOS version:/) end end + + context "with a JSON cask file" do + let(:sourcefile_path) { TEST_FIXTURE_DIR/"cask/everything.json" } + + it "loads a cask with a source file path" do + cask = described_class.new(sourcefile_path).load(config: nil) + expect(cask.sourcefile_path).to eq sourcefile_path + end + end end end