리소스 설정치환은 리소스 필터링과 리소스 교체로 나눌 수 있습니다. 이 중에서 리소스 필터링은 원본 리소스 파일을 타겟으로 복사하면서 파일 내의 특정 부분을 다른 문자열로 치환하는 방법입니다. Ant, Maven, Buildr에서 이것을 어떻게 처리하는지 살펴봅니다.
1. Ant는 copy 타스크 내부에서
filter 요소를 사용하여 리소스 필터링을 지원합니다. 보통 @토큰@ 형식으로 표현된 내용이 다른 값으로 치환됩니다.
<copy file="${build.dir}/version.txt" toFile="${dist.dir}/version.txt">
<filterset>
<filter token="DATE" value="${TODAY}"/>
<filtersfile file="${user.dir}/dist.properties"/> <!-- 이름/값 쌍을 프로퍼티 파일로 제공 -->
</filterset>
</copy>
2. Maven에서는 process-resources 단계(또는 '
resources:resources' 골)에서 보통 ${프로퍼티} 형식의 문자열이 실제 그 프로퍼티 값으로 바뀝니다.
<resources>
<resource>
<directory>src</directory>
<filtering>true</filtering>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
</resource>
</resources>
프로퍼티는 여러방식으로 제공됩니다. (1) 메이븐 실행시 -D를 통해서 제공 (2) properties 엘리먼트에 기술 (3) 프로퍼티 파일을 지정 (4) 시스템 프로퍼티. 프로퍼티 파일 형태로 이름/값 쌍을 제공하는 경우 아래처럼 build 밑에 filters 엘리먼트에 파일의 위치를 기술하면 됩니다.
<build>
<defaultGoal>install</defaultGoal>
<directory>${basedir}/target</directory>
<finalName>${artifactId}-${version}</finalName>
<filters>
<filter>filters/filter1.properties</filter>
</filters>
...
</build>
3. Buildr의 리소스 필터링은 메이븐과 유사합니다. Buildr에서는
resources 타스크를 통해 리소스의 내용을 필터링합니다. 기본적으로 src/main/resources 디렉토리의 리소스 파일들을 target/resources 디렉토리로 복사하면서 필터링을 수행합니다.
resources.from _('src/etc') # 원본 리소스 파일 디렉토리 변경
resources.include '*.html' # 포함할 파일 패턴
resources.exclude 'scratch/*' # 제외할 파일 패턴
resources.filter.using 'version'=>'experimental', 'copyright'=>'Acme Inc (C) 2007' # 치환될 내용 매핑
위의 예제에서 리소스 파일내의 ${copyright} 부분은 '
Acme Inc (C) 2007'로 바뀌게 됩니다. 이러한 이름/값 매핑은 당연히 외부 파일 형태로도 제공할 수 있습니다만, Buildr에서는 프로퍼티 형식이 아니라 buildr 파일과 동일한 위치에 있는
profiles.yaml 파일을 사용합니다. profiles.yaml 파일은 서로다른 환경에서 서로다른 설정을 가져가기 위한 것인데요(메이븐의 그것과 똑같은 개념입니다), 여기에 filter 엘리먼트를 추가하면 됩니다.
filter: &alpha1
version: experimental
copyright: Acme Inc (C) 2007
development:
filter: *alpha1
test:
filter: *alpha1
resources 타스크는 compile 타스크 실행시 자동으로 함께 수행됩니다. 아래처럼하면 단독으로 실행됩니다.
buildr 프로젝트이름:resources
그런데 이 리소스 필터링 기능이 resources 타스크가 실행될 때뿐 아니라 빌드의 다른 곳에서도 필요한 경우가 있습니다. 이때는 resources 타스크가 내부적으로 이용하고 있는 filter를 사용하면 됩니다.
filter('src/specs').into('target/specs').
using('version'=>version, 'created'=>Time.now).run