diff options
author | 2017-03-06 22:27:48 +0000 | |
---|---|---|
committer | 2017-03-07 10:47:52 +0000 | |
commit | 8527ee53c66dc15ed033c67e55c393b0c3faa78b (patch) | |
tree | 649ad90c96fbbe169686eff5ea57334ced97d54a /src/tools/android/java/com/google/devtools/build/android/AndroidResourceProcessor.java | |
parent | 9bb9001d0b5439d1fd2ed7d62ce9d9bbe8d79806 (diff) |
AndroidResourceProcessor: sort files before writing zips
walkFileTree can be non-determinisitic, so the zip entries
can be listed in a different order:
"A file tree is walked depth first, but you cannot make any
assumptions about the iteration order that subdirectories
are visited."
--
PiperOrigin-RevId: 149345145
MOS_MIGRATED_REVID=149345145
Diffstat (limited to 'src/tools/android/java/com/google/devtools/build/android/AndroidResourceProcessor.java')
-rw-r--r-- | src/tools/android/java/com/google/devtools/build/android/AndroidResourceProcessor.java | 29 |
1 files changed, 24 insertions, 5 deletions
diff --git a/src/tools/android/java/com/google/devtools/build/android/AndroidResourceProcessor.java b/src/tools/android/java/com/google/devtools/build/android/AndroidResourceProcessor.java index ec50361bb5..e466b3d357 100644 --- a/src/tools/android/java/com/google/devtools/build/android/AndroidResourceProcessor.java +++ b/src/tools/android/java/com/google/devtools/build/android/AndroidResourceProcessor.java @@ -56,6 +56,7 @@ import com.google.common.collect.ImmutableMap; import com.google.common.collect.Iterables; import com.google.common.collect.Maps; import com.google.common.collect.Multimap; +import com.google.common.collect.Ordering; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListeningExecutorService; @@ -339,6 +340,7 @@ public class AndroidResourceProcessor { SymbolFileSrcJarBuildingVisitor visitor = new SymbolFileSrcJarBuildingVisitor(zip, generatedSourcesRoot, staticIds); Files.walkFileTree(generatedSourcesRoot, visitor); + visitor.writeEntries(); } // Set to the epoch for caching purposes. Files.setLastModifiedTime(srcJar, FileTime.fromMillis(0L)); @@ -357,6 +359,7 @@ public class AndroidResourceProcessor { new BufferedOutputStream(Files.newOutputStream(classJar)))) { ClassJarBuildingVisitor visitor = new ClassJarBuildingVisitor(zip, generatedClassesRoot); Files.walkFileTree(generatedClassesRoot, visitor); + visitor.writeEntries(); visitor.writeManifestContent(); } // Set to the epoch for caching purposes. @@ -401,11 +404,13 @@ public class AndroidResourceProcessor { ZipBuilderVisitor visitor = new ZipBuilderVisitor(zout, resourcesRoot, "res"); visitor.setCompress(compress); Files.walkFileTree(resourcesRoot, visitor); + visitor.writeEntries(); } if (Files.exists(assetsRoot)) { ZipBuilderVisitor visitor = new ZipBuilderVisitor(zout, assetsRoot, "assets"); visitor.setCompress(compress); Files.walkFileTree(assetsRoot, visitor); + visitor.writeEntries(); } } } @@ -1279,6 +1284,7 @@ public class AndroidResourceProcessor { protected final Path root; private final String directoryPrefix; private int storageMethod = ZipEntry.STORED; + private final Collection<Path> paths = new ArrayList<>(); ZipBuilderVisitor(ZipOutputStream zip, Path root, String directory) { this.zip = zip; @@ -1291,6 +1297,17 @@ public class AndroidResourceProcessor { } /** + * Iterate through collected file paths in a deterministic order and write to the zip. + * + * @throws IOException if there is an error reading from the source or writing to the zip. + */ + void writeEntries() throws IOException { + for (Path path : Ordering.natural().immutableSortedCopy(paths)) { + writeFileEntry(path); + } + } + + /** * Normalize timestamps for deterministic builds. Stamp .class files to be a bit newer * than .java files. See: * {@link com.google.devtools.build.buildjar.jarhelper.JarHelper#normalizedTimestamp(String)} @@ -1321,9 +1338,13 @@ public class AndroidResourceProcessor { @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + paths.add(file); + return FileVisitResult.CONTINUE; + } + + protected void writeFileEntry(Path file) throws IOException { byte[] content = Files.readAllBytes(file); addEntry(file, content); - return FileVisitResult.CONTINUE; } } @@ -1375,7 +1396,7 @@ public class AndroidResourceProcessor { } @Override - public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + protected void writeFileEntry(Path file) throws IOException { if (file.getFileName().endsWith("R.java")) { byte[] content = Files.readAllBytes(file); if (staticIds) { @@ -1385,7 +1406,6 @@ public class AndroidResourceProcessor { } addEntry(file, content); } - return FileVisitResult.CONTINUE; } } @@ -1399,14 +1419,13 @@ public class AndroidResourceProcessor { } @Override - public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + protected void writeFileEntry(Path file) throws IOException { Path filename = file.getFileName(); String name = filename.toString(); if (name.endsWith(".class")) { byte[] content = Files.readAllBytes(file); addEntry(file, content); } - return FileVisitResult.CONTINUE; } private byte[] manifestContent() throws IOException { |