Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

argv: move formulae to cli/args #6433

Merged
merged 3 commits into from Dec 11, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
75 changes: 66 additions & 9 deletions Library/Homebrew/cli/args.rb
Expand Up @@ -5,16 +5,23 @@
module Homebrew
module CLI
class Args < OpenStruct
attr_accessor :processed_options
attr_reader :processed_options, :args_parsed
# undefine tap to allow --tap argument
undef tap

def initialize(argv:)
super
@argv = argv
@args_parsed = false
@processed_options = []
end

def freeze_processed_options!(processed_options)
@processed_options += processed_options
@processed_options.freeze
@args_parsed = true
end

def option_to_name(option)
option.sub(/\A--?/, "")
.tr("-", "_")
Expand Down Expand Up @@ -51,22 +58,36 @@ def passthrough
options_only - CLI::Parser.global_options.values.map(&:first).flatten
end

def downcased_unique_named
# Only lowercase names, not paths, bottle filenames or URLs
@downcased_unique_named ||= remaining.map do |arg|
if arg.include?("/") || arg.end_with?(".tar.gz") || File.exist?(arg)
arg
def named
remaining
end

def formulae
require "formula"
@formulae ||= (downcased_unique_named - casks).map do |name|
if name.include?("/") || File.exist?(name)
Formulary.factory(name, spec)
else
arg.downcase
Formulary.find_with_priority(name, spec)
end
end.uniq
end.uniq(&:name)
end

def resolved_formulae
require "formula"
@resolved_formulae ||= (downcased_unique_named - casks).map do |name|
Formulary.resolve(name, spec: spec(nil))
end.uniq(&:name)
end

def casks
@casks ||= downcased_unique_named.grep HOMEBREW_CASK_TAP_CASK_REGEX
end

def kegs
require "keg"
require "formula"
require "missing_formula"

@kegs ||= downcased_unique_named.map do |name|
raise UsageError if name.empty?

Expand Down Expand Up @@ -113,6 +134,42 @@ def kegs
end
end
end

private

def downcased_unique_named
# Only lowercase names, not paths, bottle filenames or URLs
arguments = if args_parsed
remaining
else
cmdline_args.reject { |arg| arg.start_with?("-") }
end
arguments.map do |arg|
if arg.include?("/") || arg.end_with?(".tar.gz") || File.exist?(arg)
arg
else
arg.downcase
end
end.uniq
end

def head
(args_parsed && HEAD?) || cmdline_args.include?("--HEAD")
end

def devel
(args_parsed && devel?) || cmdline_args.include?("--devel")
end

def spec(default = :stable)
if head
:head
elsif devel
:devel
else
default
end
end
end
end
end
12 changes: 7 additions & 5 deletions Library/Homebrew/cli/parser.rb
Expand Up @@ -13,7 +13,7 @@ class Parser
attr_reader :processed_options, :hide_from_man_page

def self.parse(args = ARGV, &block)
new(&block).parse(args)
new(args, &block).parse(args)
end

def self.global_options
Expand All @@ -25,9 +25,11 @@ def self.global_options
}
end

def initialize(&block)
def initialize(args = ARGV, &block)
@parser = OptionParser.new
@args = Homebrew::CLI::Args.new(argv: ARGV_WITHOUT_MONKEY_PATCHING)
@args[:remaining] = []
@args[:cmdline_args] = args.dup
@constraints = []
@conflicts = []
@switch_sources = {}
Expand Down Expand Up @@ -138,10 +140,10 @@ def parse(cmdline_args = ARGV)
end
check_constraint_violations
@args[:remaining] = remaining_args
@args_parsed = true
@args.processed_options = @processed_options
@args.freeze_processed_options!(@processed_options)
Homebrew.args = @args
cmdline_args.freeze
@args_parsed = true
@parser
end

Expand All @@ -159,7 +161,7 @@ def generate_help_text
end

def formula_options
ARGV.formulae.each do |f|
@args.formulae.each do |f|
next if f.options.empty?

f.options.each do |o|
Expand Down
2 changes: 1 addition & 1 deletion Library/Homebrew/cmd/--cache.rb
Expand Up @@ -29,7 +29,7 @@ def __cache
if ARGV.named.empty?
puts HOMEBREW_CACHE
else
ARGV.formulae.each do |f|
Homebrew.args.formulae.each do |f|
if Fetch.fetch_bottle?(f)
puts f.bottle.cached_download
else
Expand Down
2 changes: 1 addition & 1 deletion Library/Homebrew/cmd/--env.rb
Expand Up @@ -30,7 +30,7 @@ def __env
__env_args.parse

ENV.activate_extensions!
ENV.deps = ARGV.formulae if superenv?
ENV.deps = Homebrew.args.formulae if superenv?
ENV.setup_build_environment
ENV.universal_binary if ARGV.build_universal?

Expand Down
2 changes: 1 addition & 1 deletion Library/Homebrew/cmd/cat.rb
Expand Up @@ -20,7 +20,7 @@ def cat
# do not "fix" this to support multiple arguments, the output would be
# unparsable, if the user wants to cat multiple formula they can call
# brew cat multiple times.
formulae = ARGV.formulae
formulae = Homebrew.args.formulae
raise FormulaUnspecifiedError if formulae.empty?
raise "`brew cat` doesn't support multiple arguments" if args.remaining.size > 1

Expand Down
12 changes: 6 additions & 6 deletions Library/Homebrew/cmd/deps.rb
Expand Up @@ -67,16 +67,16 @@ def deps
if args.installed?
puts_deps_tree Formula.installed.sort, recursive
else
raise FormulaUnspecifiedError if args.remaining.empty?
raise FormulaUnspecifiedError if Homebrew.args.remaining.empty?

puts_deps_tree ARGV.formulae, recursive
puts_deps_tree Homebrew.args.formulae, recursive
end
return
elsif args.all?
puts_deps Formula.sort, recursive
return
elsif !args.remaining.empty? && args.for_each?
puts_deps ARGV.formulae, recursive
elsif !Homebrew.args.remaining.empty? && args.for_each?
puts_deps Homebrew.args.formulae, recursive
return
end

Expand All @@ -88,14 +88,14 @@ def deps
!args.include_optional? &&
!args.skip_recommended?

if args.remaining.empty?
if Homebrew.args.remaining.empty?
raise FormulaUnspecifiedError unless args.installed?

puts_deps Formula.installed.sort, recursive
return
end

all_deps = deps_for_formulae(ARGV.formulae, recursive, &(args.union? ? :| : :&))
all_deps = deps_for_formulae(Homebrew.args.formulae, recursive, &(args.union? ? :| : :&))
all_deps = condense_requirements(all_deps)
all_deps.select!(&:installed?) if args.installed?
all_deps.map!(&method(:dep_display_name))
Expand Down
2 changes: 1 addition & 1 deletion Library/Homebrew/cmd/desc.rb
Expand Up @@ -50,7 +50,7 @@ def desc
raise FormulaUnspecifiedError if ARGV.named.empty?

desc = {}
ARGV.formulae.each { |f| desc[f.full_name] = f.desc }
Homebrew.args.formulae.each { |f| desc[f.full_name] = f.desc }
Descriptions.new(desc)
else
arg = ARGV.named.join(" ")
Expand Down
4 changes: 2 additions & 2 deletions Library/Homebrew/cmd/fetch.rb
Expand Up @@ -49,13 +49,13 @@ def fetch

if args.deps?
bucket = []
ARGV.formulae.each do |f|
Homebrew.args.formulae.each do |f|
bucket << f
bucket.concat f.recursive_dependencies.map(&:to_formula)
end
bucket.uniq!
else
bucket = ARGV.formulae
bucket = Homebrew.args.formulae
end

puts "Fetching: #{bucket * ", "}" if bucket.size > 1
Expand Down
2 changes: 1 addition & 1 deletion Library/Homebrew/cmd/home.rb
Expand Up @@ -23,7 +23,7 @@ def home
if args.remaining.empty?
exec_browser HOMEBREW_WWW
else
exec_browser(*ARGV.formulae.map(&:homepage))
exec_browser(*Homebrew.args.formulae.map(&:homepage))
end
end
end
4 changes: 2 additions & 2 deletions Library/Homebrew/cmd/info.rb
Expand Up @@ -80,7 +80,7 @@ def info

print_json
elsif args.github?
exec_browser(*ARGV.formulae.map { |f| github_info(f) })
exec_browser(*Homebrew.args.formulae.map { |f| github_info(f) })
else
print_info
end
Expand Down Expand Up @@ -129,7 +129,7 @@ def print_json
elsif args.installed?
Formula.installed.sort
else
ARGV.formulae
Homebrew.args.formulae
end
json = ff.map(&:to_hash)
puts JSON.generate(json)
Expand Down
2 changes: 1 addition & 1 deletion Library/Homebrew/cmd/install.rb
Expand Up @@ -130,7 +130,7 @@ def install
# developer tools are available, we need to stop them early on
FormulaInstaller.prevent_build_flags unless DevelopmentTools.installed?

ARGV.formulae.each do |f|
Homebrew.args.formulae.each do |f|
# head-only without --HEAD is an error
if !Homebrew.args.HEAD? && f.stable.nil? && f.devel.nil?
raise <<~EOS
Expand Down
2 changes: 1 addition & 1 deletion Library/Homebrew/cmd/options.rb
Expand Up @@ -35,7 +35,7 @@ def options
else
raise FormulaUnspecifiedError if args.remaining.empty?

puts_options ARGV.formulae
puts_options Homebrew.args.formulae
end
end

Expand Down
2 changes: 1 addition & 1 deletion Library/Homebrew/cmd/style.rb
Expand Up @@ -45,7 +45,7 @@ def style
elsif ARGV.named.any? { |tap| tap.count("/") == 1 }
ARGV.named.map { |tap| Tap.fetch(tap).path }
else
ARGV.formulae.map(&:path)
Homebrew.args.formulae.map(&:path)
end

only_cops = args.only_cops
Expand Down
2 changes: 1 addition & 1 deletion Library/Homebrew/cmd/unpack.rb
Expand Up @@ -32,7 +32,7 @@ def unpack_args
def unpack
unpack_args.parse

formulae = ARGV.formulae
formulae = Homebrew.args.formulae
raise FormulaUnspecifiedError if formulae.empty?

if dir = args.destdir
Expand Down
2 changes: 1 addition & 1 deletion Library/Homebrew/cmd/uses.rb
Expand Up @@ -50,7 +50,7 @@ def uses

used_formulae_missing = false
used_formulae = begin
ARGV.formulae
Homebrew.args.formulae
rescue FormulaUnavailableError => e
opoo e
used_formulae_missing = true
Expand Down
2 changes: 1 addition & 1 deletion Library/Homebrew/dev-cmd/bump-formula-pr.rb
Expand Up @@ -114,7 +114,7 @@ def bump_formula_pr
# Use the user's browser, too.
ENV["BROWSER"] = ENV["HOMEBREW_BROWSER"]

formula = ARGV.formulae.first
formula = Homebrew.args.formulae.first

if formula
tap_full_name, origin_branch, previous_branch = use_correct_linux_tap(formula)
Expand Down
7 changes: 4 additions & 3 deletions Library/Homebrew/dev-cmd/bump-revision.rb
Expand Up @@ -32,10 +32,11 @@ def bump_revision
# user path, too.
ENV["PATH"] = ENV["HOMEBREW_PATH"]

raise FormulaUnspecifiedError if ARGV.formulae.empty?
raise "Multiple formulae given, only one is allowed." if ARGV.formulae.length > 1
formulae = Homebrew.args.formulae
raise FormulaUnspecifiedError if formulae.empty?
raise "Multiple formulae given, only one is allowed." if formulae.length > 1

formula = ARGV.formulae.first
formula = formulae.first
current_revision = formula.revision

if current_revision.zero?
Expand Down
2 changes: 1 addition & 1 deletion Library/Homebrew/dev-cmd/mirror.rb
Expand Up @@ -27,7 +27,7 @@ def mirror
bintray_key = ENV["HOMEBREW_BINTRAY_KEY"]
raise "Missing HOMEBREW_BINTRAY_USER or HOMEBREW_BINTRAY_KEY variables!" if !bintray_user || !bintray_key

ARGV.formulae.each do |f|
Homebrew.args.formulae.each do |f|
bintray_package = Utils::Bottles::Bintray.package f.name
bintray_repo_url = "https://api.bintray.com/packages/homebrew/mirror"
package_url = "#{bintray_repo_url}/#{bintray_package}"
Expand Down
25 changes: 25 additions & 0 deletions Library/Homebrew/test/cli/parser_spec.rb
Expand Up @@ -236,6 +236,21 @@
expect(Homebrew.args.passthrough).to eq %w[--foo --bar=value -s]
end

it "#formulae raises an error when a Formula is unavailable" do
parser.parse(["mxcl"])
expect { Homebrew.args.formulae }.to raise_error FormulaUnavailableError
end

it "#formulae returns an empty array when there are no Formulae" do
parser.parse([])
expect(Homebrew.args.formulae).to be_empty
end

it "#casks returns an empty array when there are no matching casks" do
parser.parse([])
expect(Homebrew.args.casks).to eq []
end

context "kegs" do
before do
keg = HOMEBREW_CELLAR + "mxcl/10.0"
Expand All @@ -252,5 +267,15 @@
expect(Homebrew.args.kegs).to be_empty
end
end

it "#named returns an array of non-option arguments" do
parser.parse(["foo", "-v", "-s"])
expect(Homebrew.args.named).to eq ["foo"]
end

it "#named returns an empty array when there are no named arguments" do
parser.parse([])
expect(Homebrew.args.named).to be_empty
end
end
end