Skip to content

Commit

Permalink
Use method result table
Browse files Browse the repository at this point in the history
  • Loading branch information
dduugg committed Dec 6, 2024
1 parent bbb9bd3 commit bcc6d0f
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 36 deletions.
35 changes: 13 additions & 22 deletions Library/Homebrew/cli/args.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ class Args
sig { returns(T::Array[String]) }
attr_reader :options_only, :flags_only, :remaining

sig { returns(T::Hash[Symbol, T.any(NilClass, T::Boolean, String, T::Array[String])]) }
attr_accessor :table

sig { void }
def initialize
require "cli/named_args"
Expand All @@ -23,7 +26,7 @@ def initialize
@options_only = T.let([], T::Array[String])
@flags_only = T.let([], T::Array[String])
@cask_options = T.let(false, T::Boolean)
@table = T.let({}, T::Hash[Symbol, T.untyped])
@table = T.let({}, T::Hash[Symbol, T.any(NilClass, T::Boolean, String, T::Array[String])])

# Can set these because they will be overwritten by freeze_named_args!
# (whereas other values below will only be overwritten if passed).
Expand Down Expand Up @@ -55,15 +58,9 @@ def build_bottle? = false
sig { returns(T::Boolean) }
def build_from_source? = false

sig { returns(T::Boolean) }
def cask? = false

sig { returns(T::Boolean) }
def force_bottle? = false

# Defined in extend/os:
# def formula; end

sig { returns(T::Boolean) }
def HEAD? = false

Expand Down Expand Up @@ -128,6 +125,8 @@ def context

sig { returns(T.nilable(Symbol)) }
def only_formula_or_cask
return unless respond_to?(:formula?) && respond_to?(:cask?)

if formula? && !cask?
:formula
elsif cask? && !formula?
Expand Down Expand Up @@ -185,26 +184,18 @@ def cli_args
@cli_args = []
@processed_options.each do |short, long|
option = long || short
switch_val = invoke_if_respond_to(:"#{option_to_name(option)}?")
flag_val = invoke_if_respond_to(option_to_name(option).to_sym)
if switch_val == true || flag_val == true
switch = :"#{option_to_name(option)}?"
flag = option_to_name(option).to_sym
if @table[switch] == true || @table[flag] == true
@cli_args << option
elsif flag_val.instance_of? String
@cli_args << "#{option}=#{flag_val}"
elsif flag_val.instance_of? Array
@cli_args << "#{option}=#{flag_val.join(",")}"
elsif @table[flag].instance_of? String
@cli_args << "#{option}=#{@table[flag]}"
elsif @table[flag].instance_of? Array
@cli_args << "#{option}=#{@table[flag].join(",")}"
end
end
@cli_args.freeze
end

# FIXME: This is here for compatibility with the previous implementation that used OpenStruct.
# This is for args that need to determine whether they have been set or not, and thus may not support a default
# implementation.
sig { params(method: Symbol).returns(T.untyped) }
def invoke_if_respond_to(method)
public_send(method) if respond_to?(method)
end
end
end
end
21 changes: 16 additions & 5 deletions Library/Homebrew/cli/parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ def comma_array(name, description: nil, hidden: false)
description = option_description(description, name, hidden:)
process_option(name, description, type: :comma_array, hidden:)
@parser.on(name, OptionParser::REQUIRED_ARGUMENT, Array, *wrap_option_desc(description)) do |list|
@args.define_singleton_method(option_to_name(name)) { list }
set_args_method(option_to_name(name).to_sym, list)
end
end

Expand All @@ -277,7 +277,7 @@ def flag(*names, description: nil, replacement: nil, depends_on: nil, hidden: fa
# This odisabled should stick around indefinitely.
odisabled "the `#{names.first}` flag", replacement unless replacement.nil?
names.each do |name|
@args.define_singleton_method(option_to_name(name)) { option_value }
set_args_method(option_to_name(name).to_sym, option_value)
end
end

Expand All @@ -286,6 +286,17 @@ def flag(*names, description: nil, replacement: nil, depends_on: nil, hidden: fa
end
end

sig { params(name: Symbol, value: T.any(NilClass, T::Boolean, String, T::Array[String])).void }
def set_args_method(name, value)
@args.table[name] = value
return if @args.respond_to?(name)

@args.define_singleton_method(name) do
T.bind(self, Args)
table.fetch(name)
end
end

sig { params(options: String).returns(T::Array[T::Array[String]]) }
def conflicts(*options)
@conflicts << options.map { |option| option_to_name(option) }
Expand Down Expand Up @@ -552,7 +563,7 @@ def generate_banner
def set_switch(*names, value:, from:)
names.each do |name|
@switch_sources[option_to_name(name)] = from
@args.define_singleton_method(:"#{option_to_name(name)}?") { value }
set_args_method(:"#{option_to_name(name)}?", value)
end
end

Expand All @@ -564,7 +575,7 @@ def disable_switch(*args)
else
false
end
@args.define_singleton_method(:"#{option_to_name(name)}?") { result }
set_args_method(:"#{option_to_name(name)}?", result)
end
end

Expand Down Expand Up @@ -673,7 +684,7 @@ def process_option(*args, type:, hidden: false)
disable_switch(*args)
else
args.each do |name|
@args.define_singleton_method(option_to_name(name)) { nil }
set_args_method(option_to_name(name).to_sym, nil)
end
end

Expand Down
6 changes: 6 additions & 0 deletions Library/Homebrew/extend/os/linux/cli/parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,14 @@ module Parser

requires_ancestor { Homebrew::CLI::Parser }

sig { void }
def set_default_options
args.table[:"formula?"] = true if args.respond_to?(:formula?)
end

sig { void }
def validate_options
return unless args.respond_to?(:cask?)
return unless args.cask?

# NOTE: We don't raise an error here because we don't want
Expand Down
9 changes: 0 additions & 9 deletions Library/Homebrew/extend/os/parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,3 @@
# frozen_string_literal: true

require "extend/os/linux/cli/parser" if OS.linux?

module Homebrew
module CLI
class Args
sig { returns(T::Boolean) }
def formula? = OS.linux?
end
end
end

0 comments on commit bcc6d0f

Please sign in to comment.