Deprecate installing casks/formulae from paths.

We've already disabled installing casks/formulae from URLs and we
regularly tell people not to install from paths so let's just deprecate
this behaviour entirely.

Even Homebrew developers do not need to work this way.
This commit is contained in:
Mike McQuaid 2024-09-25 10:05:12 +01:00
parent aed28da008
commit bbdea29a0f
No known key found for this signature in database
6 changed files with 45 additions and 30 deletions

View File

@ -211,8 +211,13 @@ rescue Exception => e # rubocop:disable Lint/RescueException
$stderr.puts "If reporting this issue please do so at (not Homebrew/brew or Homebrew/homebrew-core):" $stderr.puts "If reporting this issue please do so at (not Homebrew/brew or Homebrew/homebrew-core):"
$stderr.puts " #{Formatter.url(issues_url)}" $stderr.puts " #{Formatter.url(issues_url)}"
elsif internal_cmd elsif internal_cmd
$stderr.puts "#{Tty.bold}Please report this issue:#{Tty.reset}" if e.is_a?(MethodDeprecatedError) && (first_backtrace = e.backtrace&.first.presence) &&
$stderr.puts " #{Formatter.url(OS::ISSUES_URL)}" (first_backtrace.include?("/formulary.rb") || first_backtrace.include?("/cask_loader.rb"))
$stderr.puts Utils::Backtrace.clean(e) if ARGV.include?("--debug") || args.debug?
else
$stderr.puts "#{Tty.bold}Please report this issue:#{Tty.reset}"
$stderr.puts " #{Formatter.url(OS::ISSUES_URL)}"
end
end end
exit 1 exit 1

View File

@ -105,10 +105,19 @@ module Cask
end end
return if %w[.rb .json].exclude?(path.extname) return if %w[.rb .json].exclude?(path.extname)
return if path.to_s.include?("/Formula/")
return unless path.expand_path.exist? return unless path.expand_path.exist?
return if Homebrew::EnvConfig.forbid_packages_from_paths? && unless path.realpath.to_s.start_with?("#{Caskroom.path}/", "#{HOMEBREW_LIBRARY}/Taps/",
!path.realpath.to_s.start_with?("#{Caskroom.path}/", "#{HOMEBREW_LIBRARY}/Taps/") "#{HOMEBREW_LIBRARY_PATH}/test/support/fixtures/")
return if Homebrew::EnvConfig.forbid_packages_from_paths?
# So many tests legimately use casks from paths that we can't warn about them all.
# Let's focus on end-users for now.
unless ENV["HOMEBREW_TESTS"]
odeprecated "installing formulae from paths or URLs", "installing formulae from taps"
end
end
new(path) new(path)
end end
@ -195,6 +204,8 @@ module Cask
def load(config:) def load(config:)
path.dirname.mkpath path.dirname.mkpath
odeprecated "installing casks from paths or URLs", "installing casks from taps"
if ALLOWED_URL_SCHEMES.exclude?(url.scheme) if ALLOWED_URL_SCHEMES.exclude?(url.scheme)
raise UnsupportedInstallationMethod, raise UnsupportedInstallationMethod,
"Non-checksummed download of #{name} formula file from an arbitrary URL is unsupported! " \ "Non-checksummed download of #{name} formula file from an arbitrary URL is unsupported! " \

View File

@ -646,9 +646,6 @@ module Formulary
return unless path.expand_path.exist? return unless path.expand_path.exist?
return if Homebrew::EnvConfig.forbid_packages_from_paths? &&
!path.realpath.to_s.start_with?("#{HOMEBREW_CELLAR}/", "#{HOMEBREW_LIBRARY}/Taps/")
options = if (tap = Tap.from_path(path)) options = if (tap = Tap.from_path(path))
# Only treat symlinks in taps as aliases. # Only treat symlinks in taps as aliases.
if path.symlink? if path.symlink?
@ -675,6 +672,17 @@ module Formulary
return if path.extname != ".rb" return if path.extname != ".rb"
unless path.realpath.to_s.start_with?("#{HOMEBREW_CELLAR}/", "#{HOMEBREW_TAP_DIRECTORY}/",
"#{HOMEBREW_LIBRARY_PATH}/test/support/fixtures/")
return if Homebrew::EnvConfig.forbid_packages_from_paths?
# So many tests legimately use formulae from paths that we can't warn about them all.
# Let's focus on end-users for now.
unless ENV["HOMEBREW_TESTS"]
odeprecated "installing formulae from paths or URLs", "installing formulae from taps"
end
end
new(path, **options) new(path, **options)
end end
@ -716,6 +724,8 @@ module Formulary
return unless uri.path return unless uri.path
return unless uri.scheme.present? return unless uri.scheme.present?
odeprecated "installing formulae from paths or URLs", "installing formulae from taps"
new(uri, from:) new(uri, from:)
end end

View File

@ -29,28 +29,28 @@ RSpec.describe Cask::CaskLoader::FromURILoader do
loader = described_class.new("https://brew.sh/foo.rb") loader = described_class.new("https://brew.sh/foo.rb")
expect do expect do
loader.load(config: nil) loader.load(config: nil)
end.to raise_error(UnsupportedInstallationMethod) end.to raise_error(MethodDeprecatedError)
end end
it "raises an error when given an ftp URL" do it "raises an error when given an ftp URL" do
loader = described_class.new("ftp://brew.sh/foo.rb") loader = described_class.new("ftp://brew.sh/foo.rb")
expect do expect do
loader.load(config: nil) loader.load(config: nil)
end.to raise_error(UnsupportedInstallationMethod) end.to raise_error(MethodDeprecatedError)
end end
it "raises an error when given an sftp URL" do it "raises an error when given an sftp URL" do
loader = described_class.new("sftp://brew.sh/foo.rb") loader = described_class.new("sftp://brew.sh/foo.rb")
expect do expect do
loader.load(config: nil) loader.load(config: nil)
end.to raise_error(UnsupportedInstallationMethod) end.to raise_error(MethodDeprecatedError)
end end
it "does not raise an error when given a file URL" do it "raises an error when given a file URL" do
loader = described_class.new("file://#{TEST_FIXTURE_DIR}/cask/Casks/local-caffeine.rb") loader = described_class.new("file://#{TEST_FIXTURE_DIR}/cask/Casks/local-caffeine.rb")
expect do expect do
loader.load(config: nil) loader.load(config: nil)
end.not_to raise_error(UnsupportedInstallationMethod) end.to raise_error(MethodDeprecatedError)
end end
end end
end end

View File

@ -46,16 +46,10 @@ RSpec.describe Cask::Cask, :cask do
expect(c.token).to eq("caffeine") expect(c.token).to eq("caffeine")
end end
it "returns an instance of the Cask from a URL", :needs_utils_curl, :no_api do
c = Cask::CaskLoader.load("file://#{tap_path}/Casks/local-caffeine.rb")
expect(c).to be_a(described_class)
expect(c.token).to eq("local-caffeine")
end
it "raises an error when failing to download a Cask from a URL", :needs_utils_curl, :no_api do it "raises an error when failing to download a Cask from a URL", :needs_utils_curl, :no_api do
expect do expect do
Cask::CaskLoader.load("file://#{tap_path}/Casks/notacask.rb") Cask::CaskLoader.load("file://#{tap_path}/Casks/notacask.rb")
end.to raise_error(Cask::CaskUnavailableError) end.to raise_error(MethodDeprecatedError)
end end
it "returns an instance of the Cask from a relative file location" do it "returns an instance of the Cask from a relative file location" do

View File

@ -129,11 +129,6 @@ RSpec.describe Formulary do
end.to raise_error(FormulaUnavailableError) end.to raise_error(FormulaUnavailableError)
end end
it "returns a Formula when given a URL", :needs_utils_curl, :no_api do
formula = described_class.factory("file://#{formula_path}")
expect(formula).to be_a(Formula)
end
it "errors when given a URL but paths are disabled" do it "errors when given a URL but paths are disabled" do
ENV["HOMEBREW_FORBID_PACKAGES_FROM_PATHS"] = "1" ENV["HOMEBREW_FORBID_PACKAGES_FROM_PATHS"] = "1"
expect do expect do
@ -546,31 +541,31 @@ RSpec.describe Formulary do
it "raises an error when given an https URL" do it "raises an error when given an https URL" do
expect do expect do
described_class.factory("https://brew.sh/foo.rb") described_class.factory("https://brew.sh/foo.rb")
end.to raise_error(UnsupportedInstallationMethod) end.to raise_error(MethodDeprecatedError)
end end
it "raises an error when given a bottle URL" do it "raises an error when given a bottle URL" do
expect do expect do
described_class.factory("https://brew.sh/foo-1.0.arm64_catalina.bottle.tar.gz") described_class.factory("https://brew.sh/foo-1.0.arm64_catalina.bottle.tar.gz")
end.to raise_error(UnsupportedInstallationMethod) end.to raise_error(MethodDeprecatedError)
end end
it "raises an error when given an ftp URL" do it "raises an error when given an ftp URL" do
expect do expect do
described_class.factory("ftp://brew.sh/foo.rb") described_class.factory("ftp://brew.sh/foo.rb")
end.to raise_error(UnsupportedInstallationMethod) end.to raise_error(MethodDeprecatedError)
end end
it "raises an error when given an sftp URL" do it "raises an error when given an sftp URL" do
expect do expect do
described_class.factory("sftp://brew.sh/foo.rb") described_class.factory("sftp://brew.sh/foo.rb")
end.to raise_error(UnsupportedInstallationMethod) end.to raise_error(MethodDeprecatedError)
end end
it "does not raise an error when given a file URL" do it "raises an error when given a file URL" do
expect do expect do
described_class.factory("file://#{TEST_FIXTURE_DIR}/testball.rb") described_class.factory("file://#{TEST_FIXTURE_DIR}/testball.rb")
end.not_to raise_error(UnsupportedInstallationMethod) end.to raise_error(MethodDeprecatedError)
end end
end end