通过Rubygems的插件,定制自己的RubyGems命令
或者,你也想了解
如何创建自己的Gem包
正文:
最近RubyGems的1.3.2的版本,发布了一个热点功能,支持自己定制的Gems命令。本文将就一个例子,说明如何使用Rubygems的插件,生成自己的Gems命令。
下面是创建Gems定制命令的主要步骤:
1. 创建 rubygems_plugin.rb
2. 注册你的命令
3. 生成命令文件
4. 定制命令描述
步骤 1: 创建 rubygems_plugin.rb
在现有的gem包源文件,或者新建的gem源文件目录下创建lib/rubygems_plugin.rb。可以参考graph的命令生成。
步骤 2: 注册你的命令
在你创建的rubygems_plugin.rb文件中,你要注册你的命令,还需要加载:
require Gem::CommandManager
实际的rubygems_plugin.rb文件可能如下:
require 'rubygems/command_manager'
# dependencies specific to my command
require 'rubygems/commands/query_command'
require 'rubygems/super_search'
require 'hirb'
Gem::CommandManager.instance.register_command :grep
步骤3. 生成命令文件
为了让RubyGems自动的加载你的命令,你需要把你的命令文件放到lib/rubygems/commands/文件目录下。并且要依照Camel Case的命名方式,映射你的命令文件名。例如,对于上面的Gem::Commands::GrepCommand命令,则需要创建如下文件lib/rubygems/commands/grep_command.rb。 当然,如果,你不愿意分开文件,你也可以把你的命令代码写到rubygems_plugin.rb里。
步骤4. 定制命令描述
下面举例说明命令定制如何写,比如,我们希望生成如下命令: new, execute, arguments, defaults_str, description and usage.
new()
在这个命令对应的描述类中,我们需要定义命令的名称,提示和参数选项,具体命令可以如下:
class Gem::Commands::GrepCommand < Gem::Commands::QueryCommand
def initialize
super 'grep', "Enhances search command by providing extra search options and displaying results as a table"
defaults.merge!(:columns=>[:name,:summary,:author])
add_option('-c', '--columns STRING', 'Gemspec columns/attributes to display per gem') do |value, options|
options[:columns] = value.split(/\s*,\s*/).map {|e|
self.class.valid_gemspec_columns.detect {|c| c =~ /^#{e}/ }
}.compact.map {|e| e.to_sym}
end
add_option('-f', '--fields STRING', 'Gemspec fields/attributes to search (only for local gems)') do |value, options|
options[:fields] = value.split(/\s*,\s*/).map {|e|
self.class.valid_gemspec_columns.detect {|c| c =~ /^#{e}/ }
}.compact
end
remove_option '--name-matches'
remove_option '-d'
remove_option '--versions'
end
说明一下:
* 通常情况下我们创建命令多是Gem::Command的子类。例子中继承Gem::Commands::QueryCommand是因为,这个方法本身是query类型。
* 使用super()来定义命令名称,提示信息和默认参数。但这个例子由于没有使用默认的父类所以,需要自己定制这些信息。
* add_option 和 remove_option 用来添加和删除命令参数。它们用OptionParser定义参数。
execute()
命令的功能部分通常在这里完成,但在这个例子中execute()并没有太多的逻辑,因为通过delegates在别的地方声明了。
def execute
string = get_one_optional_argument
options[:name] = /#{string}/i
Gem.source_index.extend Gem::SuperSearch
super
end
arguments(), defaults_str(), description() and usage()
这些部分是可选的,用来描述命令的help等信息。下面是针对说明:
* arguments(): 命令参数
* defaults_str(): 用来指定默认参数.
* description: 用来指定命令的详细说明
* usage(): 描述命令的顺序.
例如
:
def arguments # :nodoc:
"REGEXP regular expression string to search specified gemspec attributes"
end
def usage # :nodoc:
"#{program_name} [REGEXP]"
end
def defaults_str # :nodoc:
"--local --columns name,summary,author --fields name --no-installed"
end
def description # :nodoc:
'Enhances search command by providing options to search (--fields) and display (--columns) ' +
'gemspec attributes. Results are displayed in an ascii table. Gemspec attributes can be specified '+
'by the first unique string that it starts with i.e. "su" for "summary". To specify multiple gemspec attributes, delimit ' +
"them with commas. Gemspec attributes available to options are: #{self.class.valid_gemspec_columns.join(', ')}."
end