Class: Toys::Definition::Tool
- Inherits:
-
Object
- Object
- Toys::Definition::Tool
- Defined in:
- lib/toys/definition/tool.rb
Overview
A Tool is a single command that can be invoked using Toys. It has a name, a series of one or more words that you use to identify the tool on the command line. It also has a set of formal flags and command line arguments supported, and a block that gets run when the tool is executed.
Constant Summary collapse
- OPTPARSER_ACCEPTORS =
Built-in acceptors (i.e. those recognized by OptionParser). You can reference these acceptors directly. Otherwise, you have to add one explicitly to the tool using #add_acceptor.
::Set.new( [ ::Object, ::NilClass, ::String, ::Integer, ::Float, ::Numeric, ::TrueClass, ::FalseClass, ::Array, ::Regexp, ::OptionParser::DecimalInteger, ::OptionParser::OctalInteger, ::OptionParser::DecimalNumeric ] ).freeze
Instance Attribute Summary collapse
-
#default_data ⇒ Hash
readonly
Return the default argument data.
-
#desc ⇒ Toys::Utils::WrappableString
Returns the short description string.
-
#flag_definitions ⇒ Array<Toys::Definition::Flag>
readonly
Return a list of all defined flags.
-
#full_name ⇒ Array<String>
readonly
Return the name of the tool as an array of strings.
-
#long_desc ⇒ Array<Toys::Utils::WrappableString>
Returns the long description strings as an array.
-
#middleware_stack ⇒ Array<Object>
readonly
Returns the middleware stack.
-
#optional_arg_definitions ⇒ Array<Toys::Definition::Arg>
readonly
Return a list of all defined optional positional arguments.
-
#priority ⇒ Integer
readonly
Return the priority of this tool definition.
-
#remaining_args_definition ⇒ Toys::Definition::Arg?
readonly
Return the remaining arguments specification, or
nilif remaining arguments are currently not supported by this tool. -
#required_arg_definitions ⇒ Array<Toys::Definition::Arg>
readonly
Return a list of all defined required positional arguments.
-
#source_path ⇒ String
readonly
Returns the path to the file that contains the definition of this tool.
-
#tool_class ⇒ Class
readonly
Return the tool class.
-
#used_flags ⇒ Array<String>
readonly
Return a list of flags that have been used in the flag definitions.
Instance Method Summary collapse
-
#add_acceptor(acceptor) ⇒ Object
Add an acceptor to the tool.
-
#add_flag(key, flags = [], accept: nil, default: nil, handler: nil, report_collisions: true, desc: nil, long_desc: nil) ⇒ Object
Add a flag to the current tool.
-
#add_initializer(proc, *args) ⇒ Object
Add an initializer.
-
#add_mixin(name, mixin_module) ⇒ Object
Add a named mixin module to this tool.
-
#add_optional_arg(key, default: nil, accept: nil, display_name: nil, desc: nil, long_desc: nil) ⇒ Object
Add an optional positional argument to the current tool.
-
#add_required_arg(key, accept: nil, display_name: nil, desc: nil, long_desc: nil) ⇒ Object
Add a required positional argument to the current tool.
-
#add_template(name, template_class) ⇒ Object
Add a named template class to this tool.
-
#append_long_desc(long_desc) ⇒ Object
Append long description strings.
-
#arg_definitions ⇒ Array<Toys::Definition::Arg>
Returns all arg definitions in order: required, optional, remaining.
-
#argument_parsing_disabled? ⇒ Boolean
Returns true if this tool has disabled argument parsing.
-
#custom_acceptors ⇒ Array<Toys::Definition::Acceptor>
Returns a list of all custom acceptors used by this tool.
-
#definition_finished? ⇒ Boolean
Returns true if this tool's definition has been finished and is locked.
-
#disable_argument_parsing ⇒ Object
Disable argument parsing for this tool.
-
#disable_flag(*flags) ⇒ Object
Mark one or more flags as disabled, preventing their use by any subsequent flag definition.
-
#display_name ⇒ String
Returns a displayable name of this tool, generally the full name delimited by spaces.
-
#include_mixin(name) ⇒ Object
Include the given mixin in the tool class.
-
#includes_arguments? ⇒ Boolean
Returns true if at least one flag or positional argument is defined for this tool.
-
#includes_definition? ⇒ Boolean
Returns true if this tool has any definition information.
-
#includes_description? ⇒ Boolean
Returns true if there is a specific description set for this tool.
-
#lock_source_path(path) ⇒ Object
Sets the path to the file that defines this tool.
-
#resolve_acceptor(accept) ⇒ Object
Resolve the given acceptor.
-
#resolve_mixin(name) ⇒ Module?
Get the named mixin from this tool or its ancestors.
-
#resolve_template(name) ⇒ Class?
Get the named template from this tool or its ancestors.
-
#root? ⇒ Boolean
Returns true if this tool is a root tool.
-
#runnable=(proc) ⇒ Object
Set the runnable block.
-
#runnable? ⇒ Boolean
Returns true if this tool is marked as runnable.
-
#set_remaining_args(key, default: [], accept: nil, display_name: nil, desc: nil, long_desc: nil) ⇒ Object
Specify what should be done with unmatched positional arguments.
-
#simple_name ⇒ String
Returns the local name of this tool.
Instance Attribute Details
#default_data ⇒ Hash (readonly)
Return the default argument data.
168 169 170 |
# File 'lib/toys/definition/tool.rb', line 168 def default_data @default_data end |
#desc ⇒ Toys::Utils::WrappableString
Returns the short description string.
125 126 127 |
# File 'lib/toys/definition/tool.rb', line 125 def desc @desc end |
#flag_definitions ⇒ Array<Toys::Definition::Flag> (readonly)
Return a list of all defined flags.
137 138 139 |
# File 'lib/toys/definition/tool.rb', line 137 def flag_definitions @flag_definitions end |
#full_name ⇒ Array<String> (readonly)
Return the name of the tool as an array of strings. This array may not be modified.
107 108 109 |
# File 'lib/toys/definition/tool.rb', line 107 def full_name @full_name end |
#long_desc ⇒ Array<Toys::Utils::WrappableString>
Returns the long description strings as an array.
131 132 133 |
# File 'lib/toys/definition/tool.rb', line 131 def long_desc @long_desc end |
#middleware_stack ⇒ Array<Object> (readonly)
Returns the middleware stack
174 175 176 |
# File 'lib/toys/definition/tool.rb', line 174 def middleware_stack @middleware_stack end |
#optional_arg_definitions ⇒ Array<Toys::Definition::Arg> (readonly)
Return a list of all defined optional positional arguments.
149 150 151 |
# File 'lib/toys/definition/tool.rb', line 149 def optional_arg_definitions @optional_arg_definitions end |
#priority ⇒ Integer (readonly)
Return the priority of this tool definition.
113 114 115 |
# File 'lib/toys/definition/tool.rb', line 113 def priority @priority end |
#remaining_args_definition ⇒ Toys::Definition::Arg? (readonly)
Return the remaining arguments specification, or nil if remaining
arguments are currently not supported by this tool.
156 157 158 |
# File 'lib/toys/definition/tool.rb', line 156 def remaining_args_definition @remaining_args_definition end |
#required_arg_definitions ⇒ Array<Toys::Definition::Arg> (readonly)
Return a list of all defined required positional arguments.
143 144 145 |
# File 'lib/toys/definition/tool.rb', line 143 def required_arg_definitions @required_arg_definitions end |
#source_path ⇒ String (readonly)
Returns the path to the file that contains the definition of this tool.
180 181 182 |
# File 'lib/toys/definition/tool.rb', line 180 def source_path @source_path end |
#tool_class ⇒ Class (readonly)
Return the tool class.
119 120 121 |
# File 'lib/toys/definition/tool.rb', line 119 def tool_class @tool_class end |
#used_flags ⇒ Array<String> (readonly)
Return a list of flags that have been used in the flag definitions.
162 163 164 |
# File 'lib/toys/definition/tool.rb', line 162 def used_flags @used_flags end |
Instance Method Details
#add_acceptor(acceptor) ⇒ Object
Add an acceptor to the tool. This acceptor may be refereneced by name when adding a flag or an arg.
407 408 409 410 411 412 413 414 415 |
# File 'lib/toys/definition/tool.rb', line 407 def add_acceptor(acceptor) if @acceptors.key?(acceptor.name) raise ToolDefinitionError, "An acceptor named #{acceptor.name.inspect} has already been" \ " defined in tool #{display_name.inspect}." end @acceptors[acceptor.name] = acceptor self end |
#add_flag(key, flags = [], accept: nil, default: nil, handler: nil, report_collisions: true, desc: nil, long_desc: nil) ⇒ Object
Add a flag to the current tool. Each flag must specify a key which
the script may use to obtain the flag value from the context.
You may then provide the flags themselves in OptionParser form.
496 497 498 499 500 501 502 503 504 505 506 507 508 509 |
# File 'lib/toys/definition/tool.rb', line 496 def add_flag(key, flags = [], accept: nil, default: nil, handler: nil, report_collisions: true, desc: nil, long_desc: nil) check_definition_state(is_arg: true) accept = resolve_acceptor(accept) flag_def = Definition::Flag.new(key, flags, @used_flags, report_collisions, accept, handler, default) flag_def.desc = desc if desc flag_def.long_desc = long_desc if long_desc @flag_definitions << flag_def if flag_def.active? @default_data[key] = default self end |
#add_initializer(proc, *args) ⇒ Object
Add an initializer.
644 645 646 647 648 |
# File 'lib/toys/definition/tool.rb', line 644 def add_initializer(proc, *args) check_definition_state @initializers << [proc, args] self end |
#add_mixin(name, mixin_module) ⇒ Object
Add a named mixin module to this tool.
423 424 425 426 427 428 429 430 431 432 |
# File 'lib/toys/definition/tool.rb', line 423 def add_mixin(name, mixin_module) name = name.to_s if @mixins.key?(name) raise ToolDefinitionError, "A mixin named #{name.inspect} has already been defined in tool" \ " #{display_name.inspect}." end @mixins[name] = mixin_module self end |
#add_optional_arg(key, default: nil, accept: nil, display_name: nil, desc: nil, long_desc: nil) ⇒ Object
Add an optional positional argument to the current tool. You must specify a key which the script may use to obtain the argument value from the context. If an optional argument is not given on the command line, the value is set to the given default.
583 584 585 586 587 588 589 590 591 592 |
# File 'lib/toys/definition/tool.rb', line 583 def add_optional_arg(key, default: nil, accept: nil, display_name: nil, desc: nil, long_desc: nil) check_definition_state(is_arg: true) accept = resolve_acceptor(accept) arg_def = Definition::Arg.new(key, :optional, accept, default, desc, long_desc, display_name) @optional_arg_definitions << arg_def @default_data[key] = default self end |
#add_required_arg(key, accept: nil, display_name: nil, desc: nil, long_desc: nil) ⇒ Object
Add a required positional argument to the current tool. You must specify a key which the script may use to obtain the argument value from the context.
550 551 552 553 554 555 556 |
# File 'lib/toys/definition/tool.rb', line 550 def add_required_arg(key, accept: nil, display_name: nil, desc: nil, long_desc: nil) check_definition_state(is_arg: true) accept = resolve_acceptor(accept) arg_def = Definition::Arg.new(key, :required, accept, nil, desc, long_desc, display_name) @required_arg_definitions << arg_def self end |
#add_template(name, template_class) ⇒ Object
Add a named template class to this tool.
440 441 442 443 444 445 446 447 448 449 |
# File 'lib/toys/definition/tool.rb', line 440 def add_template(name, template_class) name = name.to_s if @templates.key?(name) raise ToolDefinitionError, "A template named #{name.inspect} has already been defined in tool" \ " #{display_name.inspect}." end @templates[name] = template_class self end |
#append_long_desc(long_desc) ⇒ Object
Append long description strings.
Each string may be provided as a Utils::WrappableString, a single string (which will be wrapped), or an array of strings, which will be interpreted as string fragments that will be concatenated and wrapped.
396 397 398 399 |
# File 'lib/toys/definition/tool.rb', line 396 def append_long_desc(long_desc) check_definition_state @long_desc += Utils::WrappableString.make_array(long_desc) end |
#arg_definitions ⇒ Array<Toys::Definition::Arg>
Returns all arg definitions in order: required, optional, remaining.
262 263 264 265 266 |
# File 'lib/toys/definition/tool.rb', line 262 def arg_definitions result = required_arg_definitions + optional_arg_definitions result << remaining_args_definition if remaining_args_definition result end |
#argument_parsing_disabled? ⇒ Boolean
Returns true if this tool has disabled argument parsing.
254 255 256 |
# File 'lib/toys/definition/tool.rb', line 254 def argument_parsing_disabled? @disable_argument_parsing end |
#custom_acceptors ⇒ Array<Toys::Definition::Acceptor>
Returns a list of all custom acceptors used by this tool.
272 273 274 275 276 277 278 279 280 281 |
# File 'lib/toys/definition/tool.rb', line 272 def custom_acceptors result = [] flag_definitions.each do |f| result << f.accept if f.accept.is_a?(Acceptor) end arg_definitions.each do |a| result << a.accept if a.accept.is_a?(Acceptor) end result.uniq end |
#definition_finished? ⇒ Boolean
Returns true if this tool's definition has been finished and is locked.
246 247 248 |
# File 'lib/toys/definition/tool.rb', line 246 def definition_finished? @definition_finished end |
#disable_argument_parsing ⇒ Object
Disable argument parsing for this tool
454 455 456 457 458 459 460 461 462 463 |
# File 'lib/toys/definition/tool.rb', line 454 def disable_argument_parsing check_definition_state if includes_arguments? raise ToolDefinitionError, "Cannot disable argument parsing for tool #{display_name.inspect}" \ " because arguments have already been defined." end @disable_argument_parsing = true self end |
#disable_flag(*flags) ⇒ Object
Mark one or more flags as disabled, preventing their use by any subsequent flag definition. This may be used to prevent middleware from defining a particular flag.
518 519 520 521 522 523 524 525 526 527 |
# File 'lib/toys/definition/tool.rb', line 518 def disable_flag(*flags) check_definition_state(is_arg: true) flags = flags.uniq intersection = @used_flags & flags unless intersection.empty? raise ToolDefinitionError, "Cannot disable flags already used: #{intersection.inspect}" end @used_flags.concat(flags) self end |
#display_name ⇒ String
Returns a displayable name of this tool, generally the full name delimited by spaces.
195 196 197 |
# File 'lib/toys/definition/tool.rb', line 195 def display_name full_name.join(" ") end |
#include_mixin(name) ⇒ Object
Include the given mixin in the tool class.
338 339 340 341 |
# File 'lib/toys/definition/tool.rb', line 338 def include_mixin(name) tool_class.include(name) self end |
#includes_arguments? ⇒ Boolean
Returns true if at least one flag or positional argument is defined for this tool.
228 229 230 231 232 |
# File 'lib/toys/definition/tool.rb', line 228 def includes_arguments? !default_data.empty? || !flag_definitions.empty? || !required_arg_definitions.empty? || !optional_arg_definitions.empty? || !remaining_args_definition.nil? end |
#includes_definition? ⇒ Boolean
Returns true if this tool has any definition information.
238 239 240 |
# File 'lib/toys/definition/tool.rb', line 238 def includes_definition? includes_arguments? || runnable? end |
#includes_description? ⇒ Boolean
Returns true if there is a specific description set for this tool.
219 220 221 |
# File 'lib/toys/definition/tool.rb', line 219 def includes_description? !long_desc.empty? || !desc.empty? end |
#lock_source_path(path) ⇒ Object
Sets the path to the file that defines this tool. A tool may be defined from at most one path. If a different path is already set, raises ToolDefinitionError
350 351 352 353 354 355 356 357 |
# File 'lib/toys/definition/tool.rb', line 350 def lock_source_path(path) if source_path && source_path != path raise ToolDefinitionError, "Cannot redefine tool #{display_name.inspect} in #{path}" \ " (already defined in #{source_path})" end @source_path = path end |
#resolve_acceptor(accept) ⇒ Object
Resolve the given acceptor. You may pass in a
Acceptor, an acceptor name, a well-known acceptor
understood by OptionParser, or nil.
Returns either nil or an acceptor that is usable by OptionParser.
If an acceptor name is given, it may be resolved by this tool or any of its ancestors. Raises ToolDefinitionError if the name is not recognized.
297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 |
# File 'lib/toys/definition/tool.rb', line 297 def resolve_acceptor(accept) return accept if accept.nil? || accept.is_a?(Acceptor) name = accept accept = @acceptors.fetch(name) do |k| if @parent @parent.resolve_acceptor(k) elsif OPTPARSER_ACCEPTORS.include?(k) k end end if accept.nil? raise ToolDefinitionError, "Unknown acceptor: #{name.inspect}" end accept end |
#resolve_mixin(name) ⇒ Module?
Get the named mixin from this tool or its ancestors.
329 330 331 |
# File 'lib/toys/definition/tool.rb', line 329 def resolve_mixin(name) @mixins.fetch(name.to_s) { |k| @parent ? @parent.resolve_mixin(k) : nil } end |
#resolve_template(name) ⇒ Class?
Get the named template from this tool or its ancestors.
319 320 321 |
# File 'lib/toys/definition/tool.rb', line 319 def resolve_template(name) @templates.fetch(name.to_s) { |k| @parent ? @parent.resolve_template(k) : nil } end |
#root? ⇒ Boolean
Returns true if this tool is a root tool.
203 204 205 |
# File 'lib/toys/definition/tool.rb', line 203 def root? full_name.empty? end |
#runnable=(proc) ⇒ Object
Set the runnable block
634 635 636 |
# File 'lib/toys/definition/tool.rb', line 634 def runnable=(proc) @tool_class.to_run(&proc) end |
#runnable? ⇒ Boolean
Returns true if this tool is marked as runnable.
211 212 213 |
# File 'lib/toys/definition/tool.rb', line 211 def runnable? @runnable end |
#set_remaining_args(key, default: [], accept: nil, display_name: nil, desc: nil, long_desc: nil) ⇒ Object
Specify what should be done with unmatched positional arguments. You must specify a key which the script may use to obtain the remaining args from the context.
618 619 620 621 622 623 624 625 626 627 |
# File 'lib/toys/definition/tool.rb', line 618 def set_remaining_args(key, default: [], accept: nil, display_name: nil, desc: nil, long_desc: nil) check_definition_state(is_arg: true) accept = resolve_acceptor(accept) arg_def = Definition::Arg.new(key, :remaining, accept, default, desc, long_desc, display_name) @remaining_args_definition = arg_def @default_data[key] = default self end |
#simple_name ⇒ String
Returns the local name of this tool.
186 187 188 |
# File 'lib/toys/definition/tool.rb', line 186 def simple_name full_name.last end |