Question Comment passer des arguments de ligne de commande à une tâche de rake


J'ai une tâche rake qui doit insérer une valeur dans plusieurs bases de données.

Je voudrais passer cette valeur dans la tâche rake depuis la ligne de commande, ou depuis un autre Rake Tâche.

Comment puis-je faire ceci?


950
2018-05-05 16:27


origine


Réponses:


les options et les dépendances doivent être dans des tableaux:

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

alors

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"}

NOTE: variable task est l'objet de la tâche, pas très utile à moins que vous sachiez / se soucient des internes Rake.

RAILS NOTE:

Si l'exécution de la tâche à partir de rails, il est préférable de précharger l'environnement en ajoutant => [:environment] ce qui est un moyen de configurer dépendant les tâches.

  task :work, [:option, :foo, :bar] => [:environment] do |task, args|
    puts "work", args
  end

229
2018-04-07 21:56



Vous pouvez spécifier des arguments formels dans rake en ajoutant des arguments de symbole à l'appel de tâche. Par exemple:

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

Ensuite, à partir de la ligne de commande:

> rake my_task [1,2]
Args étaient: {: arg1 => "1",: arg2 => "2"}

> ratisser "my_task [1, 2]"
Args étaient: {: arg1 => "1",: arg2 => "2"}

> rake invoke_my_task
Args étaient: {: arg1 => "1",: arg2 => "2"}

> rake invoke_my_task_2
Args étaient: {: arg1 => 3,: arg2 => 4}

> rake with_prerequisite [5,6]
Args étaient: {: arg1 => "5",: arg2 => "6"}

> rake with_defaults
Les args avec les valeurs par défaut étaient: {: arg1 =>: default_1,: arg2 =>: default_2}

> rake with_defaults ['x', 'y']
Les args avec les valeurs par défaut étaient: {: arg1 => "x",: arg2 => "y"}

Comme le démontre le deuxième exemple, si vous voulez utiliser des espaces, les guillemets autour du nom de la cible sont nécessaires pour empêcher le shell de séparer les arguments de l'espace.

Regarder le code dans rake.rb, il semble que rake n'analyse pas les chaînes de tâches pour extraire les arguments pour les prérequis, donc vous ne pouvez pas faire task :t1 => "dep[1,2]". La seule façon de spécifier des arguments différents pour un prérequis serait de l'invoquer explicitement dans l'action de la tâche dépendante, comme dans :invoke_my_task et :invoke_my_task_2.

Notez que certains shells (comme zsh) nécessitent que vous échappiez aux parenthèses: rake my_task\['arg1'\]


1081
2018-05-05 16:45



En plus de répondre par kch (je n'ai pas trouvé comment laisser un commentaire à cela, désolé):

Vous n'avez pas besoin de spécifier des variables ENV variables avant la rake commander. Vous pouvez simplement les définir comme des paramètres de ligne de commande habituels comme ça:

rake mytask var=foo

et accédez à ceux de votre fichier Rake en tant que variables ENV telles que:

p ENV['var'] # => "foo"

287
2018-02-19 11:05



Si vous voulez passer des arguments nommés (par exemple, avec des arguments standard OptionParser) vous pourriez utiliser quelque chose comme ceci:

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

noter la --, c'est nécessaire pour contourner les arguments Rake standard. Devrait fonctionner avec Rake 0.9.x, <= 10.3.x.

Newer Rake a changé son analyse de --, et maintenant vous devez vous assurer qu'il n'est pas transmis à la OptionParser#parse méthode, par exemple avec 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 à la fin, assurez-vous que les arguments supplémentaires ne seront pas interprétés comme une tâche Rake.

Aussi le raccourci pour les arguments devrait fonctionner:

 rake user:create -- -u test@example.com -p 123

Lorsque les scripts de rake ressemblent à ceci, il est peut-être temps de chercher un autre outil qui permettrait cela juste en dehors de la boîte.


94
2017-10-19 13:09



J'ai trouvé la réponse de ces deux sites: Maniac net et Aimred.

Vous devez avoir une version> 0.8 de râteau pour utiliser cette technique

La description de la tâche rake normale est la suivante:

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

Pour passer des arguments, faites trois choses:

  1. Ajoutez les noms d'arguments après le nom de la tâche, séparés par des virgules.
  2. Mettez les dépendances à la fin en utilisant: needs => [...]
  3. Place | t, args | après le faire. (t est l'objet de cette tâche)

Pour accéder aux arguments du script, utilisez 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

Pour appeler cette tâche depuis la ligne de commande, passez-lui les arguments dans [] s

rake task_name['Hello',4]

sortira

Hello
Hello
Hello
Hello

et si vous voulez appeler cette tâche d'une autre tâche, et lui passer des arguments, utilisez invoke

task :caller do
  puts 'In Caller'
  Rake::Task[:task_name].invoke('hi',2)
end

alors la commande

rake caller

sortira

In Caller
hi
hi

Je n'ai pas trouvé un moyen de passer des arguments dans le cadre d'une dépendance, car le code suivant se brise:

task :caller => :task_name['hi',2]' do
   puts 'In Caller'
end

56
2018-05-05 16:51



Une autre option couramment utilisée consiste à passer des variables d'environnement. Dans votre code, vous les lisez via ENV['VAR'], et peut les passer juste avant la rake commande, comme

$ VAR=foo rake mytask

30
2018-05-05 16:53



En fait, @Nick Desjardins a répondu parfait. Mais juste pour l'éducation: vous pouvez utiliser une approche sale: en utilisant ENV argument

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

rake my_task myvar=10
#=> myvar: 10

30
2018-02-28 20:06



Je ne pouvais pas comprendre comment passer args et aussi l'environnement: jusqu'à ce que j'ai travaillé sur ceci:

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

Et puis j'appelle comme ça:

rake db:export['foo, /tmp/']

24
2017-11-29 19:38



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

23
2017-10-16 07:36



J'utilise un argument ruby ​​régulier dans le fichier rake:

DB = ARGV[1]

puis je remplace les tâches de rake au bas du fichier (puisque rake va chercher une tâche basée sur ce nom d'argument).

task :database_name1
task :database_name2

ligne de commande:

rake mytask db_name

cela me semble plus propre que la variable var = foo ENV var et les arguments de la tâche [blah, blah2].
le talon est un peu saccadé, mais pas trop mauvais si vous avez juste quelques environnements qui sont une configuration unique


13
2017-12-29 02:48