複数のデータベースに値を挿入する必要があるレーキタスクがあります。
この値をコマンドラインまたは別の RakeタスクからRakeタスクに渡したいのですが。
これどうやってするの?
複数のデータベースに値を挿入する必要があるレーキタスクがあります。
この値をコマンドラインまたは別の RakeタスクからRakeタスクに渡したいのですが。
これどうやってするの?
回答:
オプションと依存関係は配列内にある必要があります:
namespace :thing do
desc "it does a thing"
task :work, [:option, :foo, :bar] do |task, args|
puts "work", args
end
task :another, [:option, :foo, :bar] do |task, args|
puts "another #{args}"
Rake::Task["thing:work"].invoke(args[:option], args[:foo], args[:bar])
# or splat the args
# Rake::Task["thing:work"].invoke(*args)
end
end
その後
rake thing:work[1,2,3]
=> work: {:option=>"1", :foo=>"2", :bar=>"3"}
rake thing:another[1,2,3]
=> another {:option=>"1", :foo=>"2", :bar=>"3"}
=> work: {:option=>"1", :foo=>"2", :bar=>"3"}
注:変数
task
はタスクオブジェクトであり、Rakeの内部について知っている/気にしない限り、あまり役に立ちません。
レールノート:
Railsからタスクを実行する場合
=> [:environment]
は、依存するタスクをセットアップする方法を追加して、環境をプリロードするのが最善です。
task :work, [:option, :foo, :bar] => [:environment] do |task, args|
puts "work", args
end
rake thing:work[1, 2, 3]
機能しないため、エラーが発生しますDon't know how to build task
rake thing:work'[1,2,3]'
rake thing:work\[1,2,3\]
またはこれrake 'thing:work[1,2,3]'
:environment
タスクからシンボルを削除できます。railsアプリケーションには:environmentタスクがあります...
t
意味することを説明するメモを持つ代わりにtask
、なぜ単にtask
パラメータ名として使用しないのですか?
タスク呼び出しにシンボル引数を追加することにより、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
次に、コマンドラインから:
>レーキmy_task [1、false] 引数は次のとおりです:クラスRake :: TaskArgumentsの{:arg1 => "1"、:arg2 => "false"} arg1は次のとおりです:クラスStringの '1' arg2は次のとおりでした:Stringクラスの 'false' >レーキ "my_task [1、2]" 引数は次のとおりです:{:arg1 => "1"、:arg2 => "2"} > rake invoke_my_task 引数は次のとおりです:{:arg1 => "1"、:arg2 => "2"} >レーキinvoke_my_task_2 引数は次のとおりです:{:arg1 => 3、:arg2 => 4} >レーキwith_prerequisite [5,6] 引数は次のとおりです:{:arg1 => "5"、:arg2 => "6"} > rake with_defaults デフォルトの引数は次のとおりです:{:arg1 =>:default_1、:arg2 =>:default_2} > rake with_defaults ['x'、 'y'] デフォルトの引数は次のとおりです:{:arg1 => "x"、:arg2 => "y"}
2番目の例で示したように、スペースを使用する場合、シェルがスペースで引数を分割しないようにするには、ターゲット名を引用符で囲む必要があります。
rake.rbのコードを見ると、rakeがタスク文字列を解析して前提条件の引数を抽出していないように見えるため、実行できませんtask :t1 => "dep[1,2]"
。前提条件に異なる引数を指定する唯一の方法は、:invoke_my_task
およびのように、依存するタスクアクション内で明示的に呼び出すこと:invoke_my_task_2
です。
一部のシェル(zshなど)では、大括弧をエスケープする必要があることに注意してください。 rake my_task\['arg1'\]
WARNING: 'task :t, arg, :needs => [deps]' is deprecated. Please use 'task :t, [args] => [deps]' instead.
zsh: no matches found: ...
)。そのため、括弧をエスケープする必要があります:rake my_task\['arg1'\]
。robots.thoughtbot.com/post/18129303042/…
kchによる回答に加えて(コメントを残す方法が見つかりませんでした。申し訳ありません):
コマンドのENV
前に変数として変数を指定する必要はありませんrake
。あなたはそれらをそのような通常のコマンドラインパラメータとして設定することができます:
rake mytask var=foo
次のようなENV変数として、rakeファイルからそれらにアクセスします。
p ENV['var'] # => "foo"
p
意味ですか?
名前付き引数を渡したい場合(たとえば、標準OptionParser
)、次のようなものを使用できます。
$ 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])
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スクリプトがこのようになったら、たぶん、これをすぐに使える別のツールを探す時がきました。
--option-names
。私の唯一の提案は使用することですexit
ではなくabort
としてabort
シェルに1のリターンコードであなたを残します。レーキタスクが高レベルのスクリプトの一部である場合、ゼロ以外の出口が何らかのエラーであると想定するのがより一般的です。
--
か?rake
実際のタスクまたは何かに引数を渡すようなものですか?同様task :my_task, :*args do |t, args|
か何か?
{username}
。どこで使用されていますか?なぜそこにないの-u {username}
ですか?乾杯
私は、Net ManiacとAimredの 2つのWebサイトから答えを見つけました。
この手法を使用するには、バージョン> 0.8のレーキが必要です。
通常のレーキタスクの説明は次のとおりです。
desc 'Task Description'
task :task_name => [:depends_on_taskA, :depends_on_taskB] do
#interesting things
end
引数を渡すには、次の3つのことを行います。
スクリプトの引数にアクセスするには、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
'task :t, arg, :needs => [deps]' is deprecated. Please use 'task :t, [args] => [deps]' instead.
別の一般的に使用されるオプションは、環境変数を渡すことです。あなたのコードではENV['VAR']
、を介してそれらを読み取り、rake
次のようにコマンドの直前にそれらを渡すことができます
$ VAR=foo rake mytask
rake blah -- --these --go --to --a-program
(注意--
、参照そのスイッチが終了したことをレーキを伝えるために)stackoverflow.com/questions/5086224/...を
これを解決するまで、argsと:environmentを渡す方法を理解できませんでした。
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 task_name[hello, world]
私は実行できるようにしたかっただけです:
$ rake some:task arg1 arg2
シンプルでしょ?(いいえ!)
Rakeはarg1
、arg2
タスクとして解釈し、実行しようとします。そのため、実際に中止する前に中止します。
namespace :some do
task task: :environment do
arg1, arg2 = ARGV
# your task...
exit
end
end
かっこいい!
免責事項:私はかなり小さなペットのプロジェクトでこれをできるようになりたかったです。レーキタスク(つまりrake task1 task2 task3
)をチェーンする機能を失うため、「現実の世界」での使用は意図されていません。IMOはそれだけの価値はありません。醜いだけを使用してくださいrake task[arg1,arg2]
。
_, arg1, arg2 = ARGV
最初の引数はレーキタスクの名前と見なされたため、これを作成する必要がありました。しかし、それexit
はきちんとしたトリックです。
rake task[arg1,arg2] && rake task2 && rake task3
それがほど醜くないかどうかはわかりませんrake task[arg1,arg2] task2 task3
。おそらくあまり効率的ではありません。
_, *args = ARGV
後続のすべての引数をキャプチャするのに最適です!どうもありがとう!
私はrakeファイルで通常のルビ引数を使用します。
DB = ARGV[1]
次に、ファイルの下部にあるrakeタスクをスタブします(rakeはその引数名に基づいてタスクを検索するため)。
task :database_name1
task :database_name2
コマンドライン:
rake mytask db_name
これは、var = foo ENV varとタスクargs [blah、blah2]ソリューションよりも私にはきれいに感じられます。
スタブは少し面倒ですが、1回限りのセットアップであるいくつかの環境がある場合はそれほど悪くありません
dup
は、最後に次のように使用します。db = ARGV [1] .dup
db = ARGV[1].dup unless ARGV[1].nil?
nilの重複の例外を防ぐために、より良いイベント。
デフォルトのタスクに引数を渡すには、次のようにします。たとえば、「バージョン」が引数であるとします。
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]"
「クエリ文字列」は:
width=10&height=20
警告:ノート構文があることrake "mytask[foo=bar]"
と、NOT rake mytask["foo=bar"]
を使用してrakeタスク内で解析すると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
以下は、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"}}
引数の位置が何のためにあるのか覚えておく必要がなく、ルビ引数ハッシュのようなことをしたい場合。1つの引数を使用して文字列を渡し、その文字列をオプションハッシュに正規表現できます。
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
上記のメソッドのほとんどは私にはうまくいきませんでした。おそらく新しいバージョンでは非推奨になっています。最新のガイドは次の場所にあります。http://guides.rubyonrails.org/command_line.html#custom-rake-tasks
ガイドからのコピーと貼り付けのansはここにあります:
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タスクを実行するには:
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
パラメーターを渡すときは、入力ファイルが最適です。これは、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