Class: Thor
- Inherits:
-
Object
- Object
- Thor
- Includes:
- Base
- Defined in:
- lib/thor/example.rb,
lib/thor.rb,
lib/thor/base.rb,
lib/thor/util.rb,
lib/thor/error.rb,
lib/thor/shell.rb,
lib/thor/actions.rb,
lib/thor/command.rb,
lib/thor/version.rb,
lib/thor/invocation.rb,
lib/thor/shell/html.rb,
lib/thor/line_editor.rb,
lib/thor/rake_compat.rb,
lib/thor/shell/basic.rb,
lib/thor/shell/color.rb,
lib/thor/parser/option.rb,
lib/thor/parser/options.rb,
lib/thor/completion/bash.rb,
lib/thor/parser/argument.rb,
lib/thor/parser/arguments.rb,
lib/thor/actions/directory.rb,
lib/thor/line_editor/basic.rb,
lib/thor/base/class_methods.rb,
lib/thor/actions/create_file.rb,
lib/thor/actions/create_link.rb,
lib/thor/base/shared_concern.rb,
lib/thor/line_editor/readline.rb,
lib/thor/base/arguments_concern.rb,
lib/thor/completion/bash/subcmd.rb,
lib/thor/actions/empty_directory.rb,
lib/thor/completion/bash/request.rb,
lib/thor/actions/inject_into_file.rb,
lib/thor/actions/file_manipulation.rb,
lib/thor/completion/bash/thor_mixin.rb,
lib/thor/completion/bash/command_mixin.rb,
lib/thor/completion/bash/argument_mixin.rb,
lib/thor/core_ext/hash_with_indifferent_access.rb
Overview
Namespace
Direct Known Subclasses
Defined Under Namespace
Modules: Actions, Base, Completion, CoreExt, Invocation, LineEditor, RakeCompat, Sandbox, Shell, Util Classes: AmbiguousCommandError, Argument, Arguments, Command, ConflictingArgumentError, DynamicCommand, Error, Execution, Group, HiddenCommand, InvocationError, MalformattedArgumentError, Option, Options, ProhibitedArgumentError, RequiredArgumentMissingError, Runner, UndefinedCommandError, UnknownArgumentError
Constant Summary collapse
- HELP_MAPPINGS =
Shortcuts for help.
%w(-h -? --help -D)
- THOR_RESERVED_WORDS =
Thor methods that should not be overwritten by the user.
%w(invoke shell options behavior root destination_root relative_root action add_file create_file in_root inside run run_ruby_script)
- TEMPLATE_EXTNAME =
".tt"
- UndefinedTaskError =
UndefinedCommandError
- AmbiguousTaskError =
AmbiguousCommandError
- Task =
Command
- HiddenTask =
HiddenCommand
- DynamicTask =
DynamicCommand
- ROOT =
Absolute, expanded path to the gem’s root directory.
Pathname.new( __dir__ ).join( '..', '..' ).
- VERSION =
Gem version string.
See versioning for details.
'0.1.13'
- THOR_VERSION =
The version of Thor that Atli is up to date with.
Right now, it’s the version of Thor that was forked, but if I’m able to merge Thor updates in and end up doing so, I intend to update this to reflect it.
See versioning for details.
'0.1.13'
Instance Attribute Summary
Attributes included from Base
#args, #options, #parent_options
Class Method Summary collapse
-
.banner(command, namespace = nil, subcommand = false) ⇒ String
protected
The banner for this class.
-
.baseclass ⇒ Object
protected
:nodoc:.
-
.check_unknown_options!(options = {}) ⇒ Object
Extend check unknown options to accept a hash of conditions.
-
.check_unknown_options?(config) ⇒ Boolean
Overwrite check_unknown_options? to take subcommands and options into account.
-
.command_help(shell, command_name, subcommand = false) ⇒ nil
Prints help information for the given command.
-
.create_command(meth) ⇒ Object
protected
:nodoc:.
-
.default_command(meth = nil) ⇒ Object
Sets the default command when thor is executed without an explicit command to be called.
-
.desc(usage, description, options = {}) ⇒ Object
Defines the usage and the description of the next command.
-
.disable_required_check ⇒ Object
protected
help command has the required check disabled by default.
-
.disable_required_check!(*command_names) ⇒ Object
Disable the check for required options for the given commands.
-
.disable_required_check?(command) ⇒ Boolean
:nodoc:.
-
.dispatch(meth, given_args, given_opts, config) {|instance| ... } ⇒ Object
protected
The method responsible for dispatching given the args.
-
.dynamic_command_class ⇒ Object
protected
:nodoc:.
-
.example(example) ⇒ nil
Add an example to the next defined command.
-
.find_command_possibilities(input) ⇒ Object
protected
This is the logic that takes the command name passed in by the user and determines whether it is an unambiguous prefix of a command or alias name.
-
.help(shell, subcommand = false) ⇒ nil
Prints help information for this class.
-
.initialize_added ⇒ Object
protected
:nodoc:.
-
.long_desc(long_description, options = {}) ⇒ Object
Defines the long description of the next command.
-
.map(mappings = nil) ⇒ HashWithIndifferentAccess<String, Symbol>
Maps an input to a command.
-
.method_option(name, **options) ⇒ Object
Adds an option to the set of method options.
-
.method_options(options = nil) ⇒ Object
Declares the options for the next command to be declared.
-
.normalize_command_name(meth) ⇒ Object
protected
Receives a (possibly nil) command name and returns a name that is in the commands hash.
-
.package_name(name, _ = {}) ⇒ Object
Allows for custom “Command” package naming.
-
.printable_commands(all = true, subcommand = false) ⇒ Array<(String, String)>
Returns commands ready to be printed.
-
.register(klass, subcommand_name, usage, description, options = {}) ⇒ Object
Registers another Thor subclass as a command.
-
.retrieve_command_name(args) ⇒ nil
protected
Retrieve the command name from given args.
-
.running_from_source? ⇒ Boolean
Are we running from the source code (vesus from a Gem install)?.
-
.stop_on_unknown_option ⇒ Object
protected
.
-
.stop_on_unknown_option!(*command_names) ⇒ Object
Stop parsing of options as soon as an unknown option or a regular argument is encountered.
-
.stop_on_unknown_option?(command) ⇒ Boolean
:nodoc:.
-
.subcommand(ui_name, subcommand_class, desc: nil) ⇒ nil
Declare a subcommand by providing an UI name and subcommand class.
-
.subcommand_classes ⇒ Hash<String, Class<Thor::Base>]
Map of subcommand names to Thor classes for this Thor class only.
- .subcommand_help(cmd) ⇒ Object protected
-
.subcommands ⇒ Array<String>
List of subcommand names, including those inherited from super classes.
Instance Method Summary collapse
- #help(*args) ⇒ Object
-
#option_kwds(*names, groups: nil) ⇒ Hash<Symbol, V>
protected
Get a Hash mapping option name symbols to their values ready for ** usage in a method call for the option names and shared option groups.
Methods included from Base
included, #initialize, #on_run_error, #on_run_success, register_klass_file, subclass_files, subclasses
Class Method Details
.banner(command, namespace = nil, subcommand = false) ⇒ String (protected)
The banner for this class. You can customize it if you are invoking the thor class by another ways which is not the Thor::Runner. It receives the command that is going to be invoked and a boolean which indicates if the namespace should be displayed as arguments.
646 647 648 |
# File 'lib/thor.rb', line 646 def self.(command, namespace = nil, subcommand = false) "#{basename} #{command.formatted_usage(self, $thor_runner, subcommand)}" end |
.baseclass ⇒ Object (protected)
:nodoc:
651 652 653 |
# File 'lib/thor.rb', line 651 def self.baseclass #:nodoc: Thor end |
.check_unknown_options!(options = {}) ⇒ Object
Extend check unknown options to accept a hash of conditions.
Parameters
options<Hash>: A hash containing :only and/or :except keys
452 453 454 455 456 457 458 459 460 461 462 |
# File 'lib/thor.rb', line 452 def self.( = {}) @check_unknown_options ||= {} .each do |key, value| if value @check_unknown_options[key] = Array(value) else @check_unknown_options.delete(key) end end @check_unknown_options end |
.check_unknown_options?(config) ⇒ Boolean
Overwrite check_unknown_options? to take subcommands and options into account.
467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 |
# File 'lib/thor.rb', line 467 def self.(config) #:nodoc: = return false unless command = config[:current_command] return true unless command name = command.name if subcommands.include?(name) false elsif [:except] ![:except].include?(name.to_sym) elsif [:only] [:only].include?(name.to_sym) else true end end |
.command_help(shell, command_name, subcommand = false) ⇒ nil
Prints help information for the given command.
221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 |
# File 'lib/thor.rb', line 221 def self.command_help(shell, command_name, subcommand = false) meth = normalize_command_name(command_name) command = all_commands[meth] handle_no_command_error(meth) unless command shell.say "Usage:" shell.say " #{(command, nil, subcommand)}" shell.say \ shell, command..values.group_by { |option| option.group } if command.long_description shell.say "Description:" shell.print_wrapped(command.long_description, :indent => 2) else shell.say command.description end unless command.examples.empty? shell.say "\n" shell.say "Examples:" shell.say "\n" command.examples.each_with_index do |example, index| lines = example.lines bullet = "#{ index + 1}.".ljust 4 shell.say "#{ bullet }#{ lines[0] }" lines[1..-1].each do |line| shell.say " #{ line }" end end shell.say "\n" end nil end |
.create_command(meth) ⇒ Object (protected)
:nodoc:
661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 |
# File 'lib/thor.rb', line 661 def self.create_command(meth) #:nodoc: @usage ||= nil @desc ||= nil @long_desc ||= nil @hide ||= nil examples = @examples || [] @examples = [] if @usage && @desc base_class = @hide ? Thor::HiddenCommand : Thor::Command commands[meth] = base_class.new \ name: meth, description: @desc, long_description: @long_desc, usage: @usage, examples: examples, options: , arguments: method_arguments @usage, @desc, @long_desc, @method_options, @hide, @method_arguments = nil true elsif all_commands[meth] || meth == "method_missing" true else puts "[WARNING] Attempted to create command #{meth.inspect} without usage or description. " \ "Call desc if you want this method to be available as command or declare it inside a " \ "no_commands{} block. Invoked from #{caller[1].inspect}." false end end |
.default_command(meth = nil) ⇒ Object
Sets the default command when thor is executed without an explicit command to be called.
Parameters
- meth<Symbol>
-
name of the default command
30 31 32 33 34 35 36 |
# File 'lib/thor.rb', line 30 def self.default_command(meth = nil) if meth @default_command = meth == :none ? "help" : meth.to_s else @default_command ||= from_superclass(:default_command, "help") end end |
.desc(usage, description, options = {}) ⇒ Object
Defines the usage and the description of the next command.
Parameters
usage<String> description<String> options<String>
66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/thor.rb', line 66 def self.desc(usage, description, = {}) if [:for] command = find_and_refresh_command([:for]) command.usage = usage if usage command.description = description if description else @usage = usage @desc = description @hide = [:hide] || false end end |
.disable_required_check ⇒ Object (protected)
help command has the required check disabled by default.
560 561 562 |
# File 'lib/thor.rb', line 560 def self.disable_required_check #:nodoc: @disable_required_check ||= Set.new([:help]) end |
.disable_required_check!(*command_names) ⇒ Object
Disable the check for required options for the given commands. This is useful if you have a command that does not need the required options to work, like help.
Parameters
- Symbol …
-
A list of commands that should be affected.
541 542 543 |
# File 'lib/thor.rb', line 541 def self.disable_required_check!(*command_names) disable_required_check.merge(command_names) end |
.disable_required_check?(command) ⇒ Boolean
:nodoc:
546 547 548 |
# File 'lib/thor.rb', line 546 def self.disable_required_check?(command) #:nodoc: command && disable_required_check.include?(command.name.to_sym) end |
.dispatch(meth, given_args, given_opts, config) {|instance| ... } ⇒ Object (protected)
The method responsible for dispatching given the args.
573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 |
# File 'lib/thor.rb', line 573 def self.dispatch meth, given_args, given_opts, config # rubocop:disable MethodLength logger.trace "START #{ self.safe_name }.#{ __method__ }", meth: meth, given_args: given_args, given_opts: given_opts, config: config meth ||= retrieve_command_name( given_args ).tap { |new_meth| logger.trace "meth set via .retrieve_command_name", meth: new_meth, map: map } normalized_name = normalize_command_name meth command = all_commands[normalized_name] logger.trace "Fetched command", command: command, all_commands: all_commands.keys, normalized_name: normalized_name if !command && config[:invoked_via_subcommand] # We're a subcommand and our first argument didn't match any of our # commands. So we put it back and call our default command. given_args.unshift(meth) command = all_commands[normalize_command_name(default_command)] end if command args, opts = Thor::Options.split(given_args) if stop_on_unknown_option?(command) && !args.empty? # given_args starts with a non-option, so we treat everything as # ordinary arguments args.concat opts opts.clear end else args = given_args opts = nil command = dynamic_command_class.new(meth) end opts = given_opts || opts || [] config[:current_command] = command config[:command_options] = command. instance = new(args, opts, config) yield instance if block_given? args = instance.args trailing = args[ arguments( command: command ).size..-1 ] instance.invoke_command(command, trailing || []) end |
.dynamic_command_class ⇒ Object (protected)
:nodoc:
656 657 658 |
# File 'lib/thor.rb', line 656 def self.dynamic_command_class #:nodoc: Thor::DynamicCommand end |
.example(example) ⇒ nil
Add an example to the next defined command.
17 18 19 20 21 |
# File 'lib/thor/example.rb', line 17 def self.example example @examples ||= [] @examples << example nil end |
.find_command_possibilities(input) ⇒ Object (protected)
This is the logic that takes the command name passed in by the user and determines whether it is an unambiguous prefix of a command or alias name.
770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 |
# File 'lib/thor.rb', line 770 def self.find_command_possibilities input input = input.to_s possibilities = all_commands.merge(map).keys.select { |name| name.start_with? input }.sort unique_possibilities = possibilities.map { |k| map[k] || k }.uniq results = if possibilities.include? input [ input ] elsif unique_possibilities.size == 1 unique_possibilities else possibilities end logger.trace "Found #{ results.length } command possibilities", results: results, possibilities: possibilities, unique_possibilities: unique_possibilities results end |
.help(shell, subcommand = false) ⇒ nil
Prints help information for this class.
272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 |
# File 'lib/thor.rb', line 272 def self.help(shell, subcommand = false) list = printable_commands(true, subcommand) Thor::Util.thor_classes_in(self).each do |klass| list += klass.printable_commands(false) end list.sort! { |a, b| a[0] <=> b[0] } if defined?(@package_name) && @package_name shell.say "#{@package_name} commands:" else shell.say "Commands:" end shell.print_table(list, :indent => 2, :truncate => true) shell.say (shell) end |
.initialize_added ⇒ Object (protected)
:nodoc:
702 703 704 705 |
# File 'lib/thor.rb', line 702 def self.initialize_added #:nodoc: .merge!() @method_options = nil end |
.long_desc(long_description, options = {}) ⇒ Object
Defines the long description of the next command.
Parameters
long description<String>
84 85 86 87 88 89 90 91 |
# File 'lib/thor.rb', line 84 def self.long_desc(long_description, = {}) if [:for] command = find_and_refresh_command([:for]) command.long_description = long_description if long_description else @long_desc = long_description end end |
.map(mappings = nil) ⇒ HashWithIndifferentAccess<String, Symbol>
Maps an input to a command. If you define:
map "-T" => "list"
Running:
thor -T
Will invoke the list command.
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
# File 'lib/thor.rb', line 123 def self.map mappings = nil @map ||= from_superclass :map, HashWithIndifferentAccess.new if mappings mappings.each do |key, value| if key.respond_to? :each key.each { |subkey| @map[ subkey.to_s ] = value.to_s } else @map[ key.to_s ] = value.to_s end end end @map end |
.method_option(name, **options) ⇒ Object
Adds an option to the set of method options. If :for is given as option, it allows you to change the options from a previous defined command.
def previous_command
# magic
end
method_option :foo => :bar, :for => :previous_command
def next_command
# magic
end
Parameters
- name<Symbol>
-
The name of the argument.
- options<Hash>
-
Described below.
Options
:desc - Description for the argument. :required - If the argument is required or not. :default - Default value for this argument. It cannot be required and
have default values.
:aliases - Aliases for this option. :type - The type of the argument, can be :string, :hash, :array,
:numeric or :boolean.
:banner - String to show on usage notes. :hide - If you want to hide this option from the help.
184 185 186 187 188 189 190 191 192 |
# File 'lib/thor.rb', line 184 def self.method_option name, ** scope = if [:for] find_and_refresh_command([:for]). else end build_option(name, , scope) end |
.method_options(options = nil) ⇒ Object
Declares the options for the next command to be declared.
Parameters
- Hash[Symbol => Object]
-
The hash key is the name of the option and the value
is the type of the option. Can be :string, :array, :hash, :boolean, :numeric or :required (string). If you give a value, the type of the value is used.
147 148 149 150 151 |
# File 'lib/thor.rb', line 147 def self.( = nil) @method_options ||= HashWithIndifferentAccess.new (, @method_options) if @method_options end |
.normalize_command_name(meth) ⇒ Object (protected)
Receives a (possibly nil) command name and returns a name that is in the commands hash. In addition to normalizing aliases, this logic will determine if a shortened command is an unambiguous substring of a command or alias.
normalize_command_name also converts names like ‘animal-prison` into `animal_prison`.
738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 |
# File 'lib/thor.rb', line 738 def self.normalize_command_name meth #:nodoc: return default_command.to_s.tr("-", "_") unless meth possibilities = find_command_possibilities(meth) if possibilities.size > 1 raise AmbiguousTaskError, "Ambiguous command #{meth} matches [#{possibilities.join(', ')}]" end if possibilities.empty? meth ||= default_command elsif map[meth] meth = map[meth] else meth = possibilities.first end meth.to_s.tr("-", "_") # treat foo-bar as foo_bar end |
.package_name(name, _ = {}) ⇒ Object
Allows for custom “Command” package naming.
Parameters
name<String> options<Hash>
19 20 21 |
# File 'lib/thor.rb', line 19 def self.package_name(name, _ = {}) @package_name = name.nil? || name == "" ? nil : name end |
.printable_commands(all = true, subcommand = false) ⇒ Array<(String, String)>
Returns commands ready to be printed.
302 303 304 305 306 307 308 309 310 311 |
# File 'lib/thor.rb', line 302 def self.printable_commands all = true, subcommand = false (all ? all_commands : commands).map do |_, command| next if command.hidden? item = [] item << (command, false, subcommand) item << ( command.description ? "# #{command.description.gsub(/\s+/m, ' ')}" : "" ) item end.compact end |
.register(klass, subcommand_name, usage, description, options = {}) ⇒ Object
Registers another Thor subclass as a command.
Parameters
- klass<Class>
-
Thor subclass to register
- command<String>
-
Subcommand name to use
- usage<String>
-
Short usage for the subcommand
- description<String>
-
Description for the subcommand
48 49 50 51 52 53 54 55 56 |
# File 'lib/thor.rb', line 48 def self.register(klass, subcommand_name, usage, description, = {}) if klass <= Thor::Group desc usage, description, define_method(subcommand_name) { |*args| invoke(klass, args) } else desc usage, description, subcommand subcommand_name, klass end end |
.retrieve_command_name(args) ⇒ nil (protected)
Ugh… this mutates ‘args`
Retrieve the command name from given args.
718 719 720 721 |
# File 'lib/thor.rb', line 718 def self.retrieve_command_name args meth = args.first.to_s unless args.empty? args.shift if meth && (map[meth] || meth !~ /^\-/) end |
.running_from_source? ⇒ Boolean
Are we running from the source code (vesus from a Gem install)?
Looks for the ‘//dev` directory, which is not included in the package.
39 40 41 |
# File 'lib/thor/version.rb', line 39 def self.running_from_source? ( ROOT + 'dev' ).directory? end |
.stop_on_unknown_option ⇒ Object (protected)
554 555 556 |
# File 'lib/thor.rb', line 554 def self.stop_on_unknown_option #:nodoc: @stop_on_unknown_option ||= Set.new end |
.stop_on_unknown_option!(*command_names) ⇒ Object
Stop parsing of options as soon as an unknown option or a regular argument is encountered. All remaining arguments are passed to the command. This is useful if you have a command that can receive arbitrary additional options, and where those additional options should not be handled by Thor.
Example
To better understand how this is useful, let’s consider a command that calls an external command. A user may want to pass arbitrary options and arguments to that command. The command itself also accepts some options, which should be handled by Thor.
class_option "verbose", :type => :boolean
stop_on_unknown_option! :exec
:except => :exec
desc "exec", "Run a shell command"
def exec(*args)
puts "diagnostic output" if [:verbose]
Kernel.exec(*args)
end
Here exec
can be called with --verbose
to get diagnostic output, e.g.:
$ thor exec --verbose echo foo
diagnostic output
foo
But if --verbose
is given after echo
, it is passed to echo
instead:
$ thor exec echo --verbose foo
--verbose foo
Parameters
- Symbol …
-
A list of commands that should be affected.
525 526 527 |
# File 'lib/thor.rb', line 525 def self.stop_on_unknown_option!(*command_names) stop_on_unknown_option.merge(command_names) end |
.stop_on_unknown_option?(command) ⇒ Boolean
:nodoc:
530 531 532 |
# File 'lib/thor.rb', line 530 def self.stop_on_unknown_option?(command) #:nodoc: command && stop_on_unknown_option.include?(command.name.to_sym) end |
.subcommand(ui_name, subcommand_class, desc: nil) ⇒ nil
Declare a subcommand by providing an UI name and subcommand class.
395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 |
# File 'lib/thor.rb', line 395 def self.subcommand ui_name, subcommand_class, desc: nil ui_name = ui_name.to_s method_name = ui_name.underscore subcommands << method_name subcommand_class.subcommand_help ui_name subcommand_classes[method_name] = subcommand_class if desc self.desc "#{ ui_name } SUBCOMMAND...", desc end define_method method_name do |*args| args, opts = Thor::Arguments.split(args) invoke_args = [ args, opts, {:invoked_via_subcommand => true, :class_options => } ] invoke_args.unshift "help" if opts.delete("--help") || opts.delete("-h") invoke subcommand_class, *invoke_args end # Sigh... this used to just be `subcommand_class.commands...`, but that # fails when: # # 1. A Thor class is created with commands defined, then # 2. That Thor class is subclassed, then # 3. The *subclass* as added as a {.subcommand}. # # This is because then the commands that need {Command#ancestor_name} # set are not part of {.commands}, only {.all_commands}. # # At the moment, this *seems* like an architectural problem, since # the commands being mutated via {Thor::Command#ancestor_name=} do # not *belong* to `self` - they are simply part of superclass, which # could logically be re-used across through additional sub-classes # by multiple {Thor} *unless* this is not party of the paradigm... # but the paradigm fundametals and constraints are never really laid # out anywhere. # # Anyways, switching to {subcommand_classes.all_commands...} hacks # the problem away for the moment. # subcommand_class.all_commands.each do |_meth, command| command.ancestor_name ||= ui_name end nil end |
.subcommand_classes ⇒ Hash<String, Class<Thor::Base>]
‘.subcommands` is not necessarily equal to `.subcommand_classes.keys`
-
it won’t be when there are subcommands inherited from super classes.
I’m not really sure how this relates to Group… and I’m not going to take the time to find out now.
Map of subcommand names to Thor classes for this Thor class only.
338 339 340 |
# File 'lib/thor.rb', line 338 def self.subcommand_classes @subcommand_classes ||= {} end |
.subcommand_help(cmd) ⇒ Object (protected)
799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 |
# File 'lib/thor.rb', line 799 def self.subcommand_help(cmd) # logger.trace __method__.to_s, # cmd: cmd, # caller: caller desc "help [COMMAND]", "Describe subcommands or one specific subcommand" # Atli - This used to be {#class_eval} (maybe to support really old # Rubies? Who knows...) but that made it really hard to find in # stack traces, so I switched it to {#define_method}. # define_method :help do |*args| # Add the `is_subcommand = true` trailing arg case args[-1] when true # pass when false # Weird, `false` was explicitly passed... whatever, set it to `true` args[-1] = true else # "Normal" case, append it args << true end super( *args ) end end |
.subcommands ⇒ Array<String>
List of subcommand names, including those inherited from super classes.
320 321 322 |
# File 'lib/thor.rb', line 320 def self.subcommands @subcommands ||= from_superclass(:subcommands, []) end |
Instance Method Details
#help(*args) ⇒ Object
882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 |
# File 'lib/thor.rb', line 882 def help(*args) is_subcommand = case args[-1] when true, false args.pop else false end # Will be the {String} command (get help on that command) # or `nil` (get help on this class) command = args.shift # Possibly empty array of string subcommands from something like # # myexe help sub cmd # # in which case it would end up being `['cmd']` and we actually are just # passing through and want to get help on the `cmd` subcommand. # subcommands = args logger.trace "#help", args: args, command: command, is_subcommand: is_subcommand, subcommands: subcommands if command if self.class.subcommands.include? command if subcommands.empty? # Get help on a subcommand *class* self.class.subcommand_classes[command].help(shell, true) else # Atli addition - handle things like `myexe help sub cmd` # Want help on something (class or command) further down the line invoke self.class.subcommand_classes[command], ['help', *subcommands], {}, {:invoked_via_subcommand => true, :class_options => } end else # Want help on a *command* of this class # # Atli - Now that we've modified {.command_help} to accept # `subcommand`, pass it (it seems to have already been getting # the correct value to here). self.class.command_help(shell, command, is_subcommand) end else # We want help on *this class itself* (list available commands) self.class.help(shell, is_subcommand) end end |
#option_kwds(*names, groups: nil) ⇒ Hash<Symbol, V> (protected)
Get a Hash mapping option name symbols to their values ready for ** usage in a method call for the option names and shared option groups.
847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 |
# File 'lib/thor.rb', line 847 def option_kwds *names, groups: nil # Transform names into a set of strings name_set = Set.new names.map( &:to_s ) # Add groups (if any) if groups groups = Array( groups ) self.class. shared_defs. select { |shared_def| groups.any? { |group| shared_def[ :groups].include? group } }. each do |shared| name_set << shared[:name].to_s end end .slice( *name_set ).sym_keys end |