ANT读取现有清单版本并附加到其中
我需要编写一个ant构建脚本,它从META-INF/manifest.mf文件中读取现有版本并附加到该文件中 应该可以使用ANT清单任务进行更新,但是我在读取现有版本时遇到了问题 由于清单条目是use key:value而不是key=value,我无法在使用ANT的loadproperties任务时读取它们 有人做过这个/有什么想法吗ANT读取现有清单版本并附加到其中,ant,build,manifest,Ant,Build,Manifest,我需要编写一个ant构建脚本,它从META-INF/manifest.mf文件中读取现有版本并附加到该文件中 应该可以使用ANT清单任务进行更新,但是我在读取现有版本时遇到了问题 由于清单条目是use key:value而不是key=value,我无法在使用ANT的loadproperties任务时读取它们 有人做过这个/有什么想法吗 感谢从清单使用loadproperties grep键的值,这里有一个宏定义让您开始= <macrodef name="mfgrep"> <
感谢从清单使用loadproperties grep键的值,这里有一个宏定义让您开始=
<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"
/>
@{key}=>${@{key}
或者,您可以在loadproperties中使用嵌套的筛选器链。任务应该完全按照您的要求执行。它将把新的清单键=值对附加到现有清单中。知道你为什么不能用它吗
您可以将
任务与各种过滤器读取器一起使用,然后使用
任务加载结果。这需要一点时间,但这可能是一种通过这种方式读取损坏的清单文件,获取值,然后用这些旧值重写新的清单文件的方法
我必须查看您现有清单的示例以及您想要添加的内容,以便准确地了解您需要什么。您需要小心地在清单上使用
:虽然它似乎适用于较短的值,但由于清单项的奇怪包装方式,当行长度超过70个字符时,它将失败。结果值被截断
我写了一个
,它可以满足您的要求,尽管它还没有完全测试过
<!--
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)文件或独立清单文件加载。谢谢大家
仅供参考,这是我的最终代码,已测试运行
这会将修订号(第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>
loadproperties for key colon value适用于我的Ant 1.8.1。我可以确认它适用于Ant 1.7.1。另外,我的问题是,一个文件检查阻止了它加载。谢谢David,正在运行一个简单的测试。我检查清单文件是否可用,阻止了loadproperty运行,所以我假设它不起作用。loadproperty确实可以与manifest一起工作,manifest任务也可以正常工作:)当然可以,但是line length>70个字符会带来麻烦,而且非常不舒服。我不确定您为什么认为它会带来麻烦,因为它是jar规范的标准部分。这并不像你想象的那么罕见;例如,OSGi通常会创建很长的清单条目。感谢您的提示-我没有想到这一点,所以通常loadproperties可以工作,但出于特殊目的,您需要使用脚本解决方案或自己的ant Task。使用JavaScript的另一个原因是支持多行类路径条目。似乎将其作为属性加载只需要第一行。@DavidNouls是的,我曾经遇到过一个问题,我遇到了Windows类路径长度限制,解决方法是在MANIFEST.MF中创建一个带有类路径的jar并使用它。