hatenob

プログラムって分からないことだらけ

Mavenで環境ごとの設定ファイルを作成する

一人Web開発シリーズも認証で行き詰ったので閑話休題的に。

はじめに

複数環境の設定ファイルを作るのに、1つのテンプレートをベースにして差分だけを変数化するというのはよくやることです。
ChefやAnsibleなんかを使える環境にいればよいのですが、そうでない場合には簡単な置換ツールを自作したりするわけです。
手元にJavaMavenな環境があるならこんな感じでもできそうかな、と調べたときのメモ。

前提

変数化する部分は階層を持たないこととします。
繰り返し要素が出てくるとかなら、素直に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

めでたし、めでたし。
コマンド一発で出来ないとか、出力ディレクトリやファイル名に融通が利かないのはまぁ手抜きなので致し方なし。
あとはこれをシェルやらでラップしてあげればまぁそれとなく使える感じになるんではなかろうか。
ま、やってることは単なる文字列置換なので、シェルが使えるならシェルでやったほうが早いんじゃないの?とかそういうのはナシで。