2008-08-06 15 views

Respuesta

43

de timocracy.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} 
+1

con los carriles de 3.1 el rastrillo/rdoctask ha quedado obsoleto y tareas/raíles que falta. Lo anterior funciona bien solo con la primera declaración de requerimiento. – jwadsack

+0

Para cambiar la salida estándar, sugiero guardar la secuencia original a través de '# dup', luego' # reopen' a un 'Tempfile' que se lee después de volver a abrir el original. Simplemente asignando '$ stdout' no funcionará si la tarea usa la constante' STDOUT', o ejecuta un programa externo. – Kelvin

+0

Tenga en cuenta que 'rake_require' siempre une la ruta dada con cada ruta de la matriz' $ LOAD_PATH' y comprueba la existencia de un archivo. Entonces, el primer argumento debería ser ** una ruta relativa **. Se tratará como relativo, incluso si contiene una barra diagonal (o barra diagonal inversa en sistemas que no son de Unix). – siefca

13

Puede utilizar invoke y reenable para ejecutar la tarea por segunda vez.

Su llamada de ejemplo rake blog:post Title parece tener un parámetro. Este parámetro se puede utilizar como un 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, vuelva a colocar mytask con blog:post y en lugar de la definición de tarea que puede require su Rakefile.

Esta solución escribirá el resultado en stdout, pero no mencionó que desea suprimir la salida.


experimento interesante:

Usted puede llamar a la reenable también dentro de la definición de la tarea. Esto permite que una tarea vuelva a activarse.

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 el rastrillo 10.4.2):

"called mytask (one)" 
"called mytask (two)" 
+0

esto no funciona para tareas dentro de Gems –

+0

@JasonFB ¿Tiene un ejemplo de por qué no? – knut

+0

@JasonFB Vea también mi respuesta editada. Tal vez esta es una alternativa para su problema ... – knut

17

Esto funciona con la versión Rake 10.0.3:

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 , use reenable si desea invocar varias veces.

+1

esto no funciona para tareas dentro de Gems –

+0

Hola @JasonFB, puedes acceder a la gema con algo como 'app.add_import" # {Gem :: Specification.find_by_name ('estadista ') .gem_dir} /lib/tasks/statesman.rake "' – spikeheap

1

En un guión con rieles cargado (por ejemplo 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') 
Cuestiones relacionadas