¿Cómo ejecuto tareas de Rake dentro de un script de Ruby?
-
08-06-2019 - |
Pregunta
tengo un Rakefile
con una tarea de Rake que normalmente llamaría desde la línea de comando:
rake blog:post Title
Me gustaría escribir un script Ruby que llame a esa tarea Rake varias veces, pero la única solución que veo es usar `` (comillas invertidas) o system
.
¿Cuál es la forma correcta de hacer esto?
Solución
de timocracia.com:
require 'rake'
require 'rake/rdoctask'
require 'rake/testtask'
require 'tasks/rails'
def capture_stdout
s = StringIO.new
oldstdout = $stdout
$stdout = s
yield
s.string
ensure
$stdout = oldstdout
end
Rake.application.rake_require '../../lib/tasks/metric_fetcher'
results = capture_stdout {Rake.application['metric_fetcher'].invoke}
Otros consejos
Esto funciona con la versión 10.0.3 de Rake:
require 'rake'
app = Rake.application
app.init
# do this as many times as needed
app.add_import 'some/other/file.rake'
# this loads the Rakefile and other imports
app.load_rakefile
app['sometask'].invoke
Como dijo knut, usa reenable
si desea invocar varias veces.
Puedes usar invoke
y reenable
para ejecutar la tarea por segunda vez.
Tu llamada de ejemplo rake blog:post Title
Parece tener un parámetro.Este parámetro se puede utilizar como parámetro en invoke
:
Ejemplo:
require 'rake'
task 'mytask', :title do |tsk, args|
p "called #{tsk} (#{args[:title]})"
end
Rake.application['mytask'].invoke('one')
Rake.application['mytask'].reenable
Rake.application['mytask'].invoke('two')
Por favor cámbialo mytask
con blog:post
y en su lugar la definición de tarea que puedes require
tu archivo de rake.
Esta solución escribirá el resultado en la salida estándar, pero no mencionó que desea suprimir la salida.
Interesante experimento:
Puedes llamar al reenable
también dentro de la definición de la tarea.Esto permite que una tarea se reactive a sí misma.
Ejemplo:
require 'rake'
task 'mytask', :title do |tsk, args|
p "called #{tsk} (#{args[:title]})"
tsk.reenable #<-- HERE
end
Rake.application['mytask'].invoke('one')
Rake.application['mytask'].invoke('two')
El resultado (probado con rake 10.4.2):
"called mytask (one)"
"called mytask (two)"
En un script con Rails cargado (p. ej. rails runner script.rb
)
def rake(*tasks)
tasks.each do |task|
Rake.application[task].tap(&:invoke).tap(&:reenable)
end
end
rake('db:migrate', 'cache:clear', 'cache:warmup')