1168

複数のデータベースに値を挿入する必要があるrakeタスクがあります。

この値をコマンドラインまたは別のrakeタスクからrakeタスクに渡したいのですが。

これどうやってするの?

4

20 に答える 20

1159

タスク呼び出しにシンボル引数を追加することで、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]
引数は: クラス Rake::TaskArguments の {:arg1="1", :arg2="false"}
arg1 は次のとおりです: クラス String の '1'
arg2 だった: クラス String の 'false'

> レーキ "my_task[1, 2]"
引数: {:arg1="1", :arg2="2"}

> レーキinvoke_my_task
引数: {:arg1="1", :arg2="2"}

> レーキinvoke_my_task_2
引数: {:arg1=>3, :arg2=>4}

>_prerequisite[5,6]でレーキ
引数: {:arg1="5", :arg2="6"}

> レーキ 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'\]

于 2009-05-05T16:45:25.480 に答える
367

kchによる回答に加えて(コメントを残す方法が見つかりませんでした、申し訳ありません):

コマンドENVの前に変数を変数として指定する必要はありません。rake次のように、通常のコマンド ライン パラメータとして設定できます。

rake mytask var=foo

次のような ENV 変数として rake ファイルからそれらにアクセスします。

p ENV['var'] # => "foo"
于 2011-02-19T11:05:41.060 に答える
117

名前付き引数を (たとえば、 standard で) 渡したい場合OptionParserは、次のようなものを使用できます。

$ rake user:create -- --user test@example.com --pass 123

に注意してください。これは--、標準の Rake 引数をバイパスするために必要です。Rake 0.9.x<= 10.3.xで動作するはずです。

新しい Rake は の解析を変更したため、メソッドに--渡されていないことを確認する必要があります。OptionParser#parseparser.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

レーキ スクリプトがこのようになっている場合は、すぐに使用できる別のツールを探す時期かもしれません。

于 2013-10-19T13:09:57.043 に答える
58

私はこれらの 2 つの Web サイトから答えを見つけました: Net ManiacAimred .

この手法を使用するには、バージョン > 0.8 の rake が必要です

通常の rake タスクの説明は次のとおりです。

desc 'Task Description'
task :task_name => [:depends_on_taskA, :depends_on_taskB] do
  #interesting things
end

引数を渡すには、次の 3 つのことを行います。

  1. タスク名の後にコンマで区切って引数名を追加します。
  2. :needs => [...] を使用して、依存関係を最後に配置します。
  3. 場所|t、args| やった後。(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
于 2009-05-05T16:51:45.543 に答える
33

これを解決するまで、引数と :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/']
于 2014-11-29T19:38:18.303 に答える
32

実際、@Nick Dejardins は完璧に答えました。しかし、教育のためだけに: 汚いアプローチを使用できます:ENV引数の使用

task :my_task do
  myvar = ENV['myvar']
  puts "myvar: #{myvar}"
end 

rake my_task myvar=10
#=> myvar: 10
于 2011-02-28T20:06:33.597 に答える
29

よく使用されるもう 1 つのオプションは、環境変数を渡すことです。コードでは、 を介してそれらを読み取り、次のようにコマンドのENV['VAR']直前に渡すことができますrake

$ VAR=foo rake mytask
于 2009-05-05T16:53:13.107 に答える
24
desc 'an updated version'
task :task_name, [:arg1, :arg2] => [:dependency1, :dependency2] do |t, args|
    puts args[:arg1]
end
于 2012-10-16T07:36:27.603 に答える
13

rake ファイルで通常の ruby​​ 引数を使用します。

DB = ARGV[1]

次に、rake タスクをファイルの一番下にスタブします (rake はその引数名に基づいてタスクを探すため)。

task :database_name1
task :database_name2

コマンドライン:

rake mytask db_name

これは、 var=foo ENV var および task args[blah, blah2] ソリューションよりもクリーンに感じます。
スタブは少しぎくしゃくしていますが、1 回限りのセットアップである環境がいくつかあるだけであれば、それほど悪くはありません。

于 2012-12-29T02:48:52.867 に答える
5

引数を渡す方法は、上記の回答で正しいです。ただし、引数を指定して rake タスクを実行するには、レールの新しいバージョンに関連する小さな技術があります。

rake "namespace:taskname['argument1']" で動作します

コマンドラインからタスクを実行する際の逆引用符に注意してください。

于 2014-04-24T14:23:15.857 に答える
3

特に渡す引数が多い場合は、引数を渡すための「クエリ文字列」構文が好きです。

例:

rake "mytask[width=10&height=20]"

「クエリ文字列」は次のとおりです。

width=10&height=20

警告:構文はrake "mytask[foo=bar]"and 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"}}
于 2014-02-16T22:05:07.223 に答える
3

上記の方法のほとんどは私にとってはうまくいきませんでした。新しいバージョンでは廃止されている可能性があります。最新のガイドはこちらにあります: 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
于 2015-02-03T01:15:17.420 に答える
3

デフォルトタスクに引数を渡すには、次のようにします。たとえば、「バージョン」が引数であるとします。

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

ただし、引数を渡すときにタスク名 (デフォルトまたはビルド) を指定しないようにする方法は見つかりませんでした。方法を知っている方がいましたら教えていただけると幸いです。

于 2013-10-20T19:03:37.573 に答える
2

従来の引数スタイルで 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
于 2019-02-13T06:40:14.250 に答える
1
namespace :namespace1 do
  task :task1, [:arg1, :arg2, :arg3] => :environment do |_t, args|
    p args[:arg1]
  end
end

呼び出し

rake namespace1:task1["1","2","3"]

通話中に環境を提供する必要はありません

zsh では、呼び出しを引用符で囲む必要があります

'rake namespace1:task1["1","2","3"]'

ありがとう

于 2022-02-14T11:52:18.133 に答える
-5

パラメータを渡している間、より良いオプションは入力ファイルです。これは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

json の例

{
  "name_task": "I'm a task",
  "user_id": 389,
  "users_assigned": [389,672,524],
  "task_id": 3
}

実行

rake :name_task 
于 2014-02-27T13:52:06.427 に答える