Cómo pasar argumentos de línea de comando a una tarea rake

Resuelto Tilendor asked hace 15 años • 22 respuestas

Tengo una tarea de rake que necesita insertar un valor en varias bases de datos.

Me gustaría pasar este valor a la tarea de rake desde la línea de comando o desde otra tarea de rake.

¿Cómo puedo hacer esto?

Tilendor avatar May 05 '09 23:05 Tilendor
Aceptado

Puede especificar argumentos formales en rake agregando argumentos de símbolos a la llamada de tarea. Por ejemplo:

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

Luego, desde la línea de comando:

> rastrillar my_task[1,false]
Los argumentos fueron: {:arg1=>"1", :arg2=>"false"} de la clase Rake::TaskArguments
arg1 era: '1' de la clase String
arg2 era: 'falso' de la clase String

> rastrillo "my_task[1, 2]"
Los argumentos fueron: {:arg1=>"1", :arg2=>"2"}

> rastrillar invoke_my_task
Los argumentos fueron: {:arg1=>"1", :arg2=>"2"}

> rastrillo invoke_my_task_2
Los argumentos fueron: {:arg1=>3, :arg2=>4}

> rastrillo con_prerrequisito[5,6]
Los argumentos fueron: {:arg1=>"5", :arg2=>"6"}

> rastrillo con_defaults
Los argumentos con valores predeterminados eran: {:arg1=>:default_1, :arg2=>:default_2}

> rastrillo con_defaults['x','y']
Los argumentos con valores predeterminados eran: {:arg1=>"x", :arg2=>"y"}

Como se demuestra en el segundo ejemplo, si desea utilizar espacios, las comillas alrededor del nombre del objetivo son necesarias para evitar que el shell divida los argumentos en el espacio.

Al observar el código en rake.rb , parece que rake no analiza las cadenas de tareas para extraer argumentos para los requisitos previos, por lo que no puede hacerlo task :t1 => "dep[1,2]". La única forma de especificar diferentes argumentos para un requisito previo sería invocarlo explícitamente dentro de la acción de la tarea dependiente, como en :invoke_my_tasky :invoke_my_task_2.

Tenga en cuenta que algunos shells (como zsh) requieren que escape los corchetes:rake my_task\['arg1'\]

Nick Desjardins avatar May 05 '2009 16:05 Nick Desjardins

Las opciones y dependencias deben estar dentro de matrices:

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

Entonces

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

NOTA: la variable taskes el objeto de la tarea, no es muy útil a menos que conozca o se interese por los aspectos internos de Rake.

NOTA DE RIELES:

Si ejecuta la tarea desde Rails, es mejor precargar el entorno agregando, => [:environment]que es una forma de configurar tareas dependientes .

  task :work, [:option, :foo, :bar] => [:environment] do |task, args|
    puts "work", args
  end
Blair Anderson avatar Apr 07 '2015 21:04 Blair Anderson

Además de responder por kch (no encontré como dejar un comentario a eso, lo siento):

No es necesario especificar variables como ENVvariables antes del rakecomando. Puedes configurarlos como parámetros habituales de línea de comando así:

rake mytask var=foo

y acceda a aquellos desde su archivo rake como variables ENV como estas:

p ENV['var'] # => "foo"
timurb avatar Feb 19 '2011 11:02 timurb

Si desea pasar argumentos con nombre (por ejemplo, con estándar OptionParser), puede usar algo como esto:

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

tenga en cuenta --que es necesario para omitir los argumentos estándar de Rake. Debería funcionar con Rake 0.9.x , <= 10.3.x.

El nuevo Rake ha cambiado su análisis --y ahora debe asegurarse de que no se pase al OptionParser#parsemétodo, por ejemplo conparser.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

exital final se asegurará de que los argumentos adicionales no se interpreten como una tarea de Rake.

También debería funcionar el atajo para argumentos:

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

Cuando los scripts de rake se ven así, tal vez sea el momento de buscar otra herramienta que permita esto de forma inmediata.

Tombart avatar Oct 19 '2013 13:10 Tombart

Encontré la respuesta en estos dos sitios web: Net Maniac y Aimred .

Necesitas tener la versión > 0.8 de rake para usar esta técnica

La descripción normal de la tarea de rake es la siguiente:

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

Para pasar argumentos, haga tres cosas:

  1. Agregue los nombres de los argumentos después del nombre de la tarea, separados por comas.
  2. Coloque las dependencias al final usando :needs => [...]
  3. Coloque |t, argumentos| después del hacer. (t es el objeto de esta tarea)

Para acceder a los argumentos en el script, use 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

Para llamar a esta tarea desde la línea de comando, pásele los argumentos en []s

rake task_name['Hello',4]

saldrá

Hello
Hello
Hello
Hello

y si desea llamar a esta tarea desde otra tarea y pasarle argumentos, use invocar

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

entonces el comando

rake caller

saldrá

In Caller
hi
hi

No he encontrado una manera de pasar argumentos como parte de una dependencia, ya que el siguiente código falla:

task :caller => :task_name['hi',2]' do
   puts 'In Caller'
end
Tilendor avatar May 05 '2009 16:05 Tilendor