디렉토리의 각 파일에 대해 Ant 빌드 파일에서 명령을 실행하고 싶습니다.
플랫폼 독립적 인 솔루션을 찾고 있습니다.
어떻게해야합니까?
물론 일부 스크립팅 언어로 스크립트를 작성할 수 있지만 이렇게하면 프로젝트에 더 많은 종속성이 추가됩니다.
디렉토리의 각 파일에 대해 Ant 빌드 파일에서 명령을 실행하고 싶습니다.
플랫폼 독립적 인 솔루션을 찾고 있습니다.
어떻게해야합니까?
물론 일부 스크립팅 언어로 스크립트를 작성할 수 있지만 이렇게하면 프로젝트에 더 많은 종속성이 추가됩니다.
답변:
<foreach>
중첩과 함께 사용<FileSet>
Foreach에는 ant-contrib이 필요합니다 .
최근 ant-contrib에 대한 업데이트 된 예 :
<target name="foo">
<foreach target="bar" param="theFile">
<fileset dir="${server.src}" casesensitive="yes">
<include name="**/*.java"/>
<exclude name="**/*Test*"/>
</fileset>
</foreach>
</target>
<target name="bar">
<echo message="${theFile}"/>
</target>
이렇게하면 $ {theFile}로 대상 "bar"가 호출되어 현재 파일이 생성됩니다.
<apply> 작업을 사용합니다 .
각 파일에 대해 한 번씩 명령을 실행합니다. 파일 세트 또는 기타 리소스를 사용하여 파일을 지정합니다. <적용>이 내장되어 있습니다. 추가 종속성이 필요하지 않습니다. 사용자 지정 작업 구현이 필요하지 않습니다.
명령을 한 번만 실행하여 한 번에 모든 파일을 인수로 추가 할 수도 있습니다. 동작을 전환하려면 parallel 속성을 사용하십시오.
1 년 늦어서 죄송합니다.
ant-contrib 없는 접근 방식 은 Tassilo Horn 이 제안합니다 ( 원래 목표는 여기에 있음 ).
Basicly의 확장자가 없기 때문에 <자바> (아직?) 같은 방법으로하는 것이 <적용> 확장 <임원> , 그 사용에 제안 <적용> (또한 명령 줄에서 자바 programm에 실행 과정의 어느 캔)
다음은 몇 가지 예입니다.
<apply executable="java">
<arg value="-cp"/>
<arg pathref="classpath"/>
<arg value="-f"/>
<srcfile/>
<arg line="-o ${output.dir}"/>
<fileset dir="${input.dir}" includes="*.txt"/>
</apply>
javascript와 ant scriptdef 작업을 사용하여이 작업을 수행하는 방법은 다음과 같습니다. scriptdef가 핵심 ant 작업이므로이 코드가 작동하기 위해 ant-contrib이 필요하지 않습니다.
<scriptdef name="bzip2-files" language="javascript">
<element name="fileset" type="fileset"/>
<![CDATA[
importClass(java.io.File);
filesets = elements.get("fileset");
for (i = 0; i < filesets.size(); ++i) {
fileset = filesets.get(i);
scanner = fileset.getDirectoryScanner(project);
scanner.scan();
files = scanner.getIncludedFiles();
for( j=0; j < files.length; j++) {
var basedir = fileset.getDir(project);
var filename = files[j];
var src = new File(basedir, filename);
var dest= new File(basedir, filename + ".bz2");
bzip2 = self.project.createTask("bzip2");
bzip2.setSrc( src);
bzip2.setDestfile(dest );
bzip2.execute();
}
}
]]>
</scriptdef>
<bzip2-files>
<fileset id="test" dir="upstream/classpath/jars/development">
<include name="**/*.jar" />
</fileset>
</bzip2-files>
project
위의 예에서 변수 가 참조되었지만 사전 정의를 사용할 수 없습니다. 그것을 표현하거나 명확히하는 것이 좋을 것입니다. 편집 : n / m, project
현재 프로젝트에 액세스하기 위해 미리 정의 된 변수 임을 발견했습니다 . 나는 그것을 의심했지만 확실하지 않았습니다.
ant-contrib은 사악합니다. 사용자 지정 개미 작업을 작성합니다.
ant-contrib은 ant를 선언적 스타일에서 명령형 스타일로 변환하려고하기 때문에 악합니다. 그러나 xml은 쓰레기 프로그래밍 언어를 만듭니다.
반대로 사용자 지정 ant 작업을 사용하면 실제 IDE를 사용하여 실제 언어 (Java)로 작성할 수 있습니다. 여기서 단위 테스트를 작성하여 원하는 동작이 있는지 확인한 다음 빌드 스크립트에서 당신이 원하는 행동.
이 폭언은 유지 가능한 개미 스크립트를 작성하는 데 관심이있는 경우에만 중요합니다. 유지 관리에 대해 신경 쓰지 않는다면 작동하는 것은 무엇이든하십시오. :)
Jtf
나는이 포스트가 정말로 오래되었다는 것을 알고 있지만, 이제 약간의 시간과 개미 버전이 지나갔으므로 기본적인 개미 기능으로 이것을 할 수있는 방법이 있고 나는 그것을 공유해야한다고 생각했습니다.
중첩 된 작업을 호출하는 재귀 매크로 정의를 통해 수행됩니다 (다른 매크로도 호출 될 수 있음). 유일한 규칙은 고정 변수 이름 (여기에 요소)을 사용하는 것입니다.
<project name="iteration-test" default="execute" xmlns="antlib:org.apache.tools.ant" xmlns:if="ant:if" xmlns:unless="ant:unless">
<macrodef name="iterate">
<attribute name="list" />
<element name="call" implicit="yes" />
<sequential>
<local name="element" />
<local name="tail" />
<local name="hasMoreElements" />
<!-- unless to not get a error on empty lists -->
<loadresource property="element" unless:blank="@{list}" >
<concat>@{list}</concat>
<filterchain>
<replaceregex pattern="([^;]*).*" replace="\1" />
</filterchain>
</loadresource>
<!-- call the tasks that handle the element -->
<call />
<!-- recursion -->
<condition property="hasMoreElements">
<contains string="@{list}" substring=";" />
</condition>
<loadresource property="tail" if:true="${hasMoreElements}">
<concat>@{list}</concat>
<filterchain>
<replaceregex pattern="[^;]*;(.*)" replace="\1" />
</filterchain>
</loadresource>
<iterate list="${tail}" if:true="${hasMoreElements}">
<call />
</iterate>
</sequential>
</macrodef>
<target name="execute">
<fileset id="artifacts.fs" dir="build/lib">
<include name="*.jar" />
<include name="*.war" />
</fileset>
<pathconvert refid="artifacts.fs" property="artifacts.str" />
<echo message="$${artifacts.str}: ${artifacts.str}" />
<!-- unless is required for empty lists to not call the enclosed tasks -->
<iterate list="${artifacts.str}" unless:blank="${artifacts.str}">
<echo message="I see:" />
<echo message="${element}" />
</iterate>
<!-- local variable is now empty -->
<echo message="${element}" />
</target>
</project>
필요한 주요 기능 :
구분자 변수를 만들지 못했지만 이것은 큰 단점이 아닐 수도 있습니다.
ant-contrib 작업 "for"를 사용하여 구분 기호로 구분 된 파일 목록을 반복 할 수 있습니다. 기본 구분 기호는 ","입니다.
다음은이를 보여주는 샘플 파일입니다.
<project name="modify-files" default="main" basedir=".">
<taskdef resource="net/sf/antcontrib/antlib.xml"/>
<target name="main">
<for list="FileA,FileB,FileC,FileD,FileE" param="file">
<sequential>
<echo>Updating file: @{file}</echo>
<!-- Do something with file here -->
</sequential>
</for>
</target>
</project>