Author: bodewig Date: Fri Sep 11 10:36:36 2009 New Revision: 813767 URL: http://svn.apache.org/viewvc?rev=813767&view=rev Log: Add up-to-date-ness check to archiving tasks and a way to prevent it with new force-create mode
Modified: ant/sandbox/antlibs/compress/trunk/src/main/org/apache/ant/compress/taskdefs/Ar.java ant/sandbox/antlibs/compress/trunk/src/main/org/apache/ant/compress/taskdefs/ArchiveBase.java ant/sandbox/antlibs/compress/trunk/src/main/org/apache/ant/compress/taskdefs/Cpio.java ant/sandbox/antlibs/compress/trunk/src/main/org/apache/ant/compress/taskdefs/Tar.java ant/sandbox/antlibs/compress/trunk/src/main/org/apache/ant/compress/taskdefs/Zip.java ant/sandbox/antlibs/compress/trunk/src/tests/antunit/ar-test.xml ant/sandbox/antlibs/compress/trunk/src/tests/antunit/cpio-test.xml ant/sandbox/antlibs/compress/trunk/src/tests/antunit/tar-test.xml ant/sandbox/antlibs/compress/trunk/src/tests/antunit/zip-test.xml Modified: ant/sandbox/antlibs/compress/trunk/src/main/org/apache/ant/compress/taskdefs/Ar.java URL: http://svn.apache.org/viewvc/ant/sandbox/antlibs/compress/trunk/src/main/org/apache/ant/compress/taskdefs/Ar.java?rev=813767&r1=813766&r2=813767&view=diff ============================================================================== --- ant/sandbox/antlibs/compress/trunk/src/main/org/apache/ant/compress/taskdefs/Ar.java (original) +++ ant/sandbox/antlibs/compress/trunk/src/main/org/apache/ant/compress/taskdefs/Ar.java Fri Sep 11 10:36:36 2009 @@ -19,10 +19,12 @@ package org.apache.ant.compress.taskdefs; import org.apache.ant.compress.util.ArStreamFactory; +import org.apache.ant.compress.resources.ArFileSet; import org.apache.commons.compress.archivers.ArchiveEntry; import org.apache.commons.compress.archivers.ar.ArArchiveEntry; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.types.ArchiveFileSet; +import org.apache.tools.ant.types.Resource; /** * Creates ar archives. @@ -34,7 +36,7 @@ public Ar() { setFactory(new ArStreamFactory()); - setBuilder( + setEntryBuilder( new ArchiveBase.EntryBuilder() { public ArchiveEntry buildEntry(ArchiveBase.ResourceWithFlags r) { boolean isDir = r.getResource().isDirectory(); @@ -75,6 +77,13 @@ / 1000); } }); + setFileSetBuilder(new ArchiveBase.FileSetBuilder() { + public ArchiveFileSet buildFileSet(Resource dest) { + ArchiveFileSet afs = new ArFileSet(); + afs.setSrcResource(dest); + return afs; + } + }); } public void setFilesOnly(boolean b) { Modified: ant/sandbox/antlibs/compress/trunk/src/main/org/apache/ant/compress/taskdefs/ArchiveBase.java URL: http://svn.apache.org/viewvc/ant/sandbox/antlibs/compress/trunk/src/main/org/apache/ant/compress/taskdefs/ArchiveBase.java?rev=813767&r1=813766&r2=813767&view=diff ============================================================================== --- ant/sandbox/antlibs/compress/trunk/src/main/org/apache/ant/compress/taskdefs/ArchiveBase.java (original) +++ ant/sandbox/antlibs/compress/trunk/src/main/org/apache/ant/compress/taskdefs/ArchiveBase.java Fri Sep 11 10:36:36 2009 @@ -58,8 +58,12 @@ import org.apache.tools.ant.types.ResourceCollection; import org.apache.tools.ant.types.resources.ArchiveResource; import org.apache.tools.ant.types.resources.FileResource; +import org.apache.tools.ant.types.resources.MappedResource; import org.apache.tools.ant.types.resources.Resources; import org.apache.tools.ant.util.FileUtils; +import org.apache.tools.ant.util.IdentityMapper; +import org.apache.tools.ant.util.MergingMapper; +import org.apache.tools.ant.util.ResourceUtils; import org.apache.tools.zip.UnixStat; /** @@ -67,7 +71,8 @@ */ public abstract class ArchiveBase extends Task { private ArchiveStreamFactory factory; - private EntryBuilder builder; + private FileSetBuilder fileSetBuilder; + private EntryBuilder entryBuilder; private Resource dest; private List/*<ResourceCollection>*/ sources = new ArrayList(); @@ -88,8 +93,12 @@ this.factory = factory; } - protected final void setBuilder(EntryBuilder builder) { - this.builder = builder; + protected final void setEntryBuilder(EntryBuilder builder) { + this.entryBuilder = builder; + } + + protected final void setFileSetBuilder(FileSetBuilder builder) { + this.fileSetBuilder = builder; } /** @@ -213,8 +222,9 @@ public void execute() { validate(); if (!dest.isExists()) { - // create mode + // force create mode mode = new Mode(); + mode.setValue(Mode.FORCE_CREATE); } ResourceWithFlags[] toAdd; try { @@ -230,6 +240,16 @@ } } else { try { + if (!Mode.FORCE_CREATE.equals(mode.getValue()) + && !Mode.FORCE_REPLACE.equals(mode.getValue()) + && isUpToDate(toAdd)) { + log(dest + " is up-to-date, nothing to do."); + return; + } + } catch (IOException ioex) { + throw new BuildException("Failed to read target archive", ioex); + } + try { writeArchive(toAdd); } catch (IOException ioex) { throw new BuildException("Failed to write archive", ioex); @@ -245,8 +265,12 @@ throw new BuildException("subclass didn't provide a factory" + " instance"); } - if (builder == null) { - throw new BuildException("subclass didn't provide a builder" + if (entryBuilder == null) { + throw new BuildException("subclass didn't provide an entryBuilder" + + " instance"); + } + if (fileSetBuilder == null) { + throw new BuildException("subclass didn't provide an fileSetBuilder" + " instance"); } if (dest == null) { @@ -293,6 +317,29 @@ } /** + * Checks whether the target is more recent than the resources + * that shall be added to it. + * + * <p>Will only ever be invoked if the target exists.</p> + * + * @return true if the target is up-to-date + */ + protected boolean isUpToDate(ResourceWithFlags[] src) throws IOException { + final Resource[] srcResources = new Resource[src.length]; + for (int i = 0; i < srcResources.length; i++) { + srcResources[i] = + new MappedResource(src[i].getResource(), + new MergingMapper(src[i].getName())); + } + return ResourceUtils + .selectOutOfDateSources(this, srcResources, + new IdentityMapper(), + fileSetBuilder.buildFileSet(dest) + .getDirectoryScanner(getProject())) + .length == 0; + } + + /** * Creates the archive archiving the given resources. */ protected void writeArchive(ResourceWithFlags[] src) @@ -312,7 +359,7 @@ ensureParentDirs(out, src[i], addedDirectories); } - ArchiveEntry ent = builder.buildEntry(src[i]); + ArchiveEntry ent = entryBuilder.buildEntry(src[i]); out.putArchiveEntry(ent); if (!src[i].getResource().isDirectory()) { InputStream in = null; @@ -359,7 +406,7 @@ new ResourceWithFlags(currentParent, dir, r.getCollectionFlags(), new ResourceFlags()); - ArchiveEntry ent = builder.buildEntry(artifical); + ArchiveEntry ent = entryBuilder.buildEntry(artifical); out.putArchiveEntry(ent); out.closeArchiveEntry(); } @@ -584,6 +631,11 @@ */ private static final String CREATE = "create"; /** + * Create a new archive even if the target exists and seems + * up-to-date. + */ + private static final String FORCE_CREATE = "force-create"; + /** * Update an existing archive. */ private static final String UPDATE = "update"; @@ -592,6 +644,12 @@ * with those from sources. */ private static final String REPLACE = "replace"; + /** + * Update an existing archive - replacing all existing entries + * with those from sources - even if the target exists and + * seems up-to-date. + */ + private static final String FORCE_REPLACE = "force-replace"; public Mode() { super(); @@ -599,7 +657,8 @@ } public String[] getValues() { - return new String[] {CREATE, UPDATE, REPLACE}; + return new String[] {CREATE, UPDATE, REPLACE, + FORCE_CREATE, FORCE_REPLACE}; } } @@ -842,4 +901,11 @@ public static interface EntryBuilder { ArchiveEntry buildEntry(ResourceWithFlags resource); } + + /** + * Creates an archive fileset to read the target archive. + */ + public static interface FileSetBuilder { + ArchiveFileSet buildFileSet(Resource dest); + } } Modified: ant/sandbox/antlibs/compress/trunk/src/main/org/apache/ant/compress/taskdefs/Cpio.java URL: http://svn.apache.org/viewvc/ant/sandbox/antlibs/compress/trunk/src/main/org/apache/ant/compress/taskdefs/Cpio.java?rev=813767&r1=813766&r2=813767&view=diff ============================================================================== --- ant/sandbox/antlibs/compress/trunk/src/main/org/apache/ant/compress/taskdefs/Cpio.java (original) +++ ant/sandbox/antlibs/compress/trunk/src/main/org/apache/ant/compress/taskdefs/Cpio.java Fri Sep 11 10:36:36 2009 @@ -19,9 +19,11 @@ package org.apache.ant.compress.taskdefs; import org.apache.ant.compress.util.CpioStreamFactory; +import org.apache.ant.compress.resources.CpioFileSet; import org.apache.commons.compress.archivers.ArchiveEntry; import org.apache.commons.compress.archivers.cpio.CpioArchiveEntry; import org.apache.tools.ant.types.ArchiveFileSet; +import org.apache.tools.ant.types.Resource; /** * Creates cpio archives. @@ -29,7 +31,7 @@ public class Cpio extends ArchiveBase { public Cpio() { setFactory(new CpioStreamFactory()); - setBuilder( + setEntryBuilder( new ArchiveBase.EntryBuilder() { public ArchiveEntry buildEntry(ArchiveBase.ResourceWithFlags r) { boolean isDir = r.getResource().isDirectory(); @@ -69,6 +71,13 @@ return ent; } }); + setFileSetBuilder(new ArchiveBase.FileSetBuilder() { + public ArchiveFileSet buildFileSet(Resource dest) { + ArchiveFileSet afs = new CpioFileSet(); + afs.setSrcResource(dest); + return afs; + } + }); } } \ No newline at end of file Modified: ant/sandbox/antlibs/compress/trunk/src/main/org/apache/ant/compress/taskdefs/Tar.java URL: http://svn.apache.org/viewvc/ant/sandbox/antlibs/compress/trunk/src/main/org/apache/ant/compress/taskdefs/Tar.java?rev=813767&r1=813766&r2=813767&view=diff ============================================================================== --- ant/sandbox/antlibs/compress/trunk/src/main/org/apache/ant/compress/taskdefs/Tar.java (original) +++ ant/sandbox/antlibs/compress/trunk/src/main/org/apache/ant/compress/taskdefs/Tar.java Fri Sep 11 10:36:36 2009 @@ -19,10 +19,12 @@ package org.apache.ant.compress.taskdefs; import org.apache.ant.compress.util.TarStreamFactory; +import org.apache.ant.compress.resources.TarFileSet; import org.apache.commons.compress.archivers.ArchiveEntry; import org.apache.commons.compress.archivers.tar.TarArchiveEntry; import org.apache.commons.compress.archivers.tar.TarConstants; import org.apache.tools.ant.types.ArchiveFileSet; +import org.apache.tools.ant.types.Resource; /** * Creates tar archives. @@ -30,7 +32,7 @@ public class Tar extends ArchiveBase { public Tar() { setFactory(new TarStreamFactory()); - setBuilder( + setEntryBuilder( new ArchiveBase.EntryBuilder() { public ArchiveEntry buildEntry(ArchiveBase.ResourceWithFlags r) { boolean isDir = r.getResource().isDirectory(); @@ -82,6 +84,13 @@ return ent; } }); + setFileSetBuilder(new ArchiveBase.FileSetBuilder() { + public ArchiveFileSet buildFileSet(Resource dest) { + ArchiveFileSet afs = new TarFileSet(); + afs.setSrcResource(dest); + return afs; + } + }); } } \ No newline at end of file Modified: ant/sandbox/antlibs/compress/trunk/src/main/org/apache/ant/compress/taskdefs/Zip.java URL: http://svn.apache.org/viewvc/ant/sandbox/antlibs/compress/trunk/src/main/org/apache/ant/compress/taskdefs/Zip.java?rev=813767&r1=813766&r2=813767&view=diff ============================================================================== --- ant/sandbox/antlibs/compress/trunk/src/main/org/apache/ant/compress/taskdefs/Zip.java (original) +++ ant/sandbox/antlibs/compress/trunk/src/main/org/apache/ant/compress/taskdefs/Zip.java Fri Sep 11 10:36:36 2009 @@ -25,12 +25,14 @@ import java.util.zip.Deflater; import org.apache.ant.compress.util.ZipStreamFactory; +import org.apache.ant.compress.resources.ZipFileSet; import org.apache.commons.compress.archivers.ArchiveEntry; import org.apache.commons.compress.archivers.ArchiveOutputStream; import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream; import org.apache.tools.ant.types.ArchiveFileSet; import org.apache.tools.ant.types.EnumeratedAttribute; +import org.apache.tools.ant.types.Resource; /** * Creates zip archives. @@ -47,7 +49,7 @@ setFactory(new ZipStreamFactory() { public ArchiveOutputStream getArchiveStream(OutputStream stream, String encoding) - throws IOException { + throws IOException { ZipArchiveOutputStream o = (ZipArchiveOutputStream) super.getArchiveStream(stream, encoding); @@ -60,7 +62,7 @@ return o; } }); - setBuilder( + setEntryBuilder( new ArchiveBase.EntryBuilder() { public ArchiveEntry buildEntry(ArchiveBase.ResourceWithFlags r) { boolean isDir = r.getResource().isDirectory(); @@ -95,6 +97,13 @@ return ent; } }); + setFileSetBuilder(new ArchiveBase.FileSetBuilder() { + public ArchiveFileSet buildFileSet(Resource dest) { + ArchiveFileSet afs = new ZipFileSet(); + afs.setSrcResource(dest); + return afs; + } + }); } /** Modified: ant/sandbox/antlibs/compress/trunk/src/tests/antunit/ar-test.xml URL: http://svn.apache.org/viewvc/ant/sandbox/antlibs/compress/trunk/src/tests/antunit/ar-test.xml?rev=813767&r1=813766&r2=813767&view=diff ============================================================================== --- ant/sandbox/antlibs/compress/trunk/src/tests/antunit/ar-test.xml (original) +++ ant/sandbox/antlibs/compress/trunk/src/tests/antunit/ar-test.xml Fri Sep 11 10:36:36 2009 @@ -389,4 +389,52 @@ actual="${output}/ar-test.xml"/> </target> + <target name="-prepareArchive" depends="setUp"> + <mkdir dir="${input}"/> + <copy todir="${input}"> + <file file="ar-test.xml"/> + </copy> + <cmp:ar dest="${dest}"> + <fileset dir="${input}"/> + </cmp:ar> + <copy todir="${output}"> + <file file="${dest}"/> + <globmapper from="*" to="*.bak"/> + </copy> + <sleep seconds="2"/> + <touch file="${dest}.bak"/> + <sleep seconds="2"/> + </target> + + <target name="testCreateOfUpToDate" depends="-prepareArchive"> + <cmp:ar dest="${dest}" mode="create"> + <fileset dir="${input}"/> + </cmp:ar> + <au:assertLogContains + text="test.ar is up-to-date, nothing to do."/> + <au:assertDestIsUptodate + src="${dest}" dest="${dest}.bak"/> + </target> + + <target name="testForceCreateOfUpToDate" depends="-prepareArchive"> + <cmp:ar dest="${dest}" mode="force-create"> + <fileset dir="${input}"/> + </cmp:ar> + <au:assertLogDoesntContain + text="test.ar is up-to-date, nothing to do."/> + <au:assertDestIsOutofdate + src="${dest}" dest="${dest}.bak"/> + </target> + + <target name="testCreateOfOutOfDate" depends="-prepareArchive"> + <touch file="${input}/ar-test.xml"/> + <cmp:ar dest="${dest}" mode="create"> + <fileset dir="${input}"/> + </cmp:ar> + <au:assertLogDoesntContain + text="test.ar is up-to-date, nothing to do."/> + <au:assertDestIsOutofdate + src="${dest}" dest="${dest}.bak"/> + </target> + </project> Modified: ant/sandbox/antlibs/compress/trunk/src/tests/antunit/cpio-test.xml URL: http://svn.apache.org/viewvc/ant/sandbox/antlibs/compress/trunk/src/tests/antunit/cpio-test.xml?rev=813767&r1=813766&r2=813767&view=diff ============================================================================== --- ant/sandbox/antlibs/compress/trunk/src/tests/antunit/cpio-test.xml (original) +++ ant/sandbox/antlibs/compress/trunk/src/tests/antunit/cpio-test.xml Fri Sep 11 10:36:36 2009 @@ -422,4 +422,51 @@ actual="${output}/ar-test.xml"/> </target> + <target name="-prepareArchive" depends="setUp"> + <mkdir dir="${input}"/> + <copy todir="${input}"> + <file file="ar-test.xml"/> + </copy> + <cmp:cpio dest="${dest}"> + <fileset dir="${input}"/> + </cmp:cpio> + <copy todir="${output}"> + <file file="${dest}"/> + <globmapper from="*" to="*.bak"/> + </copy> + <sleep seconds="2"/> + <touch file="${dest}.bak"/> + <sleep seconds="2"/> + </target> + + <target name="testCreateOfUpToDate" depends="-prepareArchive"> + <cmp:cpio dest="${dest}" mode="create"> + <fileset dir="${input}"/> + </cmp:cpio> + <au:assertLogContains + text="test.cpio is up-to-date, nothing to do."/> + <au:assertDestIsUptodate + src="${dest}" dest="${dest}.bak"/> + </target> + + <target name="testForceCreateOfUpToDate" depends="-prepareArchive"> + <cmp:cpio dest="${dest}" mode="force-create"> + <fileset dir="${input}"/> + </cmp:cpio> + <au:assertLogDoesntContain + text="test.cpio is up-to-date, nothing to do."/> + <au:assertDestIsOutofdate + src="${dest}" dest="${dest}.bak"/> + </target> + + <target name="testCreateOfOutOfDate" depends="-prepareArchive"> + <touch file="${input}/ar-test.xml"/> + <cmp:cpio dest="${dest}" mode="create"> + <fileset dir="${input}"/> + </cmp:cpio> + <au:assertLogDoesntContain + text="test.cpio is up-to-date, nothing to do."/> + <au:assertDestIsOutofdate + src="${dest}" dest="${dest}.bak"/> + </target> </project> Modified: ant/sandbox/antlibs/compress/trunk/src/tests/antunit/tar-test.xml URL: http://svn.apache.org/viewvc/ant/sandbox/antlibs/compress/trunk/src/tests/antunit/tar-test.xml?rev=813767&r1=813766&r2=813767&view=diff ============================================================================== --- ant/sandbox/antlibs/compress/trunk/src/tests/antunit/tar-test.xml (original) +++ ant/sandbox/antlibs/compress/trunk/src/tests/antunit/tar-test.xml Fri Sep 11 10:36:36 2009 @@ -438,4 +438,52 @@ <au:assertFilesMatch expected="ar-test.xml" actual="${output}/ar-test.xml"/> </target> + + <target name="-prepareArchive" depends="setUp"> + <mkdir dir="${input}"/> + <copy todir="${input}"> + <file file="ar-test.xml"/> + </copy> + <cmp:tar dest="${dest}"> + <fileset dir="${input}"/> + </cmp:tar> + <copy todir="${output}"> + <file file="${dest}"/> + <globmapper from="*" to="*.bak"/> + </copy> + <sleep seconds="2"/> + <touch file="${dest}.bak"/> + <sleep seconds="2"/> + </target> + + <target name="testCreateOfUpToDate" depends="-prepareArchive"> + <cmp:tar dest="${dest}" mode="create"> + <fileset dir="${input}"/> + </cmp:tar> + <au:assertLogContains + text="test.tar is up-to-date, nothing to do."/> + <au:assertDestIsUptodate + src="${dest}" dest="${dest}.bak"/> + </target> + + <target name="testForceCreateOfUpToDate" depends="-prepareArchive"> + <cmp:tar dest="${dest}" mode="force-create"> + <fileset dir="${input}"/> + </cmp:tar> + <au:assertLogDoesntContain + text="test.tar is up-to-date, nothing to do."/> + <au:assertDestIsOutofdate + src="${dest}" dest="${dest}.bak"/> + </target> + + <target name="testCreateOfOutOfDate" depends="-prepareArchive"> + <touch file="${input}/ar-test.xml"/> + <cmp:tar dest="${dest}" mode="create"> + <fileset dir="${input}"/> + </cmp:tar> + <au:assertLogDoesntContain + text="test.tar is up-to-date, nothing to do."/> + <au:assertDestIsOutofdate + src="${dest}" dest="${dest}.bak"/> + </target> </project> Modified: ant/sandbox/antlibs/compress/trunk/src/tests/antunit/zip-test.xml URL: http://svn.apache.org/viewvc/ant/sandbox/antlibs/compress/trunk/src/tests/antunit/zip-test.xml?rev=813767&r1=813766&r2=813767&view=diff ============================================================================== --- ant/sandbox/antlibs/compress/trunk/src/tests/antunit/zip-test.xml (original) +++ ant/sandbox/antlibs/compress/trunk/src/tests/antunit/zip-test.xml Fri Sep 11 10:36:36 2009 @@ -446,4 +446,52 @@ <au:assertFilesMatch expected="ar-test.xml" actual="${output}/ar-test.xml"/> </target> + + <target name="-prepareArchive" depends="setUp"> + <mkdir dir="${input}"/> + <copy todir="${input}"> + <file file="ar-test.xml"/> + </copy> + <cmp:zip dest="${dest}"> + <fileset dir="${input}"/> + </cmp:zip> + <copy todir="${output}"> + <file file="${dest}"/> + <globmapper from="*" to="*.bak"/> + </copy> + <sleep seconds="2"/> + <touch file="${dest}.bak"/> + <sleep seconds="2"/> + </target> + + <target name="testCreateOfUpToDate" depends="-prepareArchive"> + <cmp:zip dest="${dest}" mode="create"> + <fileset dir="${input}"/> + </cmp:zip> + <au:assertLogContains + text="test.zip is up-to-date, nothing to do."/> + <au:assertDestIsUptodate + src="${dest}" dest="${dest}.bak"/> + </target> + + <target name="testForceCreateOfUpToDate" depends="-prepareArchive"> + <cmp:zip dest="${dest}" mode="force-create"> + <fileset dir="${input}"/> + </cmp:zip> + <au:assertLogDoesntContain + text="test.zip is up-to-date, nothing to do."/> + <au:assertDestIsOutofdate + src="${dest}" dest="${dest}.bak"/> + </target> + + <target name="testCreateOfOutOfDate" depends="-prepareArchive"> + <touch file="${input}/ar-test.xml"/> + <cmp:zip dest="${dest}" mode="create"> + <fileset dir="${input}"/> + </cmp:zip> + <au:assertLogDoesntContain + text="test.zip is up-to-date, nothing to do."/> + <au:assertDestIsOutofdate + src="${dest}" dest="${dest}.bak"/> + </target> </project>