class Bundler::Thor
常量
- AmbiguousTaskError
- Correctable
- DynamicTask
一个动态命令,处理方法缺失的情况。
- HELP_MAPPINGS
帮助的快捷方式。
- HiddenTask
一个隐藏在帮助消息中但仍然可以调用的命令。
- TEMPLATE_EXTNAME
- THOR_RESERVED_WORDS
Bundler::Thor 方法,不应被用户覆盖。
- Task
- UndefinedTaskError
当找不到命令时引发。
- VERSION
公共类方法
扩展检查未知选项以接受条件哈希。
参数¶ ↑
options<Hash>: 包含 :only 和/或 :except 键的哈希
# 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
打印给定命令的帮助信息。
参数¶ ↑
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
设置在执行 thor 时没有显式调用命令时的默认命令。
参数¶ ↑
- meth<Symbol>
-
默认命令的名称
# 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
定义下一个命令的用法和描述。
参数¶ ↑
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
打印此类的帮助信息。
参数¶ ↑
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
定义下一个命令的详细描述。
默认情况下,长描述是缩进的、换行的和重复的空白合并的。 为了逐字打印长描述,其中缩进和间距与代码中完全一致,请使用 wrap
选项
long_desc 'your very long description', wrap: false
参数¶ ↑
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
将输入映射到命令。如果您定义
map "-T" => "list"
运行
thor -T
将调用 list 命令。
参数¶ ↑
- Hash[String|Array => Symbol]
-
将字符串或数组中的字符串映射到给定的命令。
# 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
添加并声明选项组,用于块参数中至少需要一个的选项。 您可以在块外部声明选项。
如果给定 :for 作为选项,则允许您更改先前定义的命令中的选项。
参数¶ ↑
- options<Hash>
-
:for 应用于先前定义的命令。
示例¶ ↑
at_least_one do option :one option :two end
或者
option :one option :two at_least_one :one, :two
如果您不提供“--one”和“--two”,则会引发 AtLeastOneRequiredArgumentError
。
您可以同时使用 at_least_one
和 exclusive。
exclusive do at_least_one do option :one option :two end end
然后,只需要“--one”或“--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
添加并声明选项组,用于块和参数中的互斥选项。 您可以在块外部声明选项。
如果给定 :for 作为选项,则允许您更改先前定义的命令中的选项。
参数¶ ↑
- options<Hash>
-
:for 应用于先前定义的命令。
示例¶ ↑
exclusive do option :one option :two end
或者
option :one option :two exclusive :one, :two
如果您同时提供“--one”和“--two”,则会引发 ExclusiveArgumentsError。
# 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
将选项添加到方法选项集。 如果给定 :for 作为选项,则允许您更改先前定义的命令中的选项。
def previous_command # magic end method_option :foo, :for => :previous_command def next_command # magic end
参数¶ ↑
- name<Symbol>
-
参数的名称。
- options<Hash>
-
在下面描述。
选项¶ ↑
:desc - 参数的描述。 :required - 参数是否为必需。 :default - 此参数的默认值。 它不能是必需的并具有默认值。 :aliases - 此选项的别名。 :type - 参数的类型,可以是 :string、:hash、:array、:numeric 或 :boolean。 :banner - 在用法说明中显示的字符串。 :hide - 如果您想从帮助中隐藏此选项。
# 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
声明要声明的下一个命令的选项。
参数¶ ↑
- Hash[Symbol => Object]
-
哈希键是选项的名称,值是
选项的类型。可以是 :string、:array、:hash、:boolean、:numeric 或 :required (string)。如果给出一个值,则使用该值的类型。
# 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
返回准备好打印的命令。
# 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
将另一个 Bundler::Thor 子类注册为命令。
参数¶ ↑
- klass<Class>
-
要注册的 Bundler::Thor 子类
- command<String>
-
要使用的子命令名称
- usage<String>
-
子命令的简短用法
- description<String>
-
子命令的描述
# 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
一旦遇到未知选项或常规参数,就停止解析选项。 所有剩余参数都传递给命令。 如果您有一个可以接收任意其他选项的命令,并且这些附加选项不应由 Bundler::Thor 处理,则此功能很有用。
示例¶ ↑
为了更好地理解它的作用,让我们考虑一个调用外部命令的命令。 用户可能希望将任意选项和参数传递给该命令。 该命令本身也接受一些选项,这些选项应该由 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
在这里,可以使用 --verbose
调用 exec
以获取诊断输出,例如
$ thor exec --verbose echo foo diagnostic output foo
但是,如果在 echo
之后给出 --verbose
,它会传递给 echo
$ thor exec echo --verbose foo --verbose foo
参数¶ ↑
- Symbol …
-
应该受影响的命令列表。
# 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
受保护的类方法
这是获取用户传入的命令名称并确定它是否是命令或别名名称的明确子字符串的逻辑。
# 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
默认情况下,按字典顺序对命令进行排序。
可以在子类中重写以更改命令的显示顺序。
# 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
公共实例方法
# 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