我有一个rake任务须要将值插入多个数据库。 git
我想从命令行或另外一个 rake任务将此值传递给rake任务。 github
我怎样才能作到这一点? 数据库
desc 'an updated version' task :task_name, [:arg1, :arg2] => [:dependency1, :dependency2] do |t, args| puts args[:arg1] end
我在rake文件中使用常规ruby参数: 数组
DB = ARGV[1]
而后我将文件底部的rake任务存根(由于rake将根据该参数名称查找任务)。 ruby
task :database_name1 task :database_name2
命令行: 工具
rake mytask db_name
这对我来讲比var = foo ENV var和任务args [blah,blah2]解决方案感受更干净。
若是您只有一些一次性设置的环境,那么存根有点粗糙,但也不会太糟糕 ui
若是你想传递命名参数(例如使用标准的OptionParser
),你可使用这样的东西: spa
$ rake user:create -- --user test@example.com --pass 123
注意--
,这是绕过标准Rake参数所必需的。 应该使用Rake 0.9.x , <= 10.3.x。 命令行
较新的Rake改变了它的解析--
如今你必须确保它没有传递给OptionParser#parse
方法,例如使用parser.parse!(ARGV[2..-1])
code
require 'rake' require 'optparse' # Rake task for creating an account namespace :user do |args| desc 'Creates user account with given credentials: rake user:create' # environment is required to have access to Rails models task :create do options = {} OptionParser.new(args) do |opts| opts.banner = "Usage: rake user:create [options]" opts.on("-u", "--user {username}","User's email address", String) do |user| options[:user] = user end opts.on("-p", "--pass {password}","User's password", String) do |pass| options[:pass] = pass end end.parse! puts "creating user account..." u = Hash.new u[:email] = options[:user] u[:password] = options[:pass] # with some DB layer like ActiveRecord: # user = User.new(u); user.save! puts "user: " + u.to_s puts "account created." exit 0 end end
exit
将确保额外的参数不会被解释为Rake任务。
参数的快捷方式也应该有效:
rake user:create -- -u test@example.com -p 123
当rake脚本看起来像这样时,也许是时候寻找另外一个容许这个开箱即用的工具了。
要将参数传递给默认任务,您能够执行相似的操做。 例如,说“版本”是你的参数:
task :default, [:version] => [:build] task :build, :version do |t,args| version = args[:version] puts version ? "version is #{version}" : "no version passed" end
而后你能够像这样调用它:
$ rake no version passed
要么
$ rake default[3.2.1] version is 3.2.1
要么
$ rake build[3.2.1] version is 3.2.1
可是,我没有找到一种方法来避免在传入参数时指定任务名称(默认或构建)。 若是有人知道某种方式,我很乐意听到。
我喜欢参数传递的“查询字符串”语法,特别是当有不少参数要传递时。
例:
rake "mytask[width=10&height=20]"
“querystring”是:
width=10&height=20
警告:请注意语法是rake "mytask[foo=bar]"
而不是 rake mytask["foo=bar"]
使用Rack::Utils.parse_nested_query
在rake任务中解析时,咱们获得一个Hash
:
=> {"width"=>"10", "height"=>"20"}
(很酷的是你能够传递哈希和数组,下面更多)
这是如何实现这个目标的:
require 'rack/utils' task :mytask, :args_expr do |t,args| args.with_defaults(:args_expr => "width=10&height=10") options = Rack::Utils.parse_nested_query(args[:args_expr]) end
这是我在delayed_job_active_record_threaded gem中使用Rails的更加扩展的示例:
bundle exec rake "dj:start[ebooks[workers_number]=16&ebooks[worker_timeout]=60&albums[workers_number]=32&albums[worker_timeout]=120]"
以与上面相同的方式解析,具备环境依赖性(为了加载Rails环境)
namespace :dj do task :start, [ :args_expr ] => :environment do |t, args| # defaults here... options = Rack::Utils.parse_nested_query(args[:args_expr]) end end
在options
给出如下内容
=> {"ebooks"=>{"workers_number"=>"16", "worker_timeout"=>"60"}, "albums"=>{"workers_number"=>"32", "worker_timeout"=>"120"}}