class Gem::Command
所有 Gem
命令的基类。当创建新的 gem 命令时,请定义 initialize,execute
,arguments
,defaults_str
,description
和 usage
(如适用)。有关详细信息,请参阅上述方法。
一个很好的例子是 Gem::Commands::ContentsCommand
属性
命令的名称。
命令的默认选项。
命令的选项。
用于命令行调用的命令名称。
命令的简短描述。
公共类方法
# File rubygems/command.rb, line 65 def self.add_common_option(*args, &handler) Gem::Command.common_options << [args, handler] end
为给定命令添加额外的参数列表。args
可以是一个数组或一个字符串,该字符串将按空格拆分。
# File rubygems/command.rb, line 94 def self.add_specific_extra_args(cmd,args) args = args.split(/\s+/) if args.is_a? String specific_extra_args_hash[cmd] = args end
构建 gem 时使用的参数
# File rubygems/command.rb, line 53 def self.build_args @build_args ||= [] end
# File rubygems/command.rb, line 57 def self.build_args=(value) @build_args = value end
# File rubygems/command.rb, line 61 def self.common_options @common_options ||= [] end
# File rubygems/command.rb, line 69 def self.extra_args @extra_args ||= [] end
# File rubygems/command.rb, line 73 def self.extra_args=(value) case value when Array @extra_args = value when String @extra_args = value.split(" ") end end
初始化一个名为 command
的通用 gem 命令。summary
是在“gem help commands”中显示的简短描述。defaults
是默认选项。除非没有默认选项,否则默认选项应在 defaults_str
中镜像。
在定义新的命令子类时,请使用 add_option
添加命令行开关。
未处理的参数(gem 名称、文件等)将保留在 options[:args]
中。
# File rubygems/command.rb, line 120 def initialize(command, summary=nil, defaults={}) @command = command @summary = summary @program_name = "gem #{command}" @defaults = defaults @options = defaults.dup @option_groups = Hash.new {|h,k| h[k] = [] } @deprecated_options = { command => {} } @parser = nil @when_invoked = nil end
返回命令的额外参数数组。额外的参数来自程序启动时读取的 gem 配置文件。
# File rubygems/command.rb, line 86 def self.specific_extra_args(cmd) specific_extra_args_hash[cmd] end
特定额外参数哈希的访问器(自初始化)。
# File rubygems/command.rb, line 102 def self.specific_extra_args_hash @specific_extra_args_hash ||= Hash.new do |h,k| h[k] = Array.new end end
公共实例方法
从 ~/.gemrc 添加额外参数
# File rubygems/command.rb, line 451 def add_extra_args(args) result = [] s_extra = Gem::Command.specific_extra_args(@command) extra = Gem::Command.extra_args + s_extra until extra.empty? do ex = [] ex << extra.shift ex << extra.shift if /^[^-]/.match?(extra.first.to_s) result << ex if handles?(ex) end result.flatten! result.concat(args) result end
为命令添加命令行选项和处理程序。
有关 opts
的说明,请参阅 Gem::OptionParser#make_switch
。
将使用两个值调用 handler
,即参数的值和选项哈希。
如果 add_option
的第一个参数是 Symbol,则用于在输出中对选项进行分组。有关示例,请参阅“gem help list”。
# File rubygems/command.rb, line 358 def add_option(*opts, &handler) # :yields: value, options group_name = Symbol === opts.first ? opts.shift : :options raise "Do not pass an empty string in opts" if opts.include?("") @option_groups[group_name] << [opts, handler] end
覆盖以提供命令所接受的参数的详细信息。它应返回一个左对齐的字符串,每行一个参数。
例如
def usage "#{program_name} FILE [FILE ...]" end def arguments "FILE name of file to find" end
# File rubygems/command.rb, line 258 def arguments "" end
如果 long
以 short
中的字符开头,则为 True。
# File rubygems/command.rb, line 135 def begins?(long, short) return false if short.nil? long[0, short.length] == short end
# File rubygems/command.rb, line 397 def check_deprecated_options(options) options.each do |option| next unless option_is_deprecated?(option) deprecation = @deprecated_options[command][option] version_to_expire = deprecation["rg_version_to_expire"] deprecate_option_msg = if version_to_expire "The \"#{option}\" option has been deprecated and will be removed in Rubygems #{version_to_expire}." else "The \"#{option}\" option has been deprecated and will be removed in future versions of Rubygems." end extra_msg = deprecation["extra_msg"] deprecate_option_msg += " #{extra_msg}" if extra_msg alert_warning(deprecate_option_msg) end end
覆盖以显示命令选项的默认值。(类似于 arguments
,但显示默认值)。
例如
def defaults_str --no-gems-first --no-all end
# File rubygems/command.rb, line 272 def defaults_str "" end
将命令行选项标记为已弃用,并可选择指定弃用期限。
请注意,在当前实现中,选项的每个版本都需要显式弃用,因此要弃用定义为
add_option('-t', '--[no-]test', 'Set test mode') do |value, options| # ... stuff ... end
的选项,您需要为要弃用的每个选项版本显式添加对“deprecate_option”的调用,如
deprecate_option('-t') deprecate_option('--test') deprecate_option('--no-test')
# File rubygems/command.rb, line 393 def deprecate_option(name, version: nil, extra_msg: nil) @deprecated_options[command].merge!({ name => { "rg_version_to_expire" => version, "extra_msg" => extra_msg } }) end
# File rubygems/command.rb, line 469 def deprecated? false end
覆盖以显示有关此命令作用的更长描述。
# File rubygems/command.rb, line 279 def description nil end
覆盖以提供命令处理。
options
将填充您解析的选项,未解析的选项将保留在 options[:args]
中。
另请参阅:get_all_gem_names
,get_one_gem_name
,get_one_optional_argument
# File rubygems/command.rb, line 149 def execute raise Gem::Exception, "generic command has no actions" end
从命令行获取所有 gem 名称。
# File rubygems/command.rb, line 185 def get_all_gem_names args = options[:args] if args.nil? || args.empty? raise Gem::CommandLineError, "Please specify at least one gem name (e.g. gem build GEMNAME)" end args.reject {|arg| arg.start_with?("-") } end
从命令行获取所有 [gem,版本]。
形式为 gem:ver 的参数将分别分解为 gen 名称和版本。
# File rubygems/command.rb, line 201 def get_all_gem_names_and_versions get_all_gem_names.map do |name| extract_gem_name_and_version(name) end end
从命令行获取单个 gem 名称。如果不存在 gem 名称或给出了多个 gem 名称,则会失败。
# File rubygems/command.rb, line 219 def get_one_gem_name args = options[:args] if args.nil? || args.empty? raise Gem::CommandLineError, "Please specify a gem name on the command line (e.g. gem build GEMNAME)" end if args.size > 1 raise Gem::CommandLineError, "Too many gem names (#{args.join(", ")}); please specify only one" end args.first end
从命令行获取单个可选参数。如果给出了多个参数,则仅返回第一个。如果没有给出任何参数,则返回 nil。
# File rubygems/command.rb, line 239 def get_one_optional_argument args = options[:args] || [] args.first end
通过解析给定参数列表并记录结果来处理该列表。
# File rubygems/command.rb, line 440 def handle_options(args) args = add_extra_args(args) check_deprecated_options(args) @options = Marshal.load Marshal.dump @defaults # deep copy parser.parse!(args) @options[:args] = args end
如果命令处理给定的参数列表,则为 True。
# File rubygems/command.rb, line 429 def handles?(args) parser.parse!(args.dup) true rescue StandardError false end
使用给定的参数列表调用命令。
# File rubygems/command.rb, line 303 def invoke(*args) invoke_with_build_args args, nil end
使用给定的普通参数列表和额外的构建参数调用命令。
# File rubygems/command.rb, line 311 def invoke_with_build_args(args, build_args) handle_options args options[:build_args] = build_args if options[:silent] old_ui = ui self.ui = ui = Gem::SilentUI.new end if options[:help] show_help elsif @when_invoked @when_invoked.call options else execute end ensure if ui self.ui = old_ui ui.close end end
将一组命令选项与一组默认选项合并(而不修改默认选项哈希)。
# File rubygems/command.rb, line 421 def merge_options(new_options) @options = @defaults.clone new_options.each {|k,v| @options[k] = v } end
删除先前定义的命令行参数 name
。
# File rubygems/command.rb, line 369 def remove_option(name) @option_groups.each do |_, option_list| option_list.reject! {|args, _| args.any? {|x| x.is_a?(String) && x =~ /^#{name}/ } } end end
显示命令的帮助消息。
# File rubygems/command.rb, line 295 def show_help parser.program_name = usage say parser end
向用户显示找不到 gem 以及原因
# File rubygems/command.rb, line 157 def show_lookup_failure(gem_name, version, errors, suppress_suggestions = false, required_by = nil) gem = "'#{gem_name}' (#{version})" msg = String.new "Could not find a valid gem #{gem}" if errors && !errors.empty? msg << ", here is why:\n" errors.each {|x| msg << " #{x.wordy}\n" } else if required_by && gem != required_by msg << " (required by #{required_by}) in any repository" else msg << " in any repository" end end alert_error msg unless suppress_suggestions suggestions = Gem::SpecFetcher.fetcher.suggest_gems_from_name(gem_name, :latest, 10) unless suggestions.empty? alert_error "Possible alternatives: #{suggestions.join(", ")}" end end end
覆盖以显示单个 gem 命令的用法。
文本“[选项]”会自动附加到用法文本中。
# File rubygems/command.rb, line 288 def usage program_name end
调用时调用给定的代码块。
正常的命令调用只是执行命令的 execute
方法。指定调用代码块允许测试方法覆盖命令的正常操作,以确定它是否已正确调用。
# File rubygems/command.rb, line 343 def when_invoked(&block) @when_invoked = block end
私有实例方法
向解析器帮助视图添加带有 title
和 content
的部分。用于添加命令参数和默认参数。
# File rubygems/command.rb, line 510 def add_parser_run_info(title, content) return if content.empty? @parser.separator nil @parser.separator " #{title}:" content.each_line do |line| @parser.separator " #{line.rstrip}" end end
# File rubygems/command.rb, line 556 def configure_options(header, option_list) return if option_list.nil? || option_list.empty? header = header.to_s.empty? ? "" : "#{header} " @parser.separator " #{header}Options:" option_list.each do |args, handler| @parser.on(*args) do |value| handler.call(value, @options) end end @parser.separator "" end
创建一个选项解析器,并使用命令的帮助信息填充它。
# File rubygems/command.rb, line 542 def create_option_parser @parser = Gem::OptionParser.new add_parser_options @parser.separator nil configure_options "Common", Gem::Command.common_options add_parser_run_info "Arguments", arguments add_parser_summary add_parser_description add_parser_run_info "Defaults", defaults_str end
# File rubygems/command.rb, line 475 def option_is_deprecated?(option) @deprecated_options[command].key?(option) end
按需创建解析器。
# File rubygems/command.rb, line 533 def parser create_option_parser if @parser.nil? @parser end
将 text
换行到 width
# File rubygems/command.rb, line 574 def wrap(text, width) # :doc: text.gsub(/(.{1,#{width}})( +|$\n?)|(.{1,#{width}})/, "\\1\\3\n") end