模块 Bundler::Thor::Base::ClassMethods
公共实例方法
返回此 Bundler::Thor 类及其所有子类的命令。
返回¶ ↑
- Hash
-
一个有序哈希,以命令名称为键,
Bundler::Thor::Command
对象为值。
# File bundler/vendor/thor/lib/thor/base.rb, line 482 def all_commands @all_commands ||= from_superclass(:all_commands, Hash.new) @all_commands.merge!(commands) end
如果要使用与选项类型不匹配的默认值,请指定 `check_default_type: false` 或调用 `allow_incompatible_default_type!`
# File bundler/vendor/thor/lib/thor/base.rb, line 189 def allow_incompatible_default_type! @check_default_type = false end
向类添加一个参数,并为其创建一个 attr_accessor。
参数在几个方面与选项不同。第一个方面是如何从命令行解析它们,参数从位置检索
thor command NAME
而不是
thor command --name=NAME
此外,参数在您的代码中用作访问器 (self.argument),而选项都保存在哈希 (self.options) 中。
最后,参数不能有类型 :default 或 :boolean,但可以是可选的(提供 :optional => :true 或 :required => false),尽管在非必需参数之后不能有必需的参数。如果尝试这样做,则会引发错误。
参数¶ ↑
- name<Symbol>
-
参数的名称。
- options<Hash>
-
如下所述。
选项¶ ↑
:desc - 参数的描述。:required - 参数是否是必需的。:optional - 参数是否是可选的。:type - 参数的类型,可以是 :string、:hash、:array、:numeric。:default - 此参数的默认值。它不能是必需的并且具有默认值。:banner - 在使用说明中显示的字符串。
错误¶ ↑
- ArgumentError
-
如果在非必需参数之后提供必需的参数,则会引发此错误。
# File bundler/vendor/thor/lib/thor/base.rb, line 261 def argument(name, options = {}) is_thor_reserved_word?(name, :argument) no_commands { attr_accessor name } required = if options.key?(:optional) !options[:optional] elsif options.key?(:required) options[:required] else options[:default].nil? end remove_argument name if required arguments.each do |argument| next if argument.required? raise ArgumentError, "You cannot have #{name.to_s.inspect} as required argument after " \ "the non-required argument #{argument.human_name.inspect}." end end options[:required] = required arguments << Bundler::Thor::Argument.new(name, options) end
如果希望在选项的默认值与类型不匹配时引发错误,请调用 check_default_type!。这将是默认行为;为了兼容性,如果需要,会发出弃用警告。
# File bundler/vendor/thor/lib/thor/base.rb, line 183 def check_default_type! @check_default_type = true end
如果希望为未知选项引发错误,请调用 check_unknown_options!。默认情况下禁用此功能,以允许动态调用。
# File bundler/vendor/thor/lib/thor/base.rb, line 168 def check_unknown_options! @check_unknown_options = true end
添加并声明选项组,该选项组要求块和参数中至少有一个选项。您可以将选项声明为块的外部。
示例¶ ↑
class_at_least_one do class_option :one class_option :two end
或
class_option :one class_option :two class_at_least_one :one, :two
如果未给出 “–one” 和 “–two”,则会引发 AtLeastOneRequiredArgumentError
。
可以同时使用 class_at_least_one
和 class_exclusive
。
class_exclusive do class_at_least_one do class_option :one class_option :two end end
然后,必须只提供 “–one” 或 “–two” 中的一个。
# File bundler/vendor/thor/lib/thor/base.rb, line 392 def class_at_least_one(*args, &block) register_options_relation_for(:class_options, :class_at_least_one_option_names, *args, &block) end
添加并声明选项组,该选项组用于块和参数中的互斥选项。您可以将选项声明为块的外部。
参数¶ ↑
示例¶ ↑
class_exclusive do class_option :one class_option :two end
或
class_option :one class_option :two class_exclusive :one, :two
如果同时给出 “–one” 和 “–two”,则会引发 ExclusiveArgumentsError。
# File bundler/vendor/thor/lib/thor/base.rb, line 357 def class_exclusive(*args, &block) register_options_relation_for(:class_options, :class_exclusive_option_names, *args, &block) end
向类选项集添加一个选项
参数¶ ↑
- name<Symbol>
-
参数的名称。
- options<Hash>
-
如下所述。
选项¶ ↑
- :desc
-
– 参数的描述。
- :required
-
– 参数是否是必需的。
- :default
-
– 此参数的默认值。
- :group
-
– 此选项的分组。由类选项使用以在不同级别输出选项。
- :aliases
-
– 此选项的别名。注意:Bundler::Thor 遵循一杠一字母选项的约定。因此,像 “-something” 这样的别名不会被解析;请改用 “--something” 或 “-s”。
- :type
-
– 参数的类型,可以是 :string、:hash、:array、:numeric 或 :boolean。
- :banner
-
– 在使用说明中显示的字符串。
- :hide
-
– 如果您想从帮助中隐藏此选项。
# File bundler/vendor/thor/lib/thor/base.rb, line 328 def class_option(name, options = {}) unless [ Symbol, String ].any? { |klass| name.is_a?(klass) } raise ArgumentError, "Expected a Symbol or String, got #{name.inspect}" end build_option(name, options, class_options) end
向类选项集添加一组选项。
class_options :foo => false, :bar => :required, :baz => :string
如果您喜欢更详细的声明,请查看 class_option。
参数¶ ↑
Hash[Symbol => Object]
# File bundler/vendor/thor/lib/thor/base.rb, line 306 def class_options(options = nil) @class_options ||= from_superclass(:class_options, {}) build_options(options, @class_options) if options @class_options end
返回此 Bundler::Thor 类的命令。
返回¶ ↑
- Hash
-
一个有序哈希,以命令名称为键,
Bundler::Thor::Command
对象为值。
# File bundler/vendor/thor/lib/thor/base.rb, line 471 def commands @commands ||= Hash.new end
如果发生任何错误,则使进程以状态 1 退出的标志。
# File bundler/vendor/thor/lib/thor/base.rb, line 628 def exit_on_failure? Bundler::Thor.deprecation_warning "Bundler::Thor exit with status 0 on errors. To keep this behavior, you must define `exit_on_failure?` in `#{self.name}`" false end
为 Bundler::Thor 或 Bundler::Thor::Group
类设置命名空间。默认情况下,命名空间从类名检索。如果您的 Bundler::Thor 类名为 Scripts::MyScript,则 help 方法(例如)将被称为
thor scripts:my_script -h
如果更改命名空间
namespace :my_scripts
您更改命令的调用方式
thor my_scripts -h
最后,如果您将命名空间更改为 default
namespace :default
您的命令可以使用快捷方式调用。而不是
thor :my_command
# File bundler/vendor/thor/lib/thor/base.rb, line 566 def namespace(name = nil) if name @namespace = name.to_s else @namespace ||= Bundler::Thor::Util.namespace_from_thor_class(self) end end
给定块内定义的所有方法都不会添加为命令。
因此您可以这样做
class MyScript < Bundler::Thor no_commands do def this_is_not_a_command end end end
您还可以添加该方法并将其从命令列表中删除
class MyScript < Bundler::Thor def this_is_not_a_command end remove_command :this_is_not_a_command end
# File bundler/vendor/thor/lib/thor/base.rb, line 530 def no_commands(&block) no_commands_context.enter(&block) end
# File bundler/vendor/thor/lib/thor/base.rb, line 540 def no_commands? no_commands_context.entered? end
# File bundler/vendor/thor/lib/thor/base.rb, line 536 def no_commands_context @no_commands_context ||= NestedContext.new end
允许在子类中使用父类中的私有方法作为命令。
参数¶ ↑
names<Array>:: Method names to be used as commands
示例¶ ↑
public_command :foo public_command :foo, :bar, :baz
# File bundler/vendor/thor/lib/thor/base.rb, line 606 def public_command(*names) names.each do |name| class_eval "def #{name}(*); super end", __FILE__, __LINE__ end end
删除先前定义的参数。如果给定 :undefine,则同时取消定义访问器。
参数¶ ↑
- names<Array>
-
要删除的参数
示例¶ ↑
remove_argument :foo remove_argument :foo, :bar, :baz, :undefine => true
# File bundler/vendor/thor/lib/thor/base.rb, line 426 def remove_argument(*names) options = names.last.is_a?(Hash) ? names.pop : {} names.each do |name| arguments.delete_if { |a| a.name == name.to_s } undef_method name, "#{name}=" if options[:undefine] end end
从此 Bundler::Thor 类中删除给定命令。如果您从另一个类继承并且不想再使用它,通常会这样做。
默认情况下,它只删除到命令的映射。但是,您可以提供 :undefine => true 来同时取消定义类中的方法。
参数¶ ↑
- name<Symbol|String>
-
要移除的命令的名称
- options<Hash>
-
如果希望从类中取消定义该方法,可以提供 :undefine => true。
# File bundler/vendor/thor/lib/thor/base.rb, line 500 def remove_command(*names) options = names.last.is_a?(Hash) ? names.pop : {} names.each do |name| commands.delete(name.to_s) all_commands.delete(name.to_s) undef_method name if options[:undefine] end end
从给定的 args 中解析命令和选项,实例化类并调用命令。当必须从数组中解析参数时,将使用此方法。如果您在 Ruby 中并且想要使用 Bundler::Thor 类,您可以简单地初始化它
script = MyScript.new(args, options, config) script.invoke(:command, first_arg, second_arg, third_arg)
# File bundler/vendor/thor/lib/thor/base.rb, line 582 def start(given_args = ARGV, config = {}) config[:shell] ||= Bundler::Thor::Base.shell.new dispatch(nil, given_args.dup, nil, config) rescue Bundler::Thor::Error => e config[:debug] || ENV["THOR_DEBUG"] == "1" ? (raise e) : config[:shell].error(e.message) exit(false) if exit_on_failure? rescue Errno::EPIPE # This happens if a thor command is piped to something like `head`, # which closes the pipe when it's done reading. This will also # mean that if the pipe is closed, further unnecessary # computation will not occur. exit(true) end
如果您只想要严格的字符串参数(在级联 thor 类时很有用),请调用 strict_args_position! 默认情况下禁用此功能,以允许动态调用。
# File bundler/vendor/thor/lib/thor/base.rb, line 214 def strict_args_position! @strict_args_position = true end
受保护的实例方法
调用 thor 类的程序的 basename。
# File bundler/vendor/thor/lib/thor/base.rb, line 771 def basename File.basename($PROGRAM_NAME).split(" ").first end
从超类检索值。如果到达基类,则返回 default。
# File bundler/vendor/thor/lib/thor/base.rb, line 749 def from_superclass(method, default = nil) if self == baseclass || !superclass.respond_to?(method, true) default else value = superclass.send(method) # Ruby implements `dup` on Object, but raises a `TypeError` # if the method is called on immediates. As a result, we # don't have a good way to check whether dup will succeed # without calling it and rescuing the TypeError. begin value.dup rescue TypeError value end end end
每次有人从 Bundler::Thor 类继承时,将 klass 和文件注册到基类中。
# File bundler/vendor/thor/lib/thor/base.rb, line 721 def inherited(klass) super(klass) Bundler::Thor::Base.register_klass_file(klass) klass.instance_variable_set(:@no_commands, 0) end
每当添加方法时,触发此回调。 通过调用 create_command 方法将添加的方法作为命令进行跟踪。
# File bundler/vendor/thor/lib/thor/base.rb, line 729 def method_added(meth) super(meth) meth = meth.to_s if meth == "initialize" initialize_added return end # Return if it's not a public instance method return unless public_method_defined?(meth.to_sym) return if no_commands? || !create_command(meth) is_thor_reserved_word?(meth, :command) Bundler::Thor::Base.register_klass_file(self) end
接收一组选项并打印它们。
# File bundler/vendor/thor/lib/thor/base.rb, line 656 def print_options(shell, options, group_name = nil) return if options.empty? list = [] padding = options.map { |o| o.aliases_for_usage.size }.max.to_i options.each do |option| next if option.hide item = [option.usage(padding)] item.push(option.description ? "# #{option.description}" : "") list << item list << ["", "# Default: #{option.print_default}"] if option.show_default? list << ["", "# Possible values: #{option.enum_to_s}"] if option.enum end shell.say(group_name ? "#{group_name} options:" : "Options:") shell.print_table(list, indent: 2) shell.say "" end