The mailling list seems not to allow attachment. So I paste the patch
here.
------------------- START PATCHING ---------------------------------
Index: org/apache/tools/ant/taskdefs/Zip.java
===================================================================
--- org/apache/tools/ant/taskdefs/Zip.java (revision 1)
+++ org/apache/tools/ant/taskdefs/Zip.java (working copy)
@@ -733,7 +733,7 @@
zOut, prefix, dirMode);
}
if (zf != null) {
- ZipEntry ze = zf.getEntry(resources[i].getName());
+ ZipEntry ze = zf.getEntry(zfs.getBasedir() +
resources[i].getName());
addParentDirs(base, name, zOut, prefix,
ze.getUnixMode());
} else {
@@ -752,7 +752,7 @@
zipFile(f, zOut, prefix + name, fileMode);
} else if (!resources[i].isDirectory()) {
if (zf != null) {
- ZipEntry ze = zf.getEntry(resources[i].getName());
+ ZipEntry ze = zf.getEntry(zfs.getBasedir() +
resources[i].getName());
if (ze != null) {
boolean oldCompress = doCompress;
Index: org/apache/tools/ant/types/ArchiveScanner.java
===================================================================
--- org/apache/tools/ant/types/ArchiveScanner.java (revision 1)
+++ org/apache/tools/ant/types/ArchiveScanner.java (working copy)
@@ -45,6 +45,11 @@
*/
protected File srcFile;
+ /**
+ * The basedir from which this scanner begins to scan.
+ */
+ protected String basedir;
+
// CheckStyle:VisibilityModifier ON
/**
@@ -119,6 +124,32 @@
}
/**
+ * Sets the basedir for scanning.
+ *
+ * @param basedir path name inside the zip file
+ */
+ public void setBasedir(String basedir) {
+ if ((basedir != null) && (basedir.length() > 0)) {
+
+ // Make sure the basedir:
+ // 1. BE separated by slash '/',
+ // 2. NOT starts with slash '/'
+ // 3. ALWAYS ends with slash '/'
+ basedir = basedir.replace('\\', '/');
+
+ if (basedir.startsWith("/")) {
+ basedir = basedir.substring(1);
+ }
+
+ if (!basedir.endsWith("/")) {
+ basedir += "/";
+ }
+
+ this.basedir = basedir;
+ }
+ }
+
+ /**
* Sets encoding of file names.
* @param encoding the encoding format
* @since Ant 1.6
@@ -331,5 +362,23 @@
protected static final String trimSeparator(String s) {
return s.endsWith("/") ? s.substring(0, s.length() - 1) : s;
}
+
+ /**
+ * if the basedir was specified, and the entry name (path) is under the
basedir,
+ * just save the relative path to the basedir.
+ * Again, make sure the entry name is separated by slash '/'.
+ */
+ protected final String trimBasedir(String name) {
+ name = name.replace('\\', '/');
+ if (basedir != null) {
+ if (name.startsWith(basedir)) {
+ name = name.substring(basedir.length());
+ } else {
+ name = null;
+ }
+ }
+
+ return name;
+ }
}
Index: org/apache/tools/ant/types/ZipScanner.java
===================================================================
--- org/apache/tools/ant/types/ZipScanner.java (revision 1)
+++ org/apache/tools/ant/types/ZipScanner.java (working copy)
@@ -77,7 +77,15 @@
while (e.hasMoreElements()) {
entry = (ZipEntry) e.nextElement();
Resource r = new ZipResource(srcFile, encoding, entry);
- String name = entry.getName();
+ String name = trimBasedir(entry.getName());
+
+ if (name == null || name.length() == 0) {
+ continue;
+ }
+
+ // set basedir-trimmed name as resource name
+ r.setName(name);
+
if (entry.isDirectory()) {
name = trimSeparator(name);
dirEntries.put(name, r);
Index: org/apache/tools/ant/types/ArchiveFileSet.java
===================================================================
--- org/apache/tools/ant/types/ArchiveFileSet.java (revision 1)
+++ org/apache/tools/ant/types/ArchiveFileSet.java (working copy)
@@ -56,6 +56,7 @@
UnixStat.FILE_FLAG | UnixStat.DEFAULT_FILE_PERM;
private Resource src = null;
+ private String basedir = null;
private String prefix = "";
private String fullpath = "";
private boolean hasDir = false;
@@ -87,6 +88,7 @@
src = fileset.src;
prefix = fileset.prefix;
fullpath = fileset.fullpath;
+ basedir = fileset.basedir;
hasDir = fileset.hasDir;
fileMode = fileset.fileMode;
dirMode = fileset.dirMode;
@@ -223,6 +225,42 @@
}
/**
+ * Sets the basedir inside the source archive file.
+ *
+ * @param basedir the basedir
+ */
+ public void setBasedir(String basedir) {
+ if ((basedir != null) && (basedir.length() > 0)) {
+
+ // Make sure the basedir:
+ // 1. BE separated by slash '/',
+ // 2. NOT starts with slash '/'
+ // 3. ALWAYS ends with slash '/'
+ basedir = basedir.replace('\\', '/');
+
+ if (basedir.startsWith("/")) {
+ basedir = basedir.substring(1);
+ }
+
+ if (!basedir.endsWith("/")) {
+ basedir += "/";
+ }
+
+ this.basedir = basedir;
+ }
+ }
+
+ /**
+ * Gets the basedir inside the source archive file.
+ *
+ * @return the basedir
+ */
+ public String getBasedir() {
+ return (basedir == null) ? ""
+ : basedir;
+ }
+
+ /**
* Creates a scanner for this type of archive.
* @return the scanner.
*/
@@ -250,6 +288,7 @@
}
ArchiveScanner as = newArchiveScanner();
as.setSrc(src);
+ as.setBasedir(getBasedir());
super.setDir(p.getBaseDir());
setupDirectoryScanner(as, p);
as.init();
------------------- END OF PATCH ---------------------------------
Forwarded by Michael Zhou <[EMAIL PROTECTED]>
----------------------- Original Message -----------------------
From: Michael Zhou <[EMAIL PROTECTED]>
To: [email protected]
Date: Wed, 08 Aug 2007 16:38:31 +0800
Subject: Contribute: use zipfileset to extract sub-path of zips
----
I used to build a jar file (or any zip-format file: war, ear, etc.),
which contents are extracted from other zip files. For instance,
zip file src.zip contains:
+---main
| \---org
| \---apache
| Test.java
|
\---test
I just want the subtree under "main" (not include main directory) to be
packed into my jar file:
+---org
\---apache
Test.java
So I wrote a build.xml to do this:
<project default="src-jar">
<target name="src-jar">
<jar destfile="my-src.jar">
<zipfileset src="src.zip" includes="main/"/>
</jar>
</target>
</project>
But the result is not as expected:
+---main // I don't want this directory here
\---org
\---apache
Test.java
In order to take off the "main" directory, I modified some Ant classes.
Attachment is the patch file from Ant 1.7.0 source.
Usage:
<project default="src-jar">
<target name="src-jar">
<jar destfile="my-src.jar">
<!-- basedir instead of includes -->
<zipfileset src="src.zip" basedir="main/"/>
</jar>
</target>
</project>
This is not the best solution I think. Because it doesn't support tasks
other than "zip", "jar", "war". For example, the following build script
won't work:
<project default="copy-src">
<target name="copy-src">
<copy destfile="srcdir">
<zipfileset src="src.zip" basedir="main/"/>
</copy>
</target>
</project>
I suggest to improve class org.apache.tools.zip.ZipFile to support new zip
file format like "src.zip!/main". By this way, any tasks use zipfileset
do not need to be changed.
For example,
<project default="copy-src">
<target name="copy-src">
<copy destfile="srcdir">
<zipfileset src="src.zip!/main" includes="**/*.java"/>
</copy>
</target>
</project>
Michael Zhou <[EMAIL PROTECTED]>
--------------------- Original Message Ends --------------------
--
Michael Zhou <[EMAIL PROTECTED]>
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]