2013/05/06
antでファイル一覧を生成する。
JavaScriptで1クラス=1ファイルでコードを書いていると .js ファイルが沢山できる。
これを一々、<script>
タグにして HTML に埋め込むのが以外に面倒くさい。
で、ant の fileset で何とかならないかと思って調べてみたらこうなった。
<taskdef resource="net/sf/antcontrib/antcontrib.properties">
<classpath>
<pathelement location="${project.root}/lib/ant-contrib-1.0b3.jar"/>
</classpath>
</taskdef>
<target name="main">
<antcall target="makeListFile">
<param name="includes" value="**/*.js"/>
<param name="file" value="html.txt"/>
<param name="prefix" value="<script src='"/>
<param name="suffix" value="'/>"/>
</antcall>
</target>
<target name="makeListFile">
<fileset id="fileset" dir=".">
<include name="${includes}" />
</fileset>
<pathconvert property="files" refid="fileset" pathsep=";" dirsep="/" >
<map from="${basedir}/" to="" />
</pathconvert>
<echo file="${file}"></echo>
<foreach target="addLine" param="name" inheritall="true"
list="${files}" delimiter=";"
>
</foreach>
</target>
<target name="addLine">
<echo append="true" file="${file}">${prefix}${name}${suffix}
</echo>
</target>
面倒くせー。 そもそも contrib ずっとベータだし。
次に script タグを試して見ようと思って見付けたのがこちらのサンプル。
<?xml version="1.0" encoding="ISO-8859-1"?>
<project name="MyProject" basedir="." default="main">
<property name="fs.dir" value="src"/>
<property name="fs.includes" value="**/*.txt"/>
<property name="fs.excludes" value="**/*.tmp"/>
<target name="main">
<script language="javascript"> <![CDATA[
// import statements
// importPackage(java.io);
importClass(java.io.File);
// Access to Ant-Properties by their names
dir = project.getProperty("fs.dir");
includes = MyProject.getProperty("fs.includes");
excludes = self.getProject() .getProperty("fs.excludes");
// Create a <fileset dir="" includes=""/>
fs = project.createDataType("fileset");
fs.setDir( new File(dir) );
fs.setIncludes(includes);
fs.setExcludes(excludes);
// Get the files (array) of that fileset
ds = fs.getDirectoryScanner(project);
srcFiles = ds.getIncludedFiles();
// iterate over that array
for (i=0; i<srcFiles.length; i++) {
// get the values via Java API
var basedir = fs.getDir(project);
var filename = srcFiles[i];
var file = new File(basedir, filename);
var size = file.length();
// create and use a Task via Ant API
echo = MyProject.createTask("echo");
echo.setMessage(filename + ": " + size + " byte");
echo.perform();
}
]]></script>
</target>
</project>
もっと面倒くせー orz
結局、自前でスクリプトを呼ぶTask書くのが早いんじゃね、と思って作ったのがこれ。
package jstask;
import java.io.File;
import java.util.*;
import org.apache.tools.ant.*;
import org.apache.tools.ant.types.*;
import org.apache.tools.ant.types.resources.FileResource;
import org.mozilla.javascript.*;
public class JsTask extends Task {
private List<ResourceCollection> rclist = new ArrayList<ResourceCollection>();
private List<Parameter> params = new ArrayList<Parameter>();
private String text;
public void add(ResourceCollection rc) {
rclist.add(rc);
}
public void addParam(Parameter param) {
params.add(param);
}
public void addText(String str) {
text = str;
}
@Override
public void execute() throws BuildException {
Context cx = Context.enter();
try {
Scriptable scope = cx.initStandardObjects();
scope.put("task", scope, this);
scope.put("fileset", scope, toFileList(rclist));
for (Parameter param : params) {
scope.put(param.getName(), scope, param.getValue());
}
cx.evaluateString(scope, text, "ant.js", 0, null);
} finally {
Context.exit();
}
}
private List<File> toFileList(List<ResourceCollection> rclist) {
List<File> filelist = new ArrayList<File>();
for (ResourceCollection rc : rclist) {
for (Iterator<?> ite = rc.iterator(); ite.hasNext();) {
Resource resource = (Resource) ite.next();
if (resource instanceof FileResource) {
File file = ((FileResource) resource).getFile();
filelist.add(file);
}
}
}
return filelist;
}
}
使用例:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project basedir="." default="test" name="test">
<taskdef name="js"
classname="jstask.JsTask"
classpath="lib/jstask.js;lib/js.jar"
/>
<target name="test">
<js>
<fileset dir="src" includes="**/*.js" />
<param name="prefix" value="^${basedir}/" />
<param name="outfile" value="html.txt" />
<![CDATA[
var out = new java.io.FileWriter(outfile);
var ite = fileset.iterator();
while (ite.hasNext()) {
var reg = new RegExp(prefix);
var fname = (""+ite.next()).replace(reg,"");
out.write("<script src='"+fname+"'></script>\n");
}
out.close();
]]>
</js>
</target>
</project>
結局これが一番簡単だった...
この投稿へのコメント

コメント・フォーム