diff --git a/Library/Homebrew/cli/args.rb b/Library/Homebrew/cli/args.rb index 49a9940541..3f2dc9de8c 100644 --- a/Library/Homebrew/cli/args.rb +++ b/Library/Homebrew/cli/args.rb @@ -152,3 +152,5 @@ module Homebrew end end end + +require "extend/os/args" diff --git a/Library/Homebrew/cli/parser.rb b/Library/Homebrew/cli/parser.rb index 4fc804ad65..a507451f25 100644 --- a/Library/Homebrew/cli/parser.rb +++ b/Library/Homebrew/cli/parser.rb @@ -341,14 +341,20 @@ module Homebrew @args_parsed = true - if !ignore_invalid_options && @args.help? - puts generate_help_text - exit + unless ignore_invalid_options + if @args.help? + puts generate_help_text + exit + end + + validate_options end @args end + def validate_options; end + def generate_help_text Formatter.format_help_text(@parser.to_s, width: COMMAND_DESC_WIDTH) .gsub(/\n.*?@@HIDDEN@@.*?(?=\n)/, "") @@ -701,3 +707,5 @@ module Homebrew end end end + +require "extend/os/parser" diff --git a/Library/Homebrew/extend/os/args.rb b/Library/Homebrew/extend/os/args.rb new file mode 100644 index 0000000000..e497060e41 --- /dev/null +++ b/Library/Homebrew/extend/os/args.rb @@ -0,0 +1,4 @@ +# typed: false +# frozen_string_literal: true + +require "extend/os/linux/args" if OS.linux? diff --git a/Library/Homebrew/extend/os/linux/args.rb b/Library/Homebrew/extend/os/linux/args.rb new file mode 100644 index 0000000000..1d4b221909 --- /dev/null +++ b/Library/Homebrew/extend/os/linux/args.rb @@ -0,0 +1,17 @@ +# typed: false +# frozen_string_literal: true + +module Homebrew + module CLI + class Args + undef only_formula_or_cask + + def only_formula_or_cask + # Make formula the default on linux for non-developers + return :formula unless Homebrew::EnvConfig.developer? + return :formula if formula? && !cask? + return :cask if cask? && !formula? + end + end + end +end diff --git a/Library/Homebrew/extend/os/linux/parser.rb b/Library/Homebrew/extend/os/linux/parser.rb new file mode 100644 index 0000000000..939585859d --- /dev/null +++ b/Library/Homebrew/extend/os/linux/parser.rb @@ -0,0 +1,20 @@ +# typed: false +# frozen_string_literal: true + +module Homebrew + module CLI + class Parser + undef validate_options + + def validate_options + return unless @args.respond_to?(:cask?) + return unless @args.cask? + + msg = "Casks are not supported on Linux" + raise UsageError, msg unless Homebrew::EnvConfig.developer? + + opoo msg unless @args.quiet? + end + end + end +end diff --git a/Library/Homebrew/extend/os/parser.rb b/Library/Homebrew/extend/os/parser.rb new file mode 100644 index 0000000000..90b0d42da7 --- /dev/null +++ b/Library/Homebrew/extend/os/parser.rb @@ -0,0 +1,4 @@ +# typed: false +# frozen_string_literal: true + +require "extend/os/linux/parser" if OS.linux? diff --git a/Library/Homebrew/test/cli/named_args_spec.rb b/Library/Homebrew/test/cli/named_args_spec.rb index 06e85a7344..6b2e8d2418 100644 --- a/Library/Homebrew/test/cli/named_args_spec.rb +++ b/Library/Homebrew/test/cli/named_args_spec.rb @@ -67,7 +67,7 @@ describe Homebrew::CLI::NamedArgs do end describe "#to_formulae_and_casks" do - it "returns formulae and casks" do + it "returns formulae and casks", :dev_on_linux do stub_formula_loader foo, call_original: true stub_cask_loader baz, call_original: true @@ -118,7 +118,13 @@ describe Homebrew::CLI::NamedArgs do expect { described_class.new("foo").to_formulae_and_casks }.to raise_error(FormulaOrCaskUnavailableError) end - it "returns formula when formula is present and cask is unreadable" do + it "raises an error when formula is absent and cask is available on linux", :needs_linux do + stub_cask_loader foo_cask + + expect { described_class.new("foo").to_formulae_and_casks }.to raise_error(FormulaUnavailableError) + end + + it "returns formula when formula is present and cask is unreadable", :dev_on_linux do stub_formula_loader foo setup_unredable_cask "foo" @@ -126,7 +132,7 @@ describe Homebrew::CLI::NamedArgs do expect { described_class.new("foo").to_formulae_and_casks }.to output(/Failed to load cask: foo/).to_stderr end - it "returns cask when formula is unreadable and cask is present" do + it "returns cask when formula is unreadable and cask is present", :dev_on_linux do setup_unredable_formula "foo" stub_cask_loader foo_cask @@ -134,7 +140,7 @@ describe Homebrew::CLI::NamedArgs do expect { described_class.new("foo").to_formulae_and_casks }.to output(/Failed to load formula: foo/).to_stderr end - it "raises an error when formula is absent and cask is unreadable" do + it "raises an error when formula is absent and cask is unreadable", :dev_on_linux do setup_unredable_cask "foo" expect { described_class.new("foo").to_formulae_and_casks }.to raise_error(Cask::CaskUnreadableError) @@ -156,7 +162,7 @@ describe Homebrew::CLI::NamedArgs do end describe "#to_resolved_formulae_to_casks" do - it "returns resolved formulae, as well as casks" do + it "returns resolved formulae, as well as casks", :dev_on_linux do allow(Formulary).to receive(:resolve).and_call_original allow(Formulary).to receive(:resolve).with("foo", any_args).and_return foo stub_cask_loader baz, call_original: true @@ -245,7 +251,7 @@ describe Homebrew::CLI::NamedArgs do (HOMEBREW_CELLAR/"foo/1.0").mkpath end - it "returns kegs, as well as casks" do + it "returns kegs, as well as casks", :dev_on_linux do stub_cask_loader baz, call_original: true kegs, casks = described_class.new("foo", "baz").to_kegs_to_casks @@ -279,7 +285,7 @@ describe Homebrew::CLI::NamedArgs do allow(Cask::CaskLoader).to receive(:path).and_call_original end - it "returns taps, cask formula and existing paths" do + it "returns taps, cask formula and existing paths", :dev_on_linux do expect(Formulary).to receive(:path).with("foo").and_return(formula_path) expect(Cask::CaskLoader).to receive(:path).with("baz").and_return(cask_path) @@ -287,7 +293,7 @@ describe Homebrew::CLI::NamedArgs do .to eq [Tap.fetch("homebrew/core").path, formula_path, cask_path, existing_path] end - it "returns both cask and formula paths if they exist" do + it "returns both cask and formula paths if they exist", :dev_on_linux do expect(Formulary).to receive(:path).with("foo").and_return(formula_path) expect(Cask::CaskLoader).to receive(:path).with("baz").and_return(cask_path) @@ -305,6 +311,12 @@ describe Homebrew::CLI::NamedArgs do expect(described_class.new("foo", "baz").to_paths(only: :cask)).to eq [cask_path, Cask::CaskLoader.path("baz")] end + + it "returns only formulae by default on linux", :needs_linux do + expect(Formulary).to receive(:path).with("foo").and_return(formula_path) + + expect(described_class.new("foo", "baz").to_paths).to eq [formula_path, Formulary.path("baz")] + end end describe "#to_taps" do diff --git a/Library/Homebrew/test/cli/parser_spec.rb b/Library/Homebrew/test/cli/parser_spec.rb index 5aaab4683a..408295d91c 100644 --- a/Library/Homebrew/test/cli/parser_spec.rb +++ b/Library/Homebrew/test/cli/parser_spec.rb @@ -562,4 +562,20 @@ describe Homebrew::CLI::Parser do expect { parser.parse(["--not-a-command"]) }.to raise_error(OptionParser::InvalidOption, /--not-a-command/) end end + + describe "--cask on linux", :needs_linux do + subject(:parser) do + described_class.new do + switch "--cask" + end + end + + it "throws an error by default" do + expect { parser.parse(["--cask"]) }.to raise_error UsageError, /Casks are not supported on Linux/ + end + + it "only warns developers", :dev_on_linux do + expect { parser.parse(["--cask"]) }.not_to raise_error + end + end end diff --git a/Library/Homebrew/test/cmd/--cache_spec.rb b/Library/Homebrew/test/cmd/--cache_spec.rb index 410ca72f18..ca221f626a 100644 --- a/Library/Homebrew/test/cmd/--cache_spec.rb +++ b/Library/Homebrew/test/cmd/--cache_spec.rb @@ -9,7 +9,6 @@ describe "brew --cache" do it "prints all cache files for a given Formula", :integration_test do expect { brew "--cache", testball } .to output(%r{#{HOMEBREW_CACHE}/downloads/[\da-f]{64}--testball-}o).to_stdout - .and output(/Treating #{Regexp.escape(testball)} as a formula/).to_stderr .and be_a_success expect { brew "--cache", "--formula", testball } .to output(%r{#{HOMEBREW_CACHE}/downloads/[\da-f]{64}--testball-}o).to_stdout @@ -17,7 +16,7 @@ describe "brew --cache" do .and be_a_success end - it "prints the cache files for a given Cask", :integration_test do + it "prints the cache files for a given Cask", :integration_test, :needs_macos do expect { brew "--cache", cask_path("local-caffeine") } .to output(%r{#{HOMEBREW_CACHE}/downloads/[\da-f]{64}--caffeine\.zip}o).to_stdout .and output(/Treating #{Regexp.escape(cask_path("local-caffeine"))} as a cask/).to_stderr @@ -28,7 +27,7 @@ describe "brew --cache" do .and be_a_success end - it "prints the cache files for a given Formula and Cask", :integration_test do + it "prints the cache files for a given Formula and Cask", :integration_test, :needs_macos do expect { brew "--cache", testball, cask_path("local-caffeine") } .to output( %r{ diff --git a/Library/Homebrew/test/cmd/home_spec.rb b/Library/Homebrew/test/cmd/home_spec.rb index 063846c334..3845ac3859 100644 --- a/Library/Homebrew/test/cmd/home_spec.rb +++ b/Library/Homebrew/test/cmd/home_spec.rb @@ -34,7 +34,7 @@ describe "brew home" do .and be_a_success end - it "opens the homepage for a given Cask", :integration_test do + it "opens the homepage for a given Cask", :integration_test, :needs_macos do expect { brew "home", local_caffeine_path, "HOMEBREW_BROWSER" => "echo" } .to output(/#{local_caffeine_homepage}/).to_stdout .and output(/Treating #{Regexp.escape(local_caffeine_path)} as a cask/).to_stderr @@ -45,7 +45,7 @@ describe "brew home" do .and be_a_success end - it "opens the homepages for a given formula and Cask", :integration_test do + it "opens the homepages for a given formula and Cask", :integration_test, :needs_macos do setup_test_formula "testballhome" expect { brew "home", "testballhome", local_caffeine_path, "HOMEBREW_BROWSER" => "echo" } diff --git a/Library/Homebrew/test/spec_helper.rb b/Library/Homebrew/test/spec_helper.rb index 2aef66d976..769f737ce6 100644 --- a/Library/Homebrew/test/spec_helper.rb +++ b/Library/Homebrew/test/spec_helper.rb @@ -180,6 +180,10 @@ RSpec.configure do |config| skip "Unzip is not installed." unless which("unzip") end + config.before(:each, :dev_on_linux) do + allow(Homebrew::EnvConfig).to receive(:developer?).and_return(true) if OS.linux? + end + config.around do |example| def find_files return [] unless File.exist?(TEST_TMPDIR)