2010-01-18 2 views
12

파일을 변경하는 제네레이터를 어떻게 만드나요?레일 제너레이터로 파일 수정

파일의 패턴을 찾고 그 아래 줄에 내용이 추가되도록 만들기 위해 노력하고 있습니다. 이 config/routes.rb에 경로를 추가 할 때

답변

16

레일 '비계 생성기는이 작업을 수행 그것은 이것은 매우 간단한 방법을 호출하여 수행합니다

def gsub_file(relative_destination, regexp, *args, &block) 
    path = destination_path(relative_destination) 
    content = File.read(path).gsub(regexp, *args, &block) 
    File.open(path, 'wb') { |file| file.write(content) } 
end 

그것은 무엇 다음, 첫 번째 인수로 경로/파일을 복용하고있어 정규 표현식 패턴, gsub 인수 및 블록. 이것은 사용하기 위해 다시 만들어야하는 보호 된 방법입니다. destination_path이 액세스 권한이 있는지 확실하지 않으므로 정확한 경로를 전달하고 모든 전환을 건너 뛰고 싶을 것입니다.

gsub_file을 사용하려면 사용자 모델에 태그를 추가하려고한다고 가정 해 봅시다. 여기 당신이 그것을 할 것입니다 방법은 다음과 같습니다

line = "class User < ActiveRecord::Base" 
gsub_file 'app/models/user.rb', /(#{Regexp.escape(line)})/mi do |match| 
    "#{match}\n has_many :tags\n" 
end 

당신은 파일, 클래스 개막전에서 특정 라인을 찾아, 오른쪽 아래에 당신의 has_many 줄을 추가하고 있습니다.

이것은 콘텐츠를 추가하는 가장 취약한 방법이므로주의해야합니다. 라우팅이이를 사용하는 유일한 장소이기 때문입니다. 위의 예제는 일반적으로 믹스 인으로 처리됩니다.

1

저는 하이메의 대답을 좋아합니다. 그러나, 그것을 활용하기 시작했을 때, 나는 약간의 수정이 필요하다는 것을 깨달았습니다. 여기에 내가 사용하고있는 샘플 코드입니다 :

private 

    def destination_path(path) 
    File.join(destination_root, path) 
    end 

    def sub_file(relative_file, search_text, replace_text) 
    path = destination_path(relative_file) 
    file_content = File.read(path) 

    unless file_content.include? replace_text 
     content = file_content.sub(/(#{Regexp.escape(search_text)})/mi, replace_text) 
     File.open(path, 'wb') { |file| file.write(content) } 
    end 

    end 

첫째, gsub는 검색 텍스트의 모든 인스턴스를 대체 할이; 나는 오직 하나만 필요로한다. 그 대신에 sub을 사용했습니다.

다음으로 교체 문자열이 이미 있는지 확인해야합니다. 그렇지 않으면 내 레일 생성기가 여러 번 실행되면 삽입을 반복 할 것입니다. 그래서 나는 코드를 unless 블록으로 감쌌다.

마지막으로 def destination_path()을 추가했습니다.

이제 어떻게 이것을 레일 제너레이터에서 사용 하시겠습니까? 여기에 내가 확인 simplecov이 RSpec에와 오이가 설치되어 있는지 확인하는 방법의 예는 다음과 같습니다

def configure_simplecov 
    code = "#Simple Coverage\nrequire 'simplecov'\nSimpleCov.start" 

    sub_file 'spec/spec_helper.rb', search = "ENV[\"RAILS_ENV\"] ||= 'test'", "#{search}\n\n#{code}\n" 
    sub_file 'features/support/env.rb', search = "require 'cucumber/rails'", "#{search}\n\n#{code}\n" 
    end 

아마이 일을 더 우아하고 DRY - 어 방법이있다. 나는 Jamie의 예문 블록을 추가하는 방법을 정말 좋아했습니다. 다행히도 필자의 예제는 더 많은 기능과 오류 검사 기능을 추가했다.