Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

thor gem でテンプレートを利用してファイルを生成する #thor #ruby

More than 5 years have passed since last update.

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

Thor 関連資料

tbpgr
Rubyを扱う人事(研修開発、エンジニア採用) Learning Designer。 tbpgr の読み方は(てぃーびー) 個人ブログでも色々と情報を垂れ流してます。 http://tbpgr.hatenablog.com/
http://tbpgr.hatenablog.com/
studist
「伝えることを、もっと簡単に」をミッションにビジュアルSOPマネジメントプラットフォームのBtoB SaaS「Teachme Biz」を開発・運営するスタートアップ
https://medium.com/studist-dev
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away