8

Rails開発用のWebベースの開発コンソールを書いています。コントローラーアクションの1つで、Rakeを呼び出していますが、Rakeが生成する出力をキャプチャできません。たとえば、コントローラーからのサンプルコードを次に示します。

require 'rake'
require 'rake/rdoctask'
require 'rake/testtask'
require 'tasks/rails'
require 'stringio'

...

def show_routes

  @results = capture_stdout { Rake.tasks['routes'].invoke }

  # @results is nil -- the capture_stdout doesn't catpure anything that Rake generates

end

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

Rakeの出力をキャプチャできない理由を誰かが知っていますか?Rakeソースを調べてみましたが、新しいプロセスなどがどこで発生するかわからないので、これができるはずだと思います。

どうもありがとう!エイドリアン


それ以来、Rubyの内部からRakeを呼び出す正しい方法を発見しました。これは、はるかにうまく機能します。

Rake.application['db:migrate:redo'].reenable
Rake.application['db:migrate:redo'].invoke

不思議なことに、一部のrakeタスクは現在完全に機能し(ルート)、最初の実行時に出力をキャプチャし、その後は常に空白になり(db:migrate:redo)、出力をキャプチャしないように見えるものもあります(テスト)。奇数。

4

4 に答える 4

4

これはある種のハックですが(Rackはrubyで記述されているため)、コマンドラインから行うのと同じように、open3のpopen3メソッドを使用してrakeタスクを呼び出すことができます。

あなたの場合、あなたはそれをそのように使うでしょう

require 'open3'

buffer = []
Open3::popen3("rake db:migrate:redo") do |stdin,stdout,stderr|
  begin
    while line = stdout.readline
      buffer << line
    end
  rescue
  end
end

したがって、レーキがでstdoutに戻ったすべての行になりbufferます。あなたが説明する奇妙な振る舞いの原因を調査することをお勧めしますが、おそらくこれはより信頼性の高い動作をします。

于 2009-11-25T23:21:22.163 に答える
2

ZenTest が「until_capture」を介して「puts」ステートメントをキャプチャできることは知っていますし、カーネル モジュールを拡張して $stdout を StringIO のインスタンスにリダイレクトするカスタム実装について書いている人を見つけました。

お役に立てば幸いです:
http://thinkingdigitally.com/archive/capturing-output-from-puts-in-ruby/

また、Matthias Hennemeyer による OutputCatcher もチェックしてください:
http://github.com/mhennemeyer/output_catcher

于 2009-09-17T19:17:45.543 に答える
1

これは私のためのトリックを行います:

$stdout.reopen("my.log", "w")
$stdout.sync = true

# do your thing

$stdout = STDOUT

で見られる:https ://stackoverflow.com/a/2480439/21217

于 2012-12-13T14:07:28.477 に答える
1

gems/rake-0.8.7/lib/rake.rb の 1174 行目:

  # Send the message to the default rake output (which is $stderr).
  def rake_output_message(message)
    $stderr.puts(message)
  end
  private :rake_output_message

おそらく、STDOUT だけでなく STDERR もキャプチャしてみてください。

すべての出力が を介して行われると言っているわけではありません$stderrが、rake 自体がその規則を設定しているようです。おそらく、誰かが特定の rake タスクを上書きして put を直接 に作成した可能性があり$stderrます。

私はそのアイデアをテストしていません。

于 2010-04-12T02:35:30.223 に答える