Jak uruchomić zadania Rake w skrypcie Ruby?

Mam Rakefile z zadaniem Rake, które normalnie wywołam z linii poleceń:

rake blog:post Title

Chciałbym napisać skrypt Ruby, który wywołuje to zadanie Rake wiele razy, ale jedynym rozwiązaniem, jakie widzę, jest użycie " (backticks) lub system.

Jak to zrobić?
Author: the Tin Man, 2008-08-06

4 answers

Z timocracy.com :

require 'rake'

def capture_stdout
  s = StringIO.new
  oldstdout = $stdout
  $stdout = s
  yield
  s.string
ensure
  $stdout = oldstdout
end

Rake.application.rake_require 'metric_fetcher', ['../../lib/tasks']
results = capture_stdout {Rake.application['metric_fetcher'].invoke}
 43
Author: titanous,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-06-18 02:42:03

To działa z wersją 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

Jak powiedział knut, użyj reenable, jeśli chcesz wywołać wiele razy.

 20
Author: Kelvin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-19 23:09:12

Możesz użyć invoke i reenable, Aby wykonać zadanie po raz drugi.

Twoje przykładowe wywołanie rake blog:post Title wydaje się mieć parametr. Parametr ten może być użyty jako parametr w invoke:

Przykład:

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')

Proszę zastąpić {[7] } blog:post i zamiast definicji zadania Można require twój rakefile.

To rozwiązanie zapisze wynik na stdout - ale nie wspomniałeś, że chcesz wyłączyć wyjście.


Ciekawe eksperyment:

Możesz wywołać reenable również wewnątrz definicji zadania. Pozwala to zadanie odtworzyć się.

Przykład:

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')

Wynik (testowany z rake 10.4.2):

"called mytask (one)"
"called mytask (two)"
 16
Author: knut,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-31 20:53:48

W skrypcie z załadowanym Railsem (np. 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')
 4
Author: Dorian,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-24 22:09:16