我有一个rake任务,需要将一个值插入多个数据库。
我想从命令行或从另一个rake任务中将这个值传递给rake任务。
我该怎么做呢?
我有一个rake任务,需要将一个值插入多个数据库。
我想从命令行或从另一个rake任务中将这个值传递给rake任务。
我该怎么做呢?
当前回答
我喜欢参数传递的“querystring”语法,特别是当有很多参数要传递时。
例子:
rake "mytask[width=10&height=20]"
“querystring”是:
width=10&height=20
警告:注意语法是rake“mytask[foo=bar]”而不是rake mytask["foo=bar"]
当在rake任务中使用Rack::Utils进行解析时。parse_nested_query,得到一个哈希值:
=> {"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_threading gem中使用的一个更扩展的示例:
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
给出以下选项
=> {"ebooks"=>{"workers_number"=>"16", "worker_timeout"=>"60"}, "albums"=>{"workers_number"=>"32", "worker_timeout"=>"120"}}
其他回答
要将参数传递给默认任务,可以这样做。例如,说 "version"是你的论点:
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
or
$ rake default[3.2.1]
version is 3.2.1
or
$ rake build[3.2.1]
version is 3.2.1
但是,我还没有找到一种方法来避免在传递参数时指定任务名称(默认或构建)。如果有人知道办法,我很乐意听听。
desc 'an updated version'
task :task_name, [:arg1, :arg2] => [:dependency1, :dependency2] do |t, args|
puts args[:arg1]
end
通过向任务调用中添加符号参数,可以在rake中指定正式参数。例如:
require 'rake'
task :my_task, [:arg1, :arg2] do |t, args|
puts "Args were: #{args} of class #{args.class}"
puts "arg1 was: '#{args[:arg1]}' of class #{args[:arg1].class}"
puts "arg2 was: '#{args[:arg2]}' of class #{args[:arg2].class}"
end
task :invoke_my_task do
Rake.application.invoke_task("my_task[1, 2]")
end
# or if you prefer this syntax...
task :invoke_my_task_2 do
Rake::Task[:my_task].invoke(3, 4)
end
# a task with prerequisites passes its
# arguments to it prerequisites
task :with_prerequisite, [:arg1, :arg2] => :my_task #<- name of prerequisite task
# to specify default values,
# we take advantage of args being a Rake::TaskArguments object
task :with_defaults, :arg1, :arg2 do |t, args|
args.with_defaults(:arg1 => :default_1, :arg2 => :default_2)
puts "Args with defaults were: #{args}"
end
然后,从命令行:
> rake my_task[1,false] Args were: {:arg1=>"1", :arg2=>"false"} of class Rake::TaskArguments arg1 was: '1' of class String arg2 was: 'false' of class String > rake "my_task[1, 2]" Args were: {:arg1=>"1", :arg2=>"2"} > rake invoke_my_task Args were: {:arg1=>"1", :arg2=>"2"} > rake invoke_my_task_2 Args were: {:arg1=>3, :arg2=>4} > rake with_prerequisite[5,6] Args were: {:arg1=>"5", :arg2=>"6"} > rake with_defaults Args with defaults were: {:arg1=>:default_1, :arg2=>:default_2} > rake with_defaults['x','y'] Args with defaults were: {:arg1=>"x", :arg2=>"y"}
正如第二个示例中所演示的,如果您想使用空格,则需要在目标名称周围加上引号,以防止shell在空格处分隔参数。
查看rake中的代码。Rb, rake似乎没有解析任务字符串来提取先决条件的参数,因此不能执行task:t1 => "dep[1,2]"。为先决条件指定不同参数的唯一方法是在依赖任务操作中显式地调用它,如:invoke_my_task和:invoke_my_task_2。
注意,一些shell(如zsh)需要转义括号:
我在这两个网站上找到了答案:Net Maniac和Aimred。
您需要拥有版本> 0.8的rake才能使用这种技术
正常的rake任务描述如下:
desc 'Task Description'
task :task_name => [:depends_on_taskA, :depends_on_taskB] do
#interesting things
end
要传递参数,需要做三件事:
在任务名称之后添加参数名称,以逗号分隔。 将依赖项放在最后,使用:needs =>[…] 把|t, args|放在do后面。(t为本次任务的对象)
要访问脚本中的参数,请使用args.arg_name
desc 'Takes arguments task'
task :task_name, :display_value, :display_times, :needs => [:depends_on_taskA, :depends_on_taskB] do |t, args|
args.display_times.to_i.times do
puts args.display_value
end
end
要从命令行调用此任务,请将[]s中的参数传递给它
rake task_name['Hello',4]
将输出
Hello
Hello
Hello
Hello
如果你想从另一个任务调用这个任务,并给它传递参数,使用invoke
task :caller do
puts 'In Caller'
Rake::Task[:task_name].invoke('hi',2)
end
然后命令
rake caller
将输出
In Caller
hi
hi
我还没有找到一种方法来传递参数作为依赖的一部分,如下代码中断:
task :caller => :task_name['hi',2]' do
puts 'In Caller'
end
如果你懒得记参数位置是什么你想做一些类似ruby参数哈希的东西。您可以使用一个参数传入一个字符串,然后将该字符串正则化为一个选项散列。
namespace :dummy_data do
desc "Tests options hash like arguments"
task :test, [:options] => :environment do |t, args|
arg_options = args[:options] || '' # nil catch incase no options are provided
two_d_array = arg_options.scan(/\W*(\w*): (\w*)\W*/)
puts two_d_array.to_s + ' # options are regexed into a 2d array'
string_key_hash = two_d_array.to_h
puts string_key_hash.to_s + ' # options are in a hash with keys as strings'
options = two_d_array.map {|p| [p[0].to_sym, p[1]]}.to_h
puts options.to_s + ' # options are in a hash with symbols'
default_options = {users: '50', friends: '25', colour: 'red', name: 'tom'}
options = default_options.merge(options)
puts options.to_s + ' # default option values are merged into options'
end
end
在命令行中。
$ rake dummy_data:test["users: 100 friends: 50 colour: red"]
[["users", "100"], ["friends", "50"], ["colour", "red"]] # options are regexed into a 2d array
{"users"=>"100", "friends"=>"50", "colour"=>"red"} # options are in a hash with keys as strings
{:users=>"100", :friends=>"50", :colour=>"red"} # options are in a hash with symbols
{:users=>"100", :friends=>"50", :colour=>"red", :name=>"tom"} # default option values are merged into options