Giter8でテンプレートプロジェクトを作成する

Giter8でテンプレートプロジェクトを作成する

新しくプロジェクトを作成する場合

既存のマイクロサービスがあり、新たにサービスを実装することになったとします。
サービスを同じアーキテクチャで実装する場合、私は下記のようにしていました。
※GitHub上のリポジトリにJavaのプロジェクトがあると仮定   

  1. 既存プロジェクトをcheckoutしてまるごとコピー
  2. 設定ファイル内容を変更
  3. 共通クラスやインターフェイスをのこして実装クラスを削除
  4. 具体的なサービス名がはいっている箇所を修正
  5. サンプルやテストの実装
  6. コンパイルエラー・テスト・起動チェック

これが1回だけならいいのですが、新しいサービスを作成するたびに何度もやるとなると非常に面倒です。
こんなときは、プロジェクトの初期構築を少しでも楽にするために、本稿で紹介するGiter8を使いましょう。

Giter8とは

Giter8は、GitHubなどのリポジトリ上にあるテンプレートを使ってファイルやディレクトリを生成するためのツールです。
特定の位置に配置されたファイルやディレクトリをテンプレートとして取得したり、
特定のファイル名やファイル内の文字を置換することもできます。
Giter8自体はけっこう前から存在していたのですが、2年ほど前にsbtがgiter8をサポートしてから再び注目されています。(主観)

環境

今回使用した動作環境は以下のとおりです。

  • OS : MacOS X 10.12.4

Giter8のインストール

ではGiter8をインストールしてみましょう。他の方法もありますが、Homebrewを使えば簡単にインストールできます。

% brew update && brew install giter8

テンプレートプロジェクトを作成してみる

では、Giter8をつかってテンプレート用プロジェクトを作成してみましょう。
「Giter8のテンプレートを作成するためのテンプレート」もGiter8で取得することができます。

g8テンプレートプロジェクト取得

% g8 foundweekends/giter8.g8
Creates a Giter8 project template.

name [My Template Project]: mytemplate.g8
giter8_version [0.11.0-M3]: <Enter>
sbt_version [1.1.1]: <Enter>

nameにはプロジェクト名を入力します。それ以外はそのままEnterを入力しましょう。
mytemplate.g8というプロジェクトが生成されます。

foundweekends/giter8.g8テンプレートではサンプルとしてScalaファイルがありますが、  
Giter8ではどんな言語/形式のプロジェクトでも使用可能です。

Giter8の基本

生成されたプロジェクトをみてみましょう。
テンプレートとなるディレクトリのルートはsrc/main/g8 ディレクトリになります。
※g8ディレクトリがなければルートディレクトリが使用される様子  

foundweekends/giter8.g8から生成したプロジェクトでは、Stub.scalaというサンプルファイルが用意されています。
では、この状態でmytemplate.g8を使用してプロジェクトを生成してみましょう。
Git上になくても、ローカルファイルを指定してプロジェクトを生成することが可能です。

% g8 file:///path/your/mytemplate.g8

g8コマンドを実行すると、mytemplate.g8/src/main/g8がルートとなるプロジェクトが生成されます。

default.properties

default.propertiesはprojectディレクトリ下かルートの直下に配置することができるキーバリュー形式のプロパティファイルです。
ここに記述されたキーは、g8コマンド実行時に値を入力し、後述するテンプレートフィールドを置換する文字列(置換したい文字は$name$のようにする)になります。

# default.properties例
name = Template Project
root = foo.bar.giter8sample
package = $root$.$name;format="lower,word"$

よく使用するフィールドは、下記のようなものがあります。

name

このフィールドはプロジェクト名に使われることが決まっている特別なフィールドです。
ファイル内の文字だけでなく、ファイル名・ディレクトリ名も置換対象になります。

package

packageも特別なフィールドで、ソースのパッケージ名となるフィールドです。
src/main/scala/$package$というディレクトリがあった場合、パッケージディレクトリ構造に展開されます。
例えば、packageフィールドにfoo.barという値に設定した場合には src/main/scala/foo/barと展開されます。

verbatim

このフィールドは、文字列置換対象となるファイルをexcludeするためのフィールドです。
blank区切りで指定されたファイルパターンを記述します。
例えば、「*.txt Foo.java」と記述した場合、すべてのtxtファイルとFoo.javaはフィールド文字列置換の対象外となります。

テンプレートフィールド

ファイル内のテンプレートフィールドは$で囲んで記述します。
テンプレートフィールドは先程の例(rootとpackage)のように、他のフィールドのデフォルト値を定義することも可能です。
ファイル名にテンプレートフィールドを指定することも可能です。
また、テンプレートフィールドにはフォーマットを指定することも可能です。詳しくはこちらをご確認ください。

mytemplate.g8を修正してみる

では、さきほど作成したmytemplate.g8を少し修正してみます。
まずはdefault.propertiesを下記のように修正します。

name=Template Project
root = foo.bar.giter8sample
package = $root$.$name;format="lower,word"$

次に、src/main/g8/src/main/scalaディレクトリ直下に「$package$」という名前のディレクトリを作成します。
そして、元々あったStub.scalaを「$name__Camel$Stub.scala」という名前にリネームして
$package$ディレクトリに移動しましょう。
内容も下記のように変更します。

package $package$

class $name;format="Camel"$Stub {
  // got any helpful boilerplate for your users?
}

上記のように、ディレクトリ名やファイル名、ファイル内のクラス名にもテンプレートフィールドを指定可能です。
ファイル名やディレクトリ名でフォーマットを使用するには__区切り、ファイル内でフォーマットを使用するには;format=・・・と記述します。

ファイル修正が完了したら、g8コマンドを実行してためしてみましょう。

% g8 file:///path/your/mytemplate.g8

なお、GitHub上にmytemplate.g8をpushしておけば、

% g8 <mytemplate.g8のGitHubリポジトリパス>

でプロジェクトを取得可能です。

生成されたプロジェクトをみてみると、nameやpackageで指定した値でパッケージが生成され、 scalaファイルやその内容も指定どおりになっています。

Giter8を使用する際の注意点

MFA対応
GitHubのprivateリポジトリでもGiter8は使用することは可能ですが、MFA対応していないようです。
MFAを使用して認証している場合にはg8プロジェクトをローカルにcloneして、ローカルファイルをg8で指定してください。

エスケープなど
ファイル内で「$」を使用している場合、テンプレートフィールドとの関係でエラ−になってしまいます。
「$」は「\$」にあらかじめ置換しておきましょう。
また、正規表現などで「\xxx」(バックスラッシュ2つ)は「\\xxx」(バックスラッシュ3つ)にしないとエラーになったので、そのあたりも注意してください。

まとめ

いかがでしたか。
最初にしっかりとテンプレートを作成しておけば、ディレクトリ名/ファイル名/ファイルの内容など、
面倒な修正作業もなくプロジェクト初期構築が簡単に実行できます。
とくに多数のサービスを作成する場合、Giter8はとても役立つツールになると思います。

なお、ここにはさまざまなタイプのテンプレートプロジェクトがすでに用意されているので、確認してみてください。

参考サイトなど