2009-09-08 2 views
4

레일 개발 용 웹 기반 dev-console을 작성 중입니다. 내 컨트롤러 동작 중 하나에서 Rake를 호출 중이지만 Rake가 생성하는 출력을 캡처 할 수 없습니다. 예를 들어 컨트롤러의 샘플 코드는 다음과 같습니다.Ruby 스크립트에서 호출 할 때 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.application['db:migrate:redo'].reenable 
Rake.application['db:migrate:redo'].invoke 

는 이상하게도, 일부 레이크 작업은 이제 (경로) 완벽하게 작동, 일부 캡처 출력을 첫 번째 실행 이후는 항상 비어 있으며 (db : migrate : redo) 일부는 출력 (test)을 캡처하지 않는 것처럼 보입니다. 이상한.

답변

2

ZenTest는 "until_capture"를 통해 "puts"구문을 캡처 할 수 있으며 커널 모듈을 확장하고 $ stdout을 StringIO 인스턴스로 리디렉션하여 사용자 정의 구현에 대해 작성한 사람을 발견했습니다.
http://github.com/mhennemeyer/output_catcher

3

을 (Rack은 루비로 작성되기 때문에)이 해킹의 일종이지만 : 또한 마티아스 Hennemeyer에 의해 OutputCatcher을 체크 아웃 할 수 있습니다
http://thinkingdigitally.com/archive/capturing-output-from-puts-in-ruby/

: 도움이

희망 open3의 popen3 메쏘드를 사용하고 커맨드 라인에서와 같이 레이크 태스크를 호출 할 수 있습니다. 귀하의 경우에는

당신은 그래서 당신은 레이크 buffer에 stdout에 반환 된 모든 선으로 끝날 것이라고

require 'open3' 

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

처럼 사용할 수 있습니다. 아마도 이상한 행동의 원인을 조사 할 것을 권유하지만 더 신뢰할 수 있습니다. . 보석/레이크-0.8.7/lib 디렉토리/rake.rb의

1

라인 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을 통해 이루어 졌다고 말하는 것은 아니지만 레이크 자체가 그 규칙을 설정 한 것 같습니다. 아마도 누군가 특정 레이크 작업을 작성한 행을 어딘가에 넣으면 $stderr으로 직접 겹쳐 씁니다.

아이디어를 테스트하지 않았습니다.

관련 문제