git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@806174 13f79535-47bb-0310-9956-ffa450edef68master
@@ -439,6 +439,14 @@ Fixed bugs: | |||||
* The update attribute of the modified selector was ignored. | * The update attribute of the modified selector was ignored. | ||||
Bugzilla Report 32597. | Bugzilla Report 32597. | ||||
* <manifest> and <jar> can now merge Class-Path attributes from | |||||
multiple sources and optionally flatten them into a single | |||||
attribute. | |||||
The default behaviour still is to keep multiple Class-Path | |||||
attributes if they have been specified and to only include the | |||||
attributes of the last merged manifest. | |||||
Bugzilla Report 39655. | |||||
Other changes: | Other changes: | ||||
-------------- | -------------- | ||||
* The get task now also follows redirects from http to https | * The get task now also follows redirects from http to https | ||||
@@ -245,6 +245,25 @@ to a value other than its default, <code>"add"</code>.</b></p> | |||||
zip task page</a></td> | zip task page</a></td> | ||||
<td align="center" valign="top">No, default is false</td> | <td align="center" valign="top">No, default is false</td> | ||||
</tr> | </tr> | ||||
<tr> | |||||
<td valign="top">mergeClassPathAttributes</td> | |||||
<td valign="top">Whether to merge the Class-Path attributes found | |||||
in different manifests (if merging manifests). If false, only | |||||
the attribute of the last merged manifest will be preserved. | |||||
<em>Since Ant 1.8.0</em>. | |||||
<br/>unless you also set flattenAttributes to true this may | |||||
result in manifests containing multiple Class-Path attributes | |||||
which violates the manifest specification.</td> | |||||
<td align="center" valign="top">No, default is false</td> | |||||
</tr> | |||||
<tr> | |||||
<td valign="top">flattenAttributes</td> | |||||
<td valign="top">Whether to merge attributes occuring more than | |||||
once in a section (this can only happen for the Class-Path | |||||
attribute) into a single attribute. | |||||
<em>Since Ant 1.8.0</em>.</td> | |||||
<td align="center" valign="top">No, default is false</td> | |||||
</tr> | |||||
</table> | </table> | ||||
<h3>Nested elements</h3> | <h3>Nested elements</h3> | ||||
@@ -301,6 +301,25 @@ to a value other than its default, <code>"add"</code>.</b></p> | |||||
zip task page</a></td> | zip task page</a></td> | ||||
<td align="center" valign="top">No, default is false</td> | <td align="center" valign="top">No, default is false</td> | ||||
</tr> | </tr> | ||||
<tr> | |||||
<td valign="top">mergeClassPathAttributes</td> | |||||
<td valign="top">Whether to merge the Class-Path attributes found | |||||
in different manifests (if merging manifests). If false, only | |||||
the attribute of the last merged manifest will be preserved. | |||||
<em>Since Ant 1.8.0</em>. | |||||
<br/>unless you also set flattenAttributes to true this may | |||||
result in manifests containing multiple Class-Path attributes | |||||
which violates the manifest specification.</td> | |||||
<td align="center" valign="top">No, default is false</td> | |||||
</tr> | |||||
<tr> | |||||
<td valign="top">flattenAttributes</td> | |||||
<td valign="top">Whether to merge attributes occuring more than | |||||
once in a section (this can only happen for the Class-Path | |||||
attribute) into a single attribute. | |||||
<em>Since Ant 1.8.0</em>.</td> | |||||
<td align="center" valign="top">No, default is false</td> | |||||
</tr> | |||||
</table> | </table> | ||||
<h3>Nested elements</h3> | <h3>Nested elements</h3> | ||||
@@ -82,6 +82,25 @@ line.</p> | |||||
manifest.</td> | manifest.</td> | ||||
<td valign="top" align="center">No, defaults to UTF-8 encoding.</td> | <td valign="top" align="center">No, defaults to UTF-8 encoding.</td> | ||||
</tr> | </tr> | ||||
<tr> | |||||
<td valign="top">mergeClassPathAttributes</td> | |||||
<td valign="top">Whether to merge the Class-Path attributes found | |||||
in different manifests (if updating). If false, only the | |||||
attribute of the most recent manifest will be preserved. | |||||
<em>Since Ant 1.8.0</em>. | |||||
<br/>unless you also set flattenAttributes to true this may | |||||
result in manifests containing multiple Class-Path attributes | |||||
which violates the manifest specification.</td> | |||||
<td align="center" valign="top">No, default is false</td> | |||||
</tr> | |||||
<tr> | |||||
<td valign="top">flattenAttributes</td> | |||||
<td valign="top">Whether to merge attributes occuring more than | |||||
once in a section (this can only happen for the Class-Path | |||||
attribute) into a single attribute. | |||||
<em>Since Ant 1.8.0</em>.</td> | |||||
<td align="center" valign="top">No, default is false</td> | |||||
</tr> | |||||
</table> | </table> | ||||
<h3>Nested elements</h3> | <h3>Nested elements</h3> | ||||
@@ -248,6 +248,25 @@ to a value other than its default, <code>"add"</code>.</b></p> | |||||
zip task page</a></td> | zip task page</a></td> | ||||
<td align="center" valign="top">No, default is false</td> | <td align="center" valign="top">No, default is false</td> | ||||
</tr> | </tr> | ||||
<tr> | |||||
<td valign="top">mergeClassPathAttributes</td> | |||||
<td valign="top">Whether to merge the Class-Path attributes found | |||||
in different manifests (if merging manifests). If false, only | |||||
the attribute of the last merged manifest will be preserved. | |||||
<em>Since Ant 1.8.0</em>. | |||||
<br/>unless you also set flattenAttributes to true this may | |||||
result in manifests containing multiple Class-Path attributes | |||||
which violates the manifest specification.</td> | |||||
<td align="center" valign="top">No, default is false</td> | |||||
</tr> | |||||
<tr> | |||||
<td valign="top">flattenAttributes</td> | |||||
<td valign="top">Whether to merge attributes occuring more than | |||||
once in a section (this can only happen for the Class-Path | |||||
attribute) into a single attribute. | |||||
<em>Since Ant 1.8.0</em>.</td> | |||||
<td align="center" valign="top">No, default is false</td> | |||||
</tr> | |||||
</table> | </table> | ||||
<h3>Nested elements</h3> | <h3>Nested elements</h3> | ||||
@@ -157,6 +157,16 @@ public class Jar extends Zip { | |||||
// CheckStyle:LineLength ON | // CheckStyle:LineLength ON | ||||
/** | |||||
* whether to merge Class-Path attributes. | |||||
*/ | |||||
private boolean mergeClassPaths = false; | |||||
/** | |||||
* whether to flatten Class-Path attributes into a single one. | |||||
*/ | |||||
private boolean flattenClassPaths = false; | |||||
/** | /** | ||||
* Extra fields needed to make Solaris recognize the archive as a jar file. | * Extra fields needed to make Solaris recognize the archive as a jar file. | ||||
* | * | ||||
@@ -268,7 +278,7 @@ public class Jar extends Zip { | |||||
if (configuredManifest == null) { | if (configuredManifest == null) { | ||||
configuredManifest = newManifest; | configuredManifest = newManifest; | ||||
} else { | } else { | ||||
configuredManifest.merge(newManifest); | |||||
configuredManifest.merge(newManifest, false, mergeClassPaths); | |||||
} | } | ||||
savedConfiguredManifest = configuredManifest; | savedConfiguredManifest = configuredManifest; | ||||
} | } | ||||
@@ -473,6 +483,24 @@ public class Jar extends Zip { | |||||
} | } | ||||
} | } | ||||
/** | |||||
* Whether to merge Class-Path attributes. | |||||
* | |||||
* @since Ant 1.8.0 | |||||
*/ | |||||
public void setMergeClassPathAttributes(boolean b) { | |||||
mergeClassPaths = b; | |||||
} | |||||
/** | |||||
* Whether to flatten multi-valued attributes (i.e. Class-Path) | |||||
* into a single one. | |||||
* | |||||
* @since Ant 1.8.0 | |||||
*/ | |||||
public void setFlattenAttributes(boolean b) { | |||||
flattenClassPaths = b; | |||||
} | |||||
/** | /** | ||||
* Initialize the zip output stream. | * Initialize the zip output stream. | ||||
@@ -512,11 +540,13 @@ public class Jar extends Zip { | |||||
*/ | */ | ||||
if (isInUpdateMode()) { | if (isInUpdateMode()) { | ||||
finalManifest.merge(originalManifest); | |||||
finalManifest.merge(originalManifest, false, mergeClassPaths); | |||||
} | } | ||||
finalManifest.merge(filesetManifest); | |||||
finalManifest.merge(configuredManifest, !mergeManifestsMain); | |||||
finalManifest.merge(manifest, !mergeManifestsMain); | |||||
finalManifest.merge(filesetManifest, false, mergeClassPaths); | |||||
finalManifest.merge(configuredManifest, !mergeManifestsMain, | |||||
mergeClassPaths); | |||||
finalManifest.merge(manifest, !mergeManifestsMain, | |||||
mergeClassPaths); | |||||
return finalManifest; | return finalManifest; | ||||
@@ -540,7 +570,7 @@ public class Jar extends Zip { | |||||
ByteArrayOutputStream baos = new ByteArrayOutputStream(); | ByteArrayOutputStream baos = new ByteArrayOutputStream(); | ||||
OutputStreamWriter osw = new OutputStreamWriter(baos, Manifest.JAR_ENCODING); | OutputStreamWriter osw = new OutputStreamWriter(baos, Manifest.JAR_ENCODING); | ||||
PrintWriter writer = new PrintWriter(osw); | PrintWriter writer = new PrintWriter(osw); | ||||
manifest.write(writer); | |||||
manifest.write(writer, flattenClassPaths); | |||||
if (writer.checkError()) { | if (writer.checkError()) { | ||||
throw new IOException("Encountered an error writing the manifest"); | throw new IOException("Encountered an error writing the manifest"); | ||||
} | } | ||||
@@ -724,7 +754,7 @@ public class Jar extends Zip { | |||||
if (filesetManifest == null) { | if (filesetManifest == null) { | ||||
filesetManifest = newManifest; | filesetManifest = newManifest; | ||||
} else { | } else { | ||||
filesetManifest.merge(newManifest); | |||||
filesetManifest.merge(newManifest, false, mergeClassPaths); | |||||
} | } | ||||
} catch (UnsupportedEncodingException e) { | } catch (UnsupportedEncodingException e) { | ||||
throw new BuildException("Unsupported encoding while reading " | throw new BuildException("Unsupported encoding while reading " | ||||
@@ -304,16 +304,37 @@ public class Manifest { | |||||
} | } | ||||
/** | /** | ||||
* Write the attribute out to a print writer. | |||||
* Write the attribute out to a print writer without | |||||
* flattening multi-values attributes (i.e. Class-Path). | |||||
* | * | ||||
* @param writer the Writer to which the attribute is written | * @param writer the Writer to which the attribute is written | ||||
* | * | ||||
* @throws IOException if the attribute value cannot be written | * @throws IOException if the attribute value cannot be written | ||||
*/ | */ | ||||
public void write(PrintWriter writer) throws IOException { | public void write(PrintWriter writer) throws IOException { | ||||
write(writer, false); | |||||
} | |||||
/** | |||||
* Write the attribute out to a print writer. | |||||
* | |||||
* @param writer the Writer to which the attribute is written | |||||
* @param flatten whether to collapse multi-valued attributes | |||||
* (i.e. potentially Class-Path) Class-Path into a | |||||
* single attribute. | |||||
* | |||||
* @throws IOException if the attribute value cannot be written | |||||
* @since Ant 1.8.0 | |||||
*/ | |||||
public void write(PrintWriter writer, boolean flatten) | |||||
throws IOException { | |||||
if (!flatten) { | |||||
for (Enumeration e = getValues(); e.hasMoreElements();) { | for (Enumeration e = getValues(); e.hasMoreElements();) { | ||||
writeValue(writer, (String) e.nextElement()); | writeValue(writer, (String) e.nextElement()); | ||||
} | } | ||||
} else { | |||||
writeValue(writer, getValue()); | |||||
} | |||||
} | } | ||||
/** | /** | ||||
@@ -448,13 +469,27 @@ public class Manifest { | |||||
} | } | ||||
/** | /** | ||||
* Merge in another section | |||||
* Merge in another section without merging Class-Path attributes. | |||||
* | * | ||||
* @param section the section to be merged with this one. | * @param section the section to be merged with this one. | ||||
* | * | ||||
* @throws ManifestException if the sections cannot be merged. | * @throws ManifestException if the sections cannot be merged. | ||||
*/ | */ | ||||
public void merge(Section section) throws ManifestException { | public void merge(Section section) throws ManifestException { | ||||
merge(section, false); | |||||
} | |||||
/** | |||||
* Merge in another section | |||||
* | |||||
* @param section the section to be merged with this one. | |||||
* @param mergeClassPaths whether Class-Path attributes should | |||||
* be merged. | |||||
* | |||||
* @throws ManifestException if the sections cannot be merged. | |||||
*/ | |||||
public void merge(Section section, boolean mergeClassPaths) | |||||
throws ManifestException { | |||||
if (name == null && section.getName() != null | if (name == null && section.getName() != null | ||||
|| name != null | || name != null | ||||
&& !(name.equalsIgnoreCase(section.getName()))) { | && !(name.equalsIgnoreCase(section.getName()))) { | ||||
@@ -484,7 +519,16 @@ public class Manifest { | |||||
} | } | ||||
if (classpathAttribute != null) { | if (classpathAttribute != null) { | ||||
// the merge file *always* wins, even for Class-Path | |||||
if (mergeClassPaths) { | |||||
Attribute currentCp = getAttribute(ATTRIBUTE_CLASSPATH); | |||||
if (currentCp != null) { | |||||
for (Enumeration attribEnum = currentCp.getValues(); | |||||
attribEnum.hasMoreElements(); ) { | |||||
String value = (String) attribEnum.nextElement(); | |||||
classpathAttribute.addValue(value); | |||||
} | |||||
} | |||||
} | |||||
storeAttribute(classpathAttribute); | storeAttribute(classpathAttribute); | ||||
} | } | ||||
@@ -496,13 +540,30 @@ public class Manifest { | |||||
} | } | ||||
/** | /** | ||||
* Write the section out to a print writer. | |||||
* Write the section out to a print writer without flattening | |||||
* multi-values attributes (i.e. Class-Path). | |||||
* | * | ||||
* @param writer the Writer to which the section is written | * @param writer the Writer to which the section is written | ||||
* | * | ||||
* @throws IOException if the section cannot be written | * @throws IOException if the section cannot be written | ||||
*/ | */ | ||||
public void write(PrintWriter writer) throws IOException { | public void write(PrintWriter writer) throws IOException { | ||||
write(writer, false); | |||||
} | |||||
/** | |||||
* Write the section out to a print writer. | |||||
* | |||||
* @param writer the Writer to which the section is written | |||||
* @param flatten whether to collapse multi-valued attributes | |||||
* (i.e. potentially Class-Path) Class-Path into a | |||||
* single attribute. | |||||
* | |||||
* @throws IOException if the section cannot be written | |||||
* @since Ant 1.8.0 | |||||
*/ | |||||
public void write(PrintWriter writer, boolean flatten) | |||||
throws IOException { | |||||
if (name != null) { | if (name != null) { | ||||
Attribute nameAttr = new Attribute(ATTRIBUTE_NAME, name); | Attribute nameAttr = new Attribute(ATTRIBUTE_NAME, name); | ||||
nameAttr.write(writer); | nameAttr.write(writer); | ||||
@@ -511,7 +572,7 @@ public class Manifest { | |||||
while (e.hasMoreElements()) { | while (e.hasMoreElements()) { | ||||
String key = (String) e.nextElement(); | String key = (String) e.nextElement(); | ||||
Attribute attribute = getAttribute(key); | Attribute attribute = getAttribute(key); | ||||
attribute.write(writer); | |||||
attribute.write(writer, flatten); | |||||
} | } | ||||
writer.print(EOL); | writer.print(EOL); | ||||
} | } | ||||
@@ -863,6 +924,7 @@ public class Manifest { | |||||
/** | /** | ||||
* Merge the contents of the given manifest into this manifest | * Merge the contents of the given manifest into this manifest | ||||
* without merging Class-Path attributes. | |||||
* | * | ||||
* @param other the Manifest to be merged with this one. | * @param other the Manifest to be merged with this one. | ||||
* | * | ||||
@@ -875,6 +937,7 @@ public class Manifest { | |||||
/** | /** | ||||
* Merge the contents of the given manifest into this manifest | * Merge the contents of the given manifest into this manifest | ||||
* without merging Class-Path attributes. | |||||
* | * | ||||
* @param other the Manifest to be merged with this one. | * @param other the Manifest to be merged with this one. | ||||
* @param overwriteMain whether to overwrite the main section | * @param overwriteMain whether to overwrite the main section | ||||
@@ -885,11 +948,31 @@ public class Manifest { | |||||
*/ | */ | ||||
public void merge(Manifest other, boolean overwriteMain) | public void merge(Manifest other, boolean overwriteMain) | ||||
throws ManifestException { | throws ManifestException { | ||||
merge(other, overwriteMain, false); | |||||
} | |||||
/** | |||||
* Merge the contents of the given manifest into this manifest | |||||
* | |||||
* @param other the Manifest to be merged with this one. | |||||
* @param overwriteMain whether to overwrite the main section | |||||
* of the current manifest | |||||
* @param mergeClassPaths whether Class-Path attributes should be | |||||
* merged. | |||||
* | |||||
* @throws ManifestException if there is a problem merging the | |||||
* manifest according to the Manifest spec. | |||||
* | |||||
* @since Ant 1.8.0 | |||||
*/ | |||||
public void merge(Manifest other, boolean overwriteMain, | |||||
boolean mergeClassPaths) | |||||
throws ManifestException { | |||||
if (other != null) { | if (other != null) { | ||||
if (overwriteMain) { | if (overwriteMain) { | ||||
mainSection = (Section) other.mainSection.clone(); | mainSection = (Section) other.mainSection.clone(); | ||||
} else { | } else { | ||||
mainSection.merge(other.mainSection); | |||||
mainSection.merge(other.mainSection, mergeClassPaths); | |||||
} | } | ||||
if (other.manifestVersion != null) { | if (other.manifestVersion != null) { | ||||
@@ -907,20 +990,36 @@ public class Manifest { | |||||
addConfiguredSection((Section) otherSection.clone()); | addConfiguredSection((Section) otherSection.clone()); | ||||
} | } | ||||
} else { | } else { | ||||
ourSection.merge(otherSection); | |||||
ourSection.merge(otherSection, mergeClassPaths); | |||||
} | } | ||||
} | } | ||||
} | } | ||||
} | } | ||||
/** | |||||
* Write the manifest out to a print writer without flattening | |||||
* multi-values attributes (i.e. Class-Path). | |||||
* | |||||
* @param writer the Writer to which the manifest is written | |||||
* | |||||
* @throws IOException if the manifest cannot be written | |||||
*/ | |||||
public void write(PrintWriter writer) throws IOException { | |||||
write(writer, false); | |||||
} | |||||
/** | /** | ||||
* Write the manifest out to a print writer. | * Write the manifest out to a print writer. | ||||
* | * | ||||
* @param writer the Writer to which the manifest is written | * @param writer the Writer to which the manifest is written | ||||
* @param flatten whether to collapse multi-valued attributes | |||||
* (i.e. potentially Class-Path) Class-Path into a single | |||||
* attribute. | |||||
* | * | ||||
* @throws IOException if the manifest cannot be written | * @throws IOException if the manifest cannot be written | ||||
* @since Ant 1.8.0 | |||||
*/ | */ | ||||
public void write(PrintWriter writer) throws IOException { | |||||
public void write(PrintWriter writer, boolean flatten) throws IOException { | |||||
writer.print(ATTRIBUTE_MANIFEST_VERSION + ": " + manifestVersion + EOL); | writer.print(ATTRIBUTE_MANIFEST_VERSION + ": " + manifestVersion + EOL); | ||||
String signatureVersion | String signatureVersion | ||||
= mainSection.getAttributeValue(ATTRIBUTE_SIGNATURE_VERSION); | = mainSection.getAttributeValue(ATTRIBUTE_SIGNATURE_VERSION); | ||||
@@ -929,7 +1028,7 @@ public class Manifest { | |||||
+ signatureVersion + EOL); | + signatureVersion + EOL); | ||||
mainSection.removeAttribute(ATTRIBUTE_SIGNATURE_VERSION); | mainSection.removeAttribute(ATTRIBUTE_SIGNATURE_VERSION); | ||||
} | } | ||||
mainSection.write(writer); | |||||
mainSection.write(writer, flatten); | |||||
// add it back | // add it back | ||||
if (signatureVersion != null) { | if (signatureVersion != null) { | ||||
@@ -946,7 +1045,7 @@ public class Manifest { | |||||
while (e.hasMoreElements()) { | while (e.hasMoreElements()) { | ||||
String sectionName = (String) e.nextElement(); | String sectionName = (String) e.nextElement(); | ||||
Section section = getSection(sectionName); | Section section = getSection(sectionName); | ||||
section.write(writer); | |||||
section.write(writer, flatten); | |||||
} | } | ||||
} | } | ||||
@@ -72,6 +72,16 @@ public class ManifestTask extends Task { | |||||
*/ | */ | ||||
private String encoding; | private String encoding; | ||||
/** | |||||
* whether to merge Class-Path attributes. | |||||
*/ | |||||
private boolean mergeClassPaths = false; | |||||
/** | |||||
* whether to flatten Class-Path attributes into a single one. | |||||
*/ | |||||
private boolean flattenClassPaths = false; | |||||
/** | /** | ||||
* Helper class for Manifest's mode attribute. | * Helper class for Manifest's mode attribute. | ||||
*/ | */ | ||||
@@ -183,6 +193,25 @@ public class ManifestTask extends Task { | |||||
mode = m; | mode = m; | ||||
} | } | ||||
/** | |||||
* Whether to merge Class-Path attributes. | |||||
* | |||||
* @since Ant 1.8.0 | |||||
*/ | |||||
public void setMergeClassPathAttributes(boolean b) { | |||||
mergeClassPaths = b; | |||||
} | |||||
/** | |||||
* Whether to flatten multi-valued attributes (i.e. Class-Path) | |||||
* into a single one. | |||||
* | |||||
* @since Ant 1.8.0 | |||||
*/ | |||||
public void setFlattenAttributes(boolean b) { | |||||
flattenClassPaths = b; | |||||
} | |||||
/** | /** | ||||
* Create or update the Manifest when used as a task. | * Create or update the Manifest when used as a task. | ||||
* | * | ||||
@@ -228,13 +257,13 @@ public class ManifestTask extends Task { | |||||
try { | try { | ||||
if (mode.getValue().equals("update") && manifestFile.exists()) { | if (mode.getValue().equals("update") && manifestFile.exists()) { | ||||
if (current != null) { | if (current != null) { | ||||
toWrite.merge(current); | |||||
toWrite.merge(current, false, mergeClassPaths); | |||||
} else if (error != null) { | } else if (error != null) { | ||||
throw error; | throw error; | ||||
} | } | ||||
} | } | ||||
toWrite.merge(nestedManifest); | |||||
toWrite.merge(nestedManifest, false, mergeClassPaths); | |||||
} catch (ManifestException m) { | } catch (ManifestException m) { | ||||
throw new BuildException("Manifest is invalid", m, getLocation()); | throw new BuildException("Manifest is invalid", m, getLocation()); | ||||
} | } | ||||
@@ -250,7 +279,7 @@ public class ManifestTask extends Task { | |||||
FileOutputStream fos = new FileOutputStream(manifestFile); | FileOutputStream fos = new FileOutputStream(manifestFile); | ||||
OutputStreamWriter osw = new OutputStreamWriter(fos, Manifest.JAR_ENCODING); | OutputStreamWriter osw = new OutputStreamWriter(fos, Manifest.JAR_ENCODING); | ||||
w = new PrintWriter(osw); | w = new PrintWriter(osw); | ||||
toWrite.write(w); | |||||
toWrite.write(w, flattenClassPaths); | |||||
if (w.checkError()) { | if (w.checkError()) { | ||||
throw new IOException("Encountered an error writing manifest"); | throw new IOException("Encountered an error writing manifest"); | ||||
} | } | ||||
@@ -91,4 +91,49 @@ | |||||
resource="${file}" | resource="${file}" | ||||
value="Class-Path: bar "/> | value="Class-Path: bar "/> | ||||
</target> | </target> | ||||
<target name="testMergeClassPathAttributes" depends="setUp"> | |||||
<manifest file="${file}"> | |||||
<attribute name="Class-Path" value="foo"/> | |||||
<attribute name="Class-Path" value="bar"/> | |||||
</manifest> | |||||
<manifest file="${file}" mergeClassPathAttributes="true" mode="update"> | |||||
<attribute name="Class-Path" value="baz"/> | |||||
</manifest> | |||||
<au:assertResourceContains | |||||
resource="${file}" | |||||
value="Class-Path: foo "/> | |||||
<au:assertResourceContains | |||||
resource="${file}" | |||||
value="Class-Path: bar "/> | |||||
<au:assertResourceContains | |||||
resource="${file}" | |||||
value="Class-Path: baz "/> | |||||
</target> | |||||
<target name="testFlattenMultipleClassPathAttributes" depends="setUp"> | |||||
<manifest file="${file}" flattenAttributes="true"> | |||||
<attribute name="Class-Path" value="foo"/> | |||||
<attribute name="Class-Path" value="bar"/> | |||||
</manifest> | |||||
<au:assertResourceContains | |||||
resource="${file}" | |||||
value="Class-Path: foo bar "/> | |||||
</target> | |||||
<target name="testMergeAndFlattenClassPathAttributes" depends="setUp"> | |||||
<manifest file="${file}"> | |||||
<attribute name="Class-Path" value="foo"/> | |||||
<attribute name="Class-Path" value="bar"/> | |||||
</manifest> | |||||
<manifest file="${file}" | |||||
mergeClassPathAttributes="true" | |||||
flattenAttributes="true" | |||||
mode="update"> | |||||
<attribute name="Class-Path" value="baz"/> | |||||
</manifest> | |||||
<au:assertResourceContains | |||||
resource="${file}" | |||||
value="Class-Path: baz foo bar "/> | |||||
</target> | |||||
</project> | </project> |