ruby on rails - generate - ¿Cómo pasar argumentos a una tarea de Rake con entorno en Rails?
ruby on rails rake (5)
Esta pregunta ya tiene una respuesta aquí:
Soy capaz de pasar en los siguientes argumentos:
desc "Testing args"
task: :hello, :user, :message do |t, args|
args.with_defaults(:message => "Thanks for logging on")
puts "Hello #{args[:user]}. #{:message}"
end
También puedo cargar el entorno actual para una aplicación Rails
desc "Testing environment"
task: :hello => :environment do
puts "Hello #{User.first.name}."
end
Lo que me gustaría hacer es poder tener variables y entorno.
desc "Testing environment and variables"
task: :hello => :environment, :message do |t, args|
args.with_defaults(:message => "Thanks for logging on")
puts "Hello #{User.first.name}. #{:message}"
end
Pero eso no es una llamada de tarea válida. ¿Alguien sabe como puedo lograr esto?
TLDR;
task :t, [args] => [deps]
Respuesta original
Cuando pasa argumentos para realizar tareas, puede requerir que el entorno use la opción: necesidades. Por ejemplo:
desc "Testing environment and variables"
task :hello, :message, :needs => :environment do |t, args|
args.with_defaults(:message => "Thanks for logging on")
puts "Hello #{User.first.name}. #{args.message}"
end
Actualizado por @ el comentario de Peiniau a continuación
En cuanto a rieles> 3.1
task :t, arg, :needs => [deps] # deprecated
Por favor use
task :t, [args] => [deps]
Si bien estas soluciones funcionan, en mi opinión esto es demasiado complicado.
Además, si lo haces de esta manera en zsh, obtendrás errores si los paréntesis en tu matriz no se escapan con ''/'.
Recomiendo usar la matriz ARGV, que funciona bien, es mucho más simple y es menos propenso a errores. P.ej:
namespace :my_example do
desc "Something"
task :my_task => :environment do
puts ARGV.inspect
end
end
entonces
rake my_example:my_task 1 2 3
#=> ["my_example:my_task", "1", "2", "3"]
Lo único que debe tener en cuenta es que ARGV [0] es el nombre del proceso, así que use solo ARGV [1 ..- 1].
Me doy cuenta de que, estrictamente hablando, esto no responde a la pregunta, ya que no utiliza: el entorno como parte de la solución. Pero OP no declaró por qué incluyó esa estipulación, por lo que aún podría aplicarse a su caso de uso.
Solo para completar, aquí el ejemplo de los docs mencionados anteriormente:
task :name, [:first_name, :last_name] => [:pre_name] do |t, args|
args.with_defaults(:first_name => "John", :last_name => "Dough")
puts "First name is #{args.first_name}"
puts "Last name is #{args.last_name}"
end
Notas:
- Puede omitir la llamada
#with_defaults
, obviamente. - Tienes que usar una
Array
para tus argumentos, incluso si solo hay uno. - Los requisitos previos no tienen que ser una
Array
. -
args
es una instancia deRake::TaskArguments
. -
t
es una instancia deRake::Task
.
Solo para dar seguimiento a este viejo tema; esto es lo que creo que un archivo Rake actual (desde hace mucho tiempo) debería hacer allí. Es una versión mejorada y corregida de la respuesta ganadora actual (hgimenez):
desc "Testing environment and variables"
task :hello, [:message] => :environment do |t, args|
args.with_defaults(:message => "Thanks for logging on")
puts "Hello #{User.first.name}. #{args.message}" # Q&A above had a typo here : #{:message}
end
Así es como lo invocas ( http://guides.rubyonrails.org/v4.2/command_line.html#rake ):
rake "hello[World]"
Para varios argumentos, solo agregue sus palabras clave en la matriz de la declaración de tarea ( task :hello, [:a,:b,:c]...
), y páseles separados por comas:
rake "hello[Earth,Mars,Sun,Pluto]"
Nota: la cantidad de argumentos no está marcada, por lo que el planeta impar queda fuera :)
Una forma alternativa de hacerlo: usar las variables de entorno del sistema operativo. Beneficios de este enfoque:
- Todas las tareas de rake dependientes obtienen las opciones.
- La sintaxis es mucho más simple, no depende del rake DSL que es difícil de entender y cambia con el tiempo.
Tengo una tarea de rake que requiere tres opciones de línea de comandos. Así es como lo invoco:
$ rake eaternet:import country=us region=or agency=multco
Eso es muy limpio, simple y bash sintaxis, que me gusta. Aquí está mi tarea de rastrillo. También muy limpio y sin magia:
task import: [:environment] do
agency = agency_to_import
puts "Importing data for #{agency}..."
agency.import_businesses
end
def agency_to_import
country_code = ENV[''country''] or raise "No country specified"
region_slug = ENV[''region''] or raise "No region specified"
agency_slug = ENV[''agency''] or raise "No agency specified"
Agency.from_slugs(country_code, region_slug, agency_slug)
end
Este ejemplo particular no muestra el uso de dependencias. Pero si la tarea de :import
dependiera de otras, también tendrían acceso a estas opciones. Pero usando el método de opciones de rake normal, no lo harían.