我需要编写一个ant build,它从META-INF / manifest.mf文件读入现有版本并附加到它。
应该可以使用ANT 清单任务进行更新,但是我在阅读现有版本时遇到了问题。
由于清单条目是使用密钥:值而不是密钥 = 值我无法读取它们使用ANT的 loadproperties 任务。
有没有人这样做/有任何想法?
由于
答案 0 :(得分:8)
你需要小心使用清单上的<loadproperties>
:虽然它似乎使用短值,但是当行长度超过70个字符时它会失败,因为清单条目包含奇怪的方式。结果值将被截断。
我写了一个<scriptdef>
来做你所要求的,虽然还没有完全测试过。
<!--
Loads entries from a manifest file.
@jar The jar from where to read
@file A manifest file to read
@prefix A prefix to prepend
@section The name of the manifest section to load
-->
<scriptdef name="loadmf" language="javascript" loaderRef="sharedbuild-loaderRef">
<attribute name="jar" />
<attribute name="file" />
<attribute name="prefix" />
<attribute name="section" />
<![CDATA[
var jarname = attributes.get("jar");
var filename = attributes.get("file");
if (jarname != null && filename != null) {
self.fail("Only one of jar or file is required");
}
var prefix = attributes.get("prefix");
if (prefix == null) {
prefix = "";
}
var section = attributes.get("section");
var manifest;
if (jarname != null) {
var jarfile = new java.util.jar.JarFile(new java.io.File(jarname));
manifest = jarfile.getManifest();
} else if (filename != null) {
manifest = new java.util.jar.Manifest(new java.io.FileInputStream(new java.io.File(filename)));
} else {
self.fail("One of jar or file is required");
}
if (manifest == null) {
self.log("No manifest in " + jar);
} else {
var attributes = (section == null) ? manifest.getMainAttributes() : manifest.getAttributes(section);
if (attributes != null) {
var iter = attributes.entrySet().iterator();
while (iter.hasNext()) {
var entry = iter.next();
project.setProperty(prefix + entry.getKey(), entry.getValue());
}
}
}
]]>
</scriptdef>
我确信JavaScript可以改进 - 我不是专家 - 但它似乎对我来说运行得很好(运行AntUnit测试以确保我的OSGi清单正确创建。)作为额外奖励它从jar(或ear或war)文件或独立的清单文件加载。
答案 1 :(得分:2)
要从Manifest使用loadproperties grep一个键的值,这里有一个macrodef来帮助你前进=
<macrodef name="mfgrep">
<attribute name="jar"/>
<attribute name="key"/>
<attribute name="update"/>
<sequential>
<loadproperties>
<zipentry zipfile="@{jar}" name="META-INF/MANIFEST.MF"/>
</loadproperties>
<echo>@{key} => ${@{key}}</echo>
<jar jarfile="@{jar}">
<manifest>
<attribute name="@{key}" value="@{update}"/>
</manifest>
</jar>
</sequential>
</macrodef>
<!-- Grep a key from Manifest and update its value -->
<mfgrep
jar="/home/gilreb/temp/test.jar"
key="Manifest-Version"
update="2.0"
/>
您可以选择在loadproperties
中使用嵌套的过滤链答案 2 :(得分:1)
<manifest>
任务应该完全符合您的要求。它会将新的Manifest key = value对附加到现有的Manifest。知道为什么你不能使用它吗?
您可以将<concat>
任务与各种过滤器阅读器一起使用,然后使用<loadproperties>
任务加载结果。它需要一点肘部油脂,但它可能是一种以这种方式读取损坏的 Manifest文件,获取值,然后用这些旧值重写新Manifest文件的方法。
我必须查看现有Manifest的示例以及您要添加到其中的内容,以便准确了解您的需求。
答案 3 :(得分:1)
全部谢谢,
仅供参考,这是我的最终代码,经过测试工作
这会将修订号(第4个元素)附加到没有修订版本的版本,或者替换已有版本的修订版本。
<available file="META-INF/MANIFEST.MF" property="has.manifest" />
<target name="loadBundleVersion" if="has.manifest">
<!-- load version, if no current build number -->
<loadproperties srcfile="META-INF/MANIFEST.MF">
<filterchain>
<linecontainsregexp>
<regexp pattern="^Bundle-Version: \d*.\d*.\d*\s*$" />
</linecontainsregexp>
</filterchain>
</loadproperties>
</target>
<target name="loadBundleVersionRemoveBuild" unless="Bundle-Version" depends="loadBundleVersion">
<!-- if version not set here we have a current build number so needs to be stripped -->
<loadproperties srcfile="META-INF/MANIFEST.MF">
<filterchain>
<linecontains>
<contains value="Bundle-Version" />
</linecontains>
<tokenfilter>
<replaceregex pattern=".\d*$" replace="" />
</tokenfilter>
</filterchain>
</loadproperties>
</target>
<target name="loadBundleDetails" depends="loadBundleVersionRemoveBuild">
<loadproperties srcfile="META-INF/MANIFEST.MF">
<filterchain>
<linecontains>
<contains value="Bundle-SymbolicName" />
</linecontains>
</filterchain>
</loadproperties>
</target>
<target name="updateManifestVersion" if="has.manifest" depends="loadBundleDetails">
<manifest file="META-INF/MANIFEST.MF" mode="update">
<attribute name="Bundle-Version" value="${Bundle-Version}.${build.number}" />
</manifest>
</target>