環境差分をantで吸収する

Webアプリをantでデプロイするときなど、各環境用のbuild.xmlを作っているでしょうか？
それとも各環境用にbuild.xmlをその場で修正しているでしょうか。

引数で指定するだけで各環境用にプロパティを変えるようにすれば、
build.xmlの修正が１ファイルだけになり、
リリースミスも減らすことができると思います。

```xml:build.xml
<!-- ====================================================================== -->
<!-- 引数チェック後、各環境用のプロパティをセットします -->
<!-- プロパティの値に応じてデプロイ先を変更します -->
<target name="deploy" depends="check,unittest-environment,systemtest-environment,release-environment">
    <deploy url="${deploy.url}"
            username="${deploy.user}"
             password="${deploy.pass}"
             path="/app"
             war="app.war" />
</target>


<!-- ====================================================================== -->
<!-- どの環境向けにデプロイするのか、引数をチェックします。 -->
<target name="check">

  <!--
    -- 引数の指定がない場合は、エラーメッセージをはきます。
    -- （エラーメッセージはもうちょっと丁寧にすると親切です）
    -->
  <fail message="target property is invalid">
    <condition>
        <not>
            <or>
                <equals arg1="${target}" arg2="unittest" />
                <equals arg1="${target}" arg2="systemtest" />
                <equals arg1="${target}" arg2="release" />
            </or>
        </not>
    </condition>
  </fail>

  <!-- 引数にセットされている値に応じて、 env.*** を true にします -->
  <condition property="env.unittest" value="true">
      <equals arg1="${target}" arg2="unittest" />
  </condition>

  <condition property="env.systemtest" value="true">
      <equals arg1="${target}" arg2="systemtest" />
  </condition>

  <condition property="env.release" value="true">
      <equals arg1="${target}" arg2="release" />
  </condition>
</target>


<!-- ====================================================================== -->
<!-- 単体試験、総合試験、リリースのためのプロパティを定義します -->
<!-- env.*** の値が true のときのみ、ここは実行されます -->
<target name="unittest-environment" if="env.unittest">
    <echo>----------------------------------------</echo>
    <echo> Unittest Environment</echo>
    <echo>----------------------------------------</echo>
    <property name="deploy.url" value="http'//unittest-env:8080/manager/text" />
    <property name="deploy.user" value="admin" />
    <property name="deploy.pass" value="password" />
</target>

<target name="systemtest-environment" if="env.systemtest">
    <echo>----------------------------------------</echo>
    <echo> Systemtest Environment</echo>
    <echo>----------------------------------------</echo>
    <property name="deploy.url" value="http'//systemtest-env:8080/manager/text" />
    <property name="deploy.user" value="admin" />
    <property name="deploy.pass" value="password" />
</target>

<target name="release-environment" if="env.release">
    <echo>----------------------------------------</echo>
    <echo> Release Environment</echo>
    <echo>----------------------------------------</echo>
    <property name="deploy.url" value="http'//release-env:8080/manager/text" />
    <property name="deploy.user" value="admin" />
    <property name="deploy.pass" value="password" />
</target>
```


これでコマンドラインから

```
ant -Dtarget=unittest deploy
```

とやると、単体試験環境用のプロパティを元に、単体試験用のサーバにデプロイすることになります。
build.xmlを修正する必要がないため、リリース時の操作ミスを減らすことができます。
また、 -D の指定を忘れるとエラーメッセージが出て操作が中断するので、単純ミスも減ります。



## 応用例

replace を使うことで、ソースコードやプロパティファイルの中身を変更することができます。


元ファイル

```properties:application.properties
db.server=@@db-servrer@@
```


build.xml

```xml:build.xml
<target name="copy" depends="check,unittest-environment,systemtest-environment,release-environment">
    <replace file="application.properties" token="@@db-server@@" value="${db.server}" />
</target>
```


ビルド後（例）

```properties:application.properties
db.server=unittest-db-server
```