如何將命令行參數傳遞給rake任務

我有一個rake任務須要將值插入多個數據庫。 git

我想從命令行或另外一個 rake任務將此值傳遞給rake任務。 github

我怎樣才能作到這一點? 數據庫


#1樓

desc 'an updated version'
task :task_name, [:arg1, :arg2] => [:dependency1, :dependency2] do |t, args|
    puts args[:arg1]
end

#2樓

我在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


#3樓

若是你想傳遞命名參數(例如使用標準的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腳本看起來像這樣時,也許是時候尋找另外一個容許這個開箱即用的工具了。


#4樓

要將參數傳遞給默認任務,您能夠執行相似的操做。 例如,說「版本」是你的參數:

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

可是,我沒有找到一種方法來避免在傳入參數時指定任務名稱(默認或構建)。 若是有人知道某種方式,我很樂意聽到。


#5樓

我喜歡參數傳遞的「查詢字符串」語法,特別是當有不少參數要傳遞時。

例:

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"}}
相關文章
相關標籤/搜索