如果你不记得要记住什么参数位置是什么,你想做什么像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
在传递参数时,最好选择输入文件,这可以是一个excel json或者你需要的任何东西,并从那里读取你需要的数据结构和变量,包括变量名称,因为需要。 读取文件可以具有以下结构。
namespace :name_sapace_task do desc "Description task...." task :name_task => :environment do data = ActiveSupport::JSON.decode(File.read(Rails.root+"public/file.json")) if defined?(data) # and work whit yoour data, example is data["user_id"] end end
{ "name_task": "I'm a task", "user_id": 389, "users_assigned": [389,672,524], "task_id": 3 }
rake :name_task
上面描述的大多数方法都不适用于我,也许它们在较新版本中已被弃用。 最新的指南可以在这里找到: http://guides.rubyonrails.org/command_line.html#custom-rake-tasks
指南中的复制粘贴文件位于:
task :task_name, [:arg_1] => [:pre_1, :pre_2] do |t, args| # You can use args from here end
像这样调用它
bin/rake "task_name[value 1]" # entire argument string should be quoted
您可以通过向任务调用添加符号参数来在rake中指定正式参数。例如:
require 'rake' task :my_task, [:arg1, :arg2] do |t, args| puts "Args were: #{args}" 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,2] Args were: {:arg1=>"1", :arg2=>"2"} > 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 。
task :t1 => "dep[1,2]"
:invoke_my_task
:invoke_my_task_2
请注意,某些shell(如zsh)要求您转义括号: rake my_task\['arg1'\]
rake my_task\['arg1'\]
我无法弄清楚如何传递args以及:环境,直到我解决了这个问题:
namespace :db do desc 'Export product data' task :export, [:file_token, :file_path] => :environment do |t, args| args.with_defaults(:file_token => "products", :file_path => "./lib/data/") #do stuff [...] end end
然后我这样打电话:
rake db:export['foo, /tmp/']
desc 'an updated version' task :task_name, [:arg1, :arg2] => [:dependency1, :dependency2] do |t, args| puts args[:arg1] end
使用传统参数样式运行rake任务:
rake task arg1 arg2
然后使用:
task :task do |_, args| puts "This is argument 1: #{args.first}" end
添加以下rake gem补丁:
Rake::Application.class_eval do alias origin_top_level top_level def top_level @top_level_tasks = [top_level_tasks.join(' ')] origin_top_level end def parse_task_string(string) # :nodoc: parts = string.split ' ' return parts.shift, parts end end Rake::Task.class_eval do def invoke(*args) invoke_with_call_chain(args, Rake::InvocationChain::EMPTY) end end
我在rake文件中使用常规ruby参数:
DB = ARGV[1]
然后我将文件底部的rake任务存根(因为rake将根据该参数名称查找任务)。
task :database_name1 task :database_name2
命令行:
rake mytask db_name
这对我来说比var = foo ENV var和任务args [blah,blah2]解决方案感觉更干净。 如果您只有一些一次性设置的环境,那么存根有点粗糙,但也不会太糟糕
我喜欢参数传递的“查询字符串”语法,特别是当有很多参数要传递时。
例:
rake "mytask[width=10&height=20]"
“querystring”是:
width=10&height=20
的 警告: 强> 请注意语法是 rake "mytask[foo=bar]" 和 的 不 强> rake mytask["foo=bar"]
rake "mytask[foo=bar]"
rake mytask["foo=bar"]
使用时在rake任务中解析 Rack::Utils.parse_nested_query ,我们得到一个 Hash :
Rack::Utils.parse_nested_query
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
这是一个更广泛的例子,我在我的Rails中使用Rails delayed_job_active_record_threaded 宝石:
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
options
=> {"ebooks"=>{"workers_number"=>"16", "worker_timeout"=>"60"}, "albums"=>{"workers_number"=>"32", "worker_timeout"=>"120"}}
要将参数传递给默认任务,您可以执行类似的操作。例如,说 “版本”是你的论点:
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
但是,我没有找到一种方法来避免在传入参数时指定任务名称(默认或构建)。如果有人知道某种方式,我很乐意听到。
我从这两个网站找到了答案: 净疯子 和 Aimred 。
你需要有版本&gt; 0.8耙使用这种技术
正常的rake任务描述如下:
desc 'Task Description' task :task_name => [:depends_on_taskA, :depends_on_taskB] do #interesting things end
要传递参数,请执行以下三项操作:
要访问脚本中的参数,请使用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
实际上@Nick Desjardins回答得很完美。但仅限于教育:你可以使用肮脏的方法:使用 ENV 争论
ENV
task :my_task do myvar = ENV['myvar'] puts "myvar: #{myvar}" end rake my_task myvar=10 #=> myvar: 10
另一个常用选项是传递环境变量。在您的代码中,您可以通过它阅读 ENV['VAR'] ,并且可以在它之前传递它们 rake 命令,就像
ENV['VAR']
rake
$ VAR=foo rake mytask