我有一個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"}}