Giter8でテンプレートプロジェクトを作成する
新しくプロジェクトを作成する場合
既存のマイクロサービスがあり、新たにサービスを実装することになったとします。
サービスを同じアーキテクチャで実装する場合、私は下記のようにしていました。
※GitHub上のリポジトリにJavaのプロジェクトがあると仮定
- 既存プロジェクトをcheckoutしてまるごとコピー
- 設定ファイル内容を変更
- 共通クラスやインターフェイスをのこして実装クラスを削除
- 具体的なサービス名がはいっている箇所を修正
- サンプルやテストの実装
- コンパイルエラー・テスト・起動チェック
これが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はとても役立つツールになると思います。
なお、ここにはさまざまなタイプのテンプレートプロジェクトがすでに用意されているので、確認してみてください。