classThorclassOption<Argument#:nodoc:attr_reader:aliases,:group,:lazy_default,:hide,:repeatableVALID_TYPES=[:boolean,:numeric,:hash,:array,:string]definitialize(name,options={})@check_default_type=options[:check_default_type]options[:required]=falseunlessoptions.key?(:required)@repeatable=options.fetch(:repeatable,false)super@lazy_default=options[:lazy_default]@group=options[:group].to_s.capitalizeifoptions[:group]@aliases=normalize_aliases(options[:aliases])@hide=options[:hide]end# This parse quick options given as method_options. It makes several# assumptions, but you can be more specific using the option method.## parse :foo => "bar"# #=> Option foo with default value bar## parse [:foo, :baz] => "bar"# #=> Option foo with default value bar and alias :baz## parse :foo => :required# #=> Required option foo without default value## parse :foo => 2# #=> Option foo with default value 2 and type numeric## parse :foo => :numeric# #=> Option foo without default value and type numeric## parse :foo => true# #=> Option foo with default value true and type boolean## The valid types are :boolean, :numeric, :hash, :array and :string. If none# is given a default type is assumed. This default type accepts arguments as# string (--foo=value) or booleans (just --foo).## By default all options are optional, unless :required is given.#defself.parse(key,value)ifkey.is_a?(Array)name,*aliases=keyelsename=keyaliases=[]endname=name.to_sdefault=valuetype=casevaluewhenSymboldefault=nilifVALID_TYPES.include?(value)valueelsifrequired=(value==:required)# rubocop:disable Lint/AssignmentInCondition:stringendwhenTrueClass,FalseClass:booleanwhenNumeric:numericwhenHash,Array,Stringvalue.class.name.downcase.to_symendnew(name.to_s,required: required,type: type,default: default,aliases: aliases)enddefswitch_name@switch_name||=dasherized??name:dasherize(name)enddefhuman_name@human_name||=dasherized??undasherize(name):nameenddefusage(padding=0)sample=ifbanner&&!banner.to_s.empty?"#{switch_name}=#{banner}".dupelseswitch_nameendsample="[#{sample}]".dupunlessrequired?ifboolean?&&name!="force"&&!name.match(/\A(no|skip)[\-_]/)sample<<", [#{dasherize('no-'+human_name)}], [#{dasherize('skip-'+human_name)}]"endaliases_for_usage.ljust(padding)+sampleenddefaliases_for_usageifaliases.empty?""else"#{aliases.join(', ')}, "endenddefshow_default?casedefaultwhenTrueClass,FalseClasstrueelsesuperendendVALID_TYPES.eachdo|type|class_eval<<-RUBY,__FILE__,__LINE__+1
def #{type}?
self.type == #{type.inspect}
end
RUBYendprotecteddefvalidate!raiseArgumentError,"An option cannot be boolean and required."ifboolean?&&required?validate_default_type!enddefvalidate_default_type!default_type=case@defaultwhennilreturnwhenTrueClass,FalseClassrequired??:string::booleanwhenNumeric:numericwhenSymbol:stringwhenHash,Array,String@default.class.name.downcase.to_symendexpected_type=(@repeatable&&@type!=:hash)?:array:@typeifdefault_type!=expected_typeerr="Expected #{expected_type} default value for '#{switch_name}'; got #{@default.inspect} (#{default_type})"if@check_default_typeraiseArgumentError,errelsif@check_default_type==nilThor.deprecation_warning"#{err}.\n"+"This will be rejected in the future unless you explicitly pass the options `check_default_type: false`"+" or call `allow_incompatible_default_type!` in your code"endendenddefdasherized?name.index("-")==0enddefundasherize(str)str.sub(/^-{1,2}/,"")enddefdasherize(str)(str.length>1?"--":"-")+str.tr("_","-")endprivatedefnormalize_aliases(aliases)Array(aliases).map{|short|short.to_s.sub(/^(?!\-)/,"-")}endendend