2011-04-14

Ant Cookbook

Property vs. Var

상수인 Property은 하위 Target 에게 보이지 않지만, 변수인 Var 는 보인다.

특정 확장자를 가진 파일만 삭제하기(recursive)

<delete>
    <fileset dir="${dir}/.." includes="**/*.js"/>
</delete>

특정 폴더 이하 모든 하위 폴더를 삭제하기(빈 폴더 포함)

<delete includeemptydirs="yes">
    <fileset dir="${dir}" includes="**/*"/>
</delete>

정규식을 이용해서 파일 이름 바꾸기

apply task 보다는 move task + regexpmapper 를 이용하면 간단하다. move 는 대상 폴더가 없으면 무조건 만들기 때문에 편하다!

<!--
<apply executable="mv">
    <fileset dir="${dir}" includes="*.png"/>
    -v"/>
    <srcfile/>
    <targetfile/>
    <regexpmapper from="^_\d\d\d\d_(.*)\.png$" to="${dir}/\1.png"/>
</apply>
-->

<move todir="${dir}">
    <fileset dir="${dir}" includes="*.png"/>
    <regexpmapper from="_\d\d\d\d_(.*)\.png" to="\1.png"/>
</move>

경로에서 부모 폴더(dirname)와 파일명(basename)으로 분리하기

basename 의 suffix 를 지정하면 확장자 없는 순수 파일명만 저장할 수 있다.

<dirname property="parentdir" file="${file}"/>
<basename property="basename" file="${file}" suffix=".png"/>

파일명에 정규식을 적용해서 속성에 저장하기

propertyregex 를 이용하면 된다. 이때 디폴트값을 정해줄 수도 있다.

<propertyregex property="output"
    input="${file}"
    regexp="(.+?)_(.+)"
    select="\2"
    defaultValue="${default}"/>

하위 폴더 각각에 대해서 특정 타겟을 실행하기

foreach task 를 이용하면 된다. 이때 dirset 은 항상 부모 폴더 자신(./)을 포함하는데, excludes=./ 등으로 자신을 제거할 수 없으므로, 아래처럼 includes=/* 으로 제외할 수 있다.

<foreach param="dir" target="xxx">
    <path>
        <dirset dir="${parentdir}" includes="*/**"/>
    </path>
</foreach>

Exec vs. Apply

exec 는 커맨드라인 명령을 1회 실행하지만, apply 는 특정 집합에 대해서 for 루프처럼 실행이 가능하다.
이때 arg value 는 -v 나 -f 같은 단일 파라미터이고, arg line 은 --output xxx 처럼 공백이 들어가는 긴 파라미터에 사용한다.
또한 regexpmapper 를 이용해서 targetfile 에 대해 정규식을 적용할 수도 있다.

<exec executable="${file.python}">
    <arg value="trim.py"/>
    <arg value="--verbose"/>
    json ${trim.dir}/anchor.json"/>
    <arg value="${trim.dir}"/>
</exec>
<apply executable="${file.python}">
    <fileset dir="${flip.dir}" includes="*.png" excludes="*.r.png"/>
    <arg value="flip.py"/>
    <arg value="--verbose"/>
    <arg value="-o"/>
    <targetfile/>
    <srcfile/>
    <regexpmapper from="(.*)\.png$" to="${flip.dir}/${flip.default}.png"/>
</apply>

파일 출력

echo task를 이용하면 화면 출력 뿐만 아니라, 파일에 임의의 문자열을 append를 할 수 있다. 이걸 이용하면 concat task 를 쓰지 않고도 header 나 footer 를 간단하게 넣을 수 있다.

<echo file="${script}" append="yes">
    sprites = sprites || {};
    sprites.data = sprites.data || {};
</echo>

파일 이어붙일 때 필터링하기

filterchain 을 이용해서 특정 문자열을 포함한 라인을 제거하거나, tokenfilter + replaceregex 를 이용해서 문자열을 바꿀 수도 있다.

<concat destfile="${script}" append="yes">
    <path>
        <filelist dir="${dir}" files="${json}" />
    </path>
    <filterchain>
        <linecontains negate="true">
            <contains value="trimmed"/>
        </linecontains>
        <tokenfilter>
            <!--
            <replaceregex pattern="\{"frames"\:" replace='sprites["${spritename}"] =' flags="g"/>
            -->
            <!-- remove .<span class="hiddenSpellError" pre="remove ">png</span> -->
            <replaceregex pattern="\.png" replace='' flags="g"/>
        </tokenfilter>
    </filterchain>
</concat>

파일을 복사하면서 이름 바꾸기

copy task 와 globmapper 를 쓰면 파일을 복사하면서 단순하게 이름을 바꿀 수 있다.

<copy todir="${destdir}">
    <fileset dir="${srcdir}" includes="*.png"/>
</copy>
<copy todir="${destdir}">
    <filelist dir="${srcdir}" files="${src}.js"/>
    <mapper type="glob" from="*.js" to="sprite.*.js"/>
</copy>

명령 실행시 입력 리다이렉트 적용하기

잘 알려지진 않았지만, 구글 앱엔진의 패스워드를 파일에 저장한 후, appcfg.py --passin < file 을 이용하면 자동화가 가능하다. ant 에서는 exec 의 inputstring 으로 대체할 수 있다.

<exec executable="appcfg.py" inputstring="${bulkload.pass}">
  <arg value="${bulkload.cmd}"/>
  <arg line="--application=${bulkload.appid}"/>
  <arg value="--config_file=${bulkload.config}"/>
  <arg value="--email=${bulkload.email}"/>
  <arg value="--url=${bulkload.url}"/>
  <arg value="--kind=${bulkload.kind}"/>
  <arg value="--filename=${bulkload.csv}"/>
  <arg value="--no_cookies"/>
  passin"/>
  <arg value="."/>
  </exec>

comments powered by Disqus