如何制作改变文件的生成器。
我试图让它在文件中找到一个模式,并将内容添加到它下面的行。
答案 0 :(得分:16)
Rails'脚手架生成器在向config/routes.rb
添加路由时执行此操作。它通过调用一个非常简单的方法来实现:
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
它正在做的是将路径/文件作为第一个参数,然后是regexp模式,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 :(得分:1)
我喜欢Jaime的回答。但是,当我开始使用它时,我意识到我需要做一些修改。以下是我使用的示例代码:
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
代替。
接下来,我需要检查替换字符串是否已经到位。否则,如果我的rails生成器多次运行,我会重复插入。所以我将代码包装在unless
块中。
最后,我为您添加了def destination_path()
。
现在,您如何在轨道生成器中使用它?以下是我如何确保为rspec和黄瓜安装simplecov的示例:
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
这可能是一种更优雅,更干燥的方式。我真的很喜欢你如何添加Jamie的例子。希望我的示例添加更多功能和错误检查。