Mavenで環境ごとの設定ファイルを作成する
一人Web開発シリーズも認証で行き詰ったので閑話休題的に。
はじめに
複数環境の設定ファイルを作るのに、1つのテンプレートをベースにして差分だけを変数化するというのはよくやることです。
ChefやAnsibleなんかを使える環境にいればよいのですが、そうでない場合には簡単な置換ツールを自作したりするわけです。
手元にJava+Mavenな環境があるならこんな感じでもできそうかな、と調べたときのメモ。
前提
変数化する部分は階層を持たないこととします。
繰り返し要素が出てくるとかなら、素直にMustacheとかのテンプレートエンジンを使うとか、完全に自作するとかしたほうが早いです。
用意するもの
テンプレートファイルと、変数値を記載したプロパティファイルと、pom.xmlだけです。
pom.xml src main template httpd.conf props prod.properties dev.properties
ここではhttpd.confを例にしています。
# template/httpd.conf #==================== ServerRoot /etc/httpd ServerName ${server.name} Listen ${server.port} MaxClients ${server.worker.max}
# props/prod.properties #====================== server.name=prod.example.com server.port=80 server.worker.max=250
# props/dev.properties #====================== server.name=dev.example.com server.port=8080 server.worker.max=100
pom.xml
pom.xmlはこんな感じ。
環境ごとのプロパティファイルを読み込んで、resourceで置換するだけです。
<build> <plugins> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>properties-maven-plugin</artifactId> <version>1.0.0</version> <executions> <execution> <phase>initialize</phase> <goals> <goal>read-project-properties</goal> </goals> <configuration> <files> <file>src/main/props/${target.env}.properties</file> </files> </configuration> </execution> </executions> </plugin> </plugins> <outputDirectory>${project.build.directory}/${target.env}</outputDirectory> <resources> <resource> <directory>src/main/template</directory> <filtering>true</filtering> </resource> </resources> </build>
環境の指定は実行時にプロパティとして与えることにしています。
もちろん、まじめにprofileを書いてもよいと思います。
作成
実行はこんな感じ。
mvn -Dtarget.env=prod process-resources mvn -Dtarget.env=dev process-resources
これで下のようなファイルが出来上がります。
target prod httpd.conf dev httpd.conf
中身はプロパティの値で書き換わっています。
# target/prod/httpd.conf #======================= ServerRoot /etc/httpd ServerName prod.example.com Listen 80 MaxClients 250
# target/dev/httpd.conf #======================= ServerRoot /etc/httpd ServerName dev.example.com Listen 8080 MaxClients 100
めでたし、めでたし。
コマンド一発で出来ないとか、出力ディレクトリやファイル名に融通が利かないのはまぁ手抜きなので致し方なし。
あとはこれをシェルやらでラップしてあげればまぁそれとなく使える感じになるんではなかろうか。
ま、やってることは単なる文字列置換なので、シェルが使えるならシェルでやったほうが早いんじゃないの?とかそういうのはナシで。