class Bundler::Thor
Constants
- AmbiguousTaskError
- Correctable
- DynamicTask
A dynamic command that handles method missing scenarios.
- HELP_MAPPINGS
Shortcuts for help.
- HiddenTask
A command that is hidden in help messages but still invocable.
- TEMPLATE_EXTNAME
- THOR_RESERVED_WORDS
Bundler::Thor methods that should not be overwritten by the user.
- Task
- UndefinedTaskError
Raised when a command was not found.
- VERSION
Public Class Methods
Extend check unknown options to accept a hash of conditions.
Parameters¶ ↑
options<Hash>: A hash containing :only and/or :except keys
# File bundler/vendor/thor/lib/thor.rb, line 350 def check_unknown_options!(options = {}) @check_unknown_options ||= {} 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
Prints help information for the given command.
Parameters¶ ↑
shell<Bundler::Thor::Shell> command_name<String>
# File bundler/vendor/thor/lib/thor.rb, line 258 def command_help(shell, command_name) meth = normalize_command_name(command_name) command = all_commands[meth] handle_no_command_error(meth) unless command shell.say "Usage:" shell.say " #{banner(command).split("\n").join("\n ")}" shell.say class_options_help(shell, nil => command.options.values) print_exclusive_options(shell, command) print_at_least_one_required_options(shell, command) if command.long_description shell.say "Description:" if command.wrap_long_description shell.print_wrapped(command.long_description, indent: 2) else shell.say command.long_description end else shell.say command.description end end
Sets the default command when thor is executed without an explicit command to be called.
Parameters¶ ↑
- meth<Symbol>
-
name of the default command
# File bundler/vendor/thor/lib/thor.rb, line 21 def default_command(meth = nil) if meth @default_command = meth == :none ? "help" : meth.to_s else @default_command ||= from_superclass(:default_command, "help") end end
Defines the usage and the description of the next command.
Parameters¶ ↑
usage<String> description<String> options<String>
# File bundler/vendor/thor/lib/thor.rb, line 54 def desc(usage, description, options = {}) if options[:for] command = find_and_refresh_command(options[:for]) command.usage = usage if usage command.description = description if description else @usage = usage @desc = description @hide = options[:hide] || false end end
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.
# File bundler/vendor/thor/lib/thor.rb, line 434 def disable_required_check!(*command_names) @disable_required_check = disable_required_check | command_names end
Prints help information for this class.
Parameters¶ ↑
shell<Bundler::Thor::Shell>
# File bundler/vendor/thor/lib/thor.rb, line 288 def help(shell, subcommand = false) list = printable_commands(true, subcommand) Bundler::Thor::Util.thor_classes_in(self).each do |klass| list += klass.printable_commands(false) end sort_commands!(list) 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 class_options_help(shell) print_exclusive_options(shell) print_at_least_one_required_options(shell) end
Defines the long description of the next command.
Long description is by default indented, line-wrapped and repeated whitespace merged. In order to print long description verbatim, with indentation and spacing exactly as found in the code, use the wrap
option
long_desc 'your very long description', wrap: false
Parameters¶ ↑
long description<String> options<Hash>
# File bundler/vendor/thor/lib/thor.rb, line 78 def long_desc(long_description, options = {}) if options[:for] command = find_and_refresh_command(options[:for]) command.long_description = long_description if long_description else @long_desc = long_description @long_desc_wrap = options[:wrap] != false end end
Maps an input to a command. If you define:
map "-T" => "list"
Running:
thor -T
Will invoke the list command.
Parameters¶ ↑
- Hash[String|Array => Symbol]
-
Maps the string or the strings in the array to the given command.
# File bundler/vendor/thor/lib/thor.rb, line 101 def map(mappings = nil, **kw) @map ||= from_superclass(:map, {}) if mappings && !kw.empty? mappings = kw.merge!(mappings) else mappings ||= kw end if mappings mappings.each do |key, value| if key.respond_to?(:each) key.each { |subkey| @map[subkey] = value } else @map[key] = value end end end @map end
Adds and declares option group for required at least one of options in the block of arguments. You can declare options as the outside of the block.
If :for is given as option, it allows you to change the options from a previous defined command.
Parameters¶ ↑
- options<Hash>
-
:for is applied for previous defined command.
Examples¶ ↑
at_least_one do option :one option :two end
Or
option :one option :two at_least_one :one, :two
If you do not give “–one” and “–two” AtLeastOneRequiredArgumentError
will be raised.
You can use at_least_one
and exclusive at the same time.
exclusive do at_least_one do option :one option :two end end
Then it is required either only one of “–one” or “–two”.
# File bundler/vendor/thor/lib/thor.rb, line 246 def method_at_least_one(*args, &block) register_options_relation_for(:method_options, :method_at_least_one_option_names, *args, &block) end
Adds and declares option group for exclusive options in the block and arguments. You can declare options as the outside of the block.
If :for is given as option, it allows you to change the options from a previous defined command.
Parameters¶ ↑
- options<Hash>
-
:for is applied for previous defined command.
Examples¶ ↑
exclusive do option :one option :two end
Or
option :one option :two exclusive :one, :two
If you give “–one” and “–two” at the same time ExclusiveArgumentsError will be raised.
# File bundler/vendor/thor/lib/thor.rb, line 203 def method_exclusive(*args, &block) register_options_relation_for(:method_options, :method_exclusive_option_names, *args, &block) end
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, :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.
# File bundler/vendor/thor/lib/thor.rb, line 163 def method_option(name, options = {}) unless [ Symbol, String ].any? { |klass| name.is_a?(klass) } raise ArgumentError, "Expected a Symbol or String, got #{name.inspect}" end scope = if options[:for] find_and_refresh_command(options[:for]).options else method_options end build_option(name, options, scope) end
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.
# File bundler/vendor/thor/lib/thor.rb, line 129 def method_options(options = nil) @method_options ||= {} build_options(options, @method_options) if options @method_options end
Returns commands ready to be printed.
# File bundler/vendor/thor/lib/thor.rb, line 309 def printable_commands(all = true, subcommand = false) (all ? all_commands : commands).map do |_, command| next if command.hidden? item = [] item << banner(command, false, subcommand) item << (command.description ? "# #{command.description.gsub(/\s+/m, ' ')}" : "") item end.compact end
Registers another Bundler::Thor subclass as a command.
Parameters¶ ↑
- klass<Class>
-
Bundler::Thor subclass to register
- command<String>
-
Subcommand name to use
- usage<String>
-
Short usage for the subcommand
- description<String>
-
Description for the subcommand
# File bundler/vendor/thor/lib/thor.rb, line 37 def register(klass, subcommand_name, usage, description, options = {}) if klass <= Bundler::Thor::Group desc usage, description, options define_method(subcommand_name) { |*args| invoke(klass, args) } else desc usage, description, options subcommand subcommand_name, klass end end
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 Bundler::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 Bundler::Thor.
class_option "verbose", :type => :boolean stop_on_unknown_option! :exec check_unknown_options! :except => :exec desc "exec", "Run a shell command" def exec(*args) puts "diagnostic output" if options[: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.
# File bundler/vendor/thor/lib/thor.rb, line 420 def stop_on_unknown_option!(*command_names) @stop_on_unknown_option = stop_on_unknown_option | command_names end
# File bundler/vendor/thor/lib/thor.rb, line 329 def subcommand(subcommand, subcommand_class) subcommands << subcommand.to_s subcommand_class.subcommand_help subcommand subcommand_classes[subcommand.to_s] = subcommand_class define_method(subcommand) do |*args| args, opts = Bundler::Thor::Arguments.split(args) invoke_args = [args, opts, {invoked_via_subcommand: true, class_options: options}] invoke_args.unshift "help" if opts.delete("--help") || opts.delete("-h") invoke subcommand_class, *invoke_args end subcommand_class.commands.each do |_meth, command| command.ancestor_name = subcommand end end
# File bundler/vendor/thor/lib/thor.rb, line 325 def subcommand_classes @subcommand_classes ||= {} end
# File bundler/vendor/thor/lib/thor.rb, line 320 def subcommands @subcommands ||= from_superclass(:subcommands, []) end
Protected Class Methods
this is the logic that takes the command name passed in by the user and determines whether it is an unambiguous substrings of a command or alias name.
# File bundler/vendor/thor/lib/thor.rb, line 626 def find_command_possibilities(meth) len = meth.to_s.length possibilities = all_commands.merge(map).keys.select { |n| meth == n[0, len] }.sort unique_possibilities = possibilities.map { |k| map[k] || k }.uniq if possibilities.include?(meth) [meth] elsif unique_possibilities.size == 1 unique_possibilities else possibilities end end
Sort the commands, lexicographically by default.
Can be overridden in the subclass to change the display order of the commands.
# File bundler/vendor/thor/lib/thor.rb, line 653 def sort_commands!(list) list.sort! { |a, b| a[0] <=> b[0] } end
# File bundler/vendor/thor/lib/thor.rb, line 641 def subcommand_help(cmd) desc "help [COMMAND]", "Describe subcommands or one specific subcommand" class_eval " def help(command = nil, subcommand = true); super; end " end
Public Instance Methods
# File bundler/vendor/thor/lib/thor.rb, line 663 def help(command = nil, subcommand = false) if command if self.class.subcommands.include? command self.class.subcommand_classes[command].help(shell, true) else self.class.command_help(shell, command) end else self.class.help(shell, subcommand) end end