thor gem でテンプレートを利用してファイルを生成する #thor #ruby
概要
thor gem でテンプレートを利用してファイルを生成します。
Thor の Thor::Actions を利用することで内部的に ERB を利用した
ファイル出力が可能です。
後述の例は Thor::Group でファイル出力処理を定義し、
Thor を継承したクラスに register
で登録しています。
-
argument
メソッドに引数を定義します。定義した引数はクラス内、テンプレートファイル内で利用可能です -
source_root
クラスメソッドに処理のルートディレクトリを定義します -
template
メソッドでテンプレートの出力を行います。引数の最後にハッシュを渡すと、
テンプレート内でconfig
という名前でアクセス出来ます。
これは、 thor の内部実装を知っている必要があって結構微妙な仕様だな、と思ったりします。
本当はtemplate
メソッド呼び出し時に指定する Hash の変数名は自由なのですが、
config
という名前にしておいた方が理解しやすいかもしれません。
以下URLにて内部実装を確認可能。 create_file 時に config と言う名前で Hash を渡している
thor file_manipulation.rb L108-120
仕様
下記の3ファイルを生成する
<name>/lib/<name>.rb
<name>/lib/version.rb
<name>/README
テンプレート
template/ruby_src.tt
module_name
, class_name
は argument を参照している。
config
は template メソッドの呼び出し時に渡した opt
の内容を取得している。
module <%=module_name%>
class <%=class_name%>
def hoge
<%=config[:logic]%>
end
end
end
template/version.tt
module <%=module_name%>
VERSION = '0.0.1'
end
ソースコード
thor_generate_file_from_template.rb
require 'thor'
class Generator < Thor::Group
include Thor::Actions
argument :module_name
argument :class_name
argument :file_name
argument :logic
def self.source_root
File.dirname(__FILE__)
end
def create_lib_file
# わざと config 以外の命名にしているが、 config にしたたほうがよさそう
opt = {
logic: "puts 'hoge'"
}
template('templates/ruby_src.tt', "#{file_name}/lib/#{file_name}.rb", opt)
end
def create_version
template('templates/version.tt', "#{file_name}/lib/version.rb")
end
def create_readme
create_file "#{file_name}/README.md"
end
end
module Hoge
class CLI < Thor
register(Generator, "gen", "generate sample", "generate sample")
end
end
Hoge::CLI.start(ARGV)
実行
$ ruby thor_generate_file_from_template.rb gen HogeModule HogeClass hoge "puts 'hoge'"
create hoge/lib/hoge.rb
create hoge/lib/version.rb
create hoge/README.md
$ tree
.
┣ hoge
┃ ┣ lib
┃ ┃ ┣ hoge.rb
┃ ┃ ┗ version.rb
┃ ┗ README.md
┣ templates
┃ ┣ ruby_src.tt
┃ ┗ version.tt
┗ thor_generate_file_from_template.rb
$ cat hoge/lib/hoge.rb
module HogeModule
class HogeClass
def hoge
puts 'hoge'
end
end
end
$ cat hoge/lib/version.rb
module HogeModule
VERSION = '0.0.1'
end
$ cat hoge/README.md