Changes OutputFileSet to overwrite on equal timestamps. Previously OutputFileSetOnDirectory took special care to not overwrite a file in the output directory if it had the same timestamp as the current artifact being written. For a long time this had no effect since Link.java deleted al output directory contents anyway and DevMode was not using OutputFileSets to perform it's writes. But somewhat recently DevMode was changed to use OutputFileSetOnDirectory and it resulted in a subtle change in behavior where generated files from 1 compile would not be overwritten by the samely named (but differently contented) generated file on a subsequent compile. As a result running a prod mode test followed by a dev mode test would fail as the dev mode test tried to reuse the incompatible prod mode test Foo.nocache.js file. Change-Id: I0916ab7933f9dfcb36b361f2e21657fac8174d67 Review-Link: https://gwt-review.googlesource.com/#/c/10311/ (cherry picked from commit c123d4887524191e960dec037641935ebff57d15)
diff --git a/dev/core/src/com/google/gwt/dev/util/OutputFileSet.java b/dev/core/src/com/google/gwt/dev/util/OutputFileSet.java index 2a0d780..4f95198 100644 --- a/dev/core/src/com/google/gwt/dev/util/OutputFileSet.java +++ b/dev/core/src/com/google/gwt/dev/util/OutputFileSet.java
@@ -68,14 +68,15 @@ } /** - * Opens a file for write. If writing to a zip file and the file already - * exists, there will be no effect. If writing to a directory, the file - * exists, and the given timestamp is older or equal to the file's - * current timestamp, there will be no effect. + * Opens a file for write. If writing to a zip file and the file already exists, + * there will be no effect. If writing to a directory, the file exists, and the + * given timestamp is older than the current timestamp, there will be no effect. + * * @param timeStampMillis last modified time in milliseconds, or - * TIMESTAMP_UNAVAILABLE to force an overwrite. + * TIMESTAMP_UNAVAILABLE to force an overwrite. * @return the output stream to write to, possibly a NullOutputStream */ + // TODO: revalidate whether any timestamp based overwrite prevention is needed. public OutputStream openForWrite(String path, long timeStampMillis) throws IOException { pathsSeen.add(path);
diff --git a/dev/core/src/com/google/gwt/dev/util/OutputFileSetOnDirectory.java b/dev/core/src/com/google/gwt/dev/util/OutputFileSetOnDirectory.java index fc9b195..d772a9a 100644 --- a/dev/core/src/com/google/gwt/dev/util/OutputFileSetOnDirectory.java +++ b/dev/core/src/com/google/gwt/dev/util/OutputFileSetOnDirectory.java
@@ -47,7 +47,7 @@ final long timeStampMillis) throws IOException { final File file = pathToFile(path); if (file.exists() && timeStampMillis != TIMESTAMP_UNAVAILABLE && - file.lastModified() >= timeStampMillis) { + file.lastModified() > timeStampMillis) { return new NullOutputStream(); }
diff --git a/dev/core/test/com/google/gwt/dev/util/OutputFileSetOnDirectoryTest.java b/dev/core/test/com/google/gwt/dev/util/OutputFileSetOnDirectoryTest.java index 9aa7fbd..0c2283e 100644 --- a/dev/core/test/com/google/gwt/dev/util/OutputFileSetOnDirectoryTest.java +++ b/dev/core/test/com/google/gwt/dev/util/OutputFileSetOnDirectoryTest.java
@@ -18,10 +18,12 @@ import junit.framework.TestCase; import java.io.File; +import java.io.FileOutputStream; import java.io.IOException; +import java.io.OutputStream; /** - * Tests for {@link OutputFileSetOnDirectory} + * Tests for {@link OutputFileSetOnDirectory}. */ public class OutputFileSetOnDirectoryTest extends TestCase { @@ -46,4 +48,37 @@ } } + public void testNewFileEqualTimestampOverwrites() throws IOException { + File work = Utility.makeTemporaryDirectory(null, "outputfileset"); + try { + OutputFileSetOnDirectory output = new OutputFileSetOnDirectory(work, "test/"); + + OutputStream firstStream = output.createNewOutputStream("path/to/file", 1000); + assertTrue(firstStream instanceof FileOutputStream); + firstStream.close(); + + OutputStream secondStream = output.createNewOutputStream("path/to/file", 1000); + assertTrue(secondStream instanceof FileOutputStream); + secondStream.close(); + } finally { + Util.recursiveDelete(work, false); + } + } + + public void testNewFileOlderTimestampDies() throws IOException { + File work = Utility.makeTemporaryDirectory(null, "outputfileset"); + try { + OutputFileSetOnDirectory output = new OutputFileSetOnDirectory(work, "test/"); + + OutputStream firstStream = output.createNewOutputStream("path/to/file", 2000); + assertTrue(firstStream instanceof FileOutputStream); + firstStream.close(); + + OutputStream secondStream = output.createNewOutputStream("path/to/file", 1000); + assertFalse(secondStream instanceof FileOutputStream); + secondStream.close(); + } finally { + Util.recursiveDelete(work, false); + } + } }