Skip to content

Support AbstractArchiveTask.preserveFileTimestamps for reproducible builds #391

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Sep 12, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import java.util.zip.ZipException

@Slf4j
class ShadowCopyAction implements CopyAction {
private static final long CONSTANT_TIME_FOR_ZIP_ENTRIES = (new GregorianCalendar(1980, 1, 1, 0, 0, 0)).getTimeInMillis()

private final File zipFile
private final ZipCompressor compressor
Expand All @@ -50,10 +51,12 @@ class ShadowCopyAction implements CopyAction {
private final ShadowStats stats
private final String encoding
private final GradleVersionUtil versionUtil
private final boolean preserveFileTimestamps

ShadowCopyAction(File zipFile, ZipCompressor compressor, DocumentationRegistry documentationRegistry,
String encoding, List<Transformer> transformers, List<Relocator> relocators,
PatternSet patternSet, ShadowStats stats, GradleVersionUtil util) {
PatternSet patternSet, ShadowStats stats, GradleVersionUtil util,
boolean preserveFileTimestamps) {

this.zipFile = zipFile
this.compressor = compressor
Expand All @@ -64,6 +67,7 @@ class ShadowCopyAction implements CopyAction {
this.stats = stats
this.encoding = encoding
this.versionUtil = util
this.preserveFileTimestamps = preserveFileTimestamps
}

@Override
Expand Down Expand Up @@ -109,6 +113,17 @@ class ShadowCopyAction implements CopyAction {
}
}

private long getArchiveTimeFor(long timestamp) {
return preserveFileTimestamps ? timestamp : CONSTANT_TIME_FOR_ZIP_ENTRIES
}

private ZipEntry setArchiveTimes(ZipEntry zipEntry) {
if (!preserveFileTimestamps) {
zipEntry.setTime(CONSTANT_TIME_FOR_ZIP_ENTRIES)
}
return zipEntry
}

private static <T extends Closeable> void withResource(T resource, Action<? super T> action) {
try {
action.execute(resource)
Expand Down Expand Up @@ -176,7 +191,7 @@ class ShadowCopyAction implements CopyAction {
if (!isTransformable(fileDetails)) {
String mappedPath = remapper.map(fileDetails.relativePath.pathString)
ZipEntry archiveEntry = new ZipEntry(mappedPath)
archiveEntry.setTime(fileDetails.lastModified)
archiveEntry.setTime(getArchiveTimeFor(fileDetails.lastModified))
archiveEntry.unixMode = (UnixStat.FILE_FLAG | fileDetails.mode)
zipOutStr.putNextEntry(archiveEntry)
fileDetails.copyTo(zipOutStr)
Expand Down Expand Up @@ -248,7 +263,8 @@ class ShadowCopyAction implements CopyAction {

private void remapClass(RelativeArchivePath file, ZipFile archive) {
if (file.classFile) {
addParentDirectories(new RelativeArchivePath(new ZipEntry(remapper.mapPath(file) + '.class'), null))
ZipEntry zipEntry = setArchiveTimes(new ZipEntry(remapper.mapPath(file) + '.class'))
addParentDirectories(new RelativeArchivePath(zipEntry, null))
InputStream is = archive.getInputStream(file.entry)
try {
remapClass(is, file.pathString, file.entry.time)
Expand Down Expand Up @@ -292,7 +308,7 @@ class ShadowCopyAction implements CopyAction {
try {
// Now we put it back on so the class file is written out with the right extension.
ZipEntry archiveEntry = new ZipEntry(mappedName + ".class")
archiveEntry.setTime(lastModified)
archiveEntry.setTime(getArchiveTimeFor(lastModified))
zipOutStr.putNextEntry(archiveEntry)
IOUtils.copyLarge(bis, zipOutStr)
zipOutStr.closeEntry()
Expand All @@ -306,7 +322,7 @@ class ShadowCopyAction implements CopyAction {
private void copyArchiveEntry(RelativeArchivePath archiveFile, ZipFile archive) {
String mappedPath = remapper.map(archiveFile.entry.name)
ZipEntry entry = new ZipEntry(mappedPath)
entry.setTime(archiveFile.entry.time)
entry.setTime(getArchiveTimeFor(archiveFile.entry.time))
RelativeArchivePath mappedFile = new RelativeArchivePath(entry, archiveFile.details)
addParentDirectories(mappedFile)
zipOutStr.putNextEntry(mappedFile.entry)
Expand All @@ -324,7 +340,7 @@ class ShadowCopyAction implements CopyAction {
// Trailing slash in name indicates that entry is a directory
String path = dirDetails.relativePath.pathString + '/'
ZipEntry archiveEntry = new ZipEntry(path)
archiveEntry.setTime(dirDetails.lastModified)
archiveEntry.setTime(getArchiveTimeFor(dirDetails.lastModified))
archiveEntry.unixMode = (UnixStat.DIR_FLAG | dirDetails.mode)
zipOutStr.putNextEntry(archiveEntry)
zipOutStr.closeEntry()
Expand Down Expand Up @@ -386,7 +402,7 @@ class ShadowCopyAction implements CopyAction {
} else {
//Parent is always a directory so add / to the end of the path
String path = segments[0..-2].join('/') + '/'
return new RelativeArchivePath(new ZipEntry(path), null)
return new RelativeArchivePath(setArchiveTimes(new ZipEntry(path)), null)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ protected CopyAction createCopyAction() {
DocumentationRegistry documentationRegistry = getServices().get(DocumentationRegistry.class);
return new ShadowCopyAction(getArchivePath(), getInternalCompressor(), documentationRegistry,
this.getMetadataCharset(), transformers, relocators, getRootPatternSet(), shadowStats,
versionUtil);
versionUtil, isPreserveFileTimestamps());
}

@Internal
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ class ShadowPluginSpec extends PluginSpecification {
assert output.exists()

where:
version << ['3.0', '3.1', '3.2', '3.3', '3.4', '3.5', '4.0', '4.1', '4.2', '4.3', '4.4', '4.5', '4.6']
version << ['3.4', '3.5', '4.0', '4.1', '4.2', '4.3', '4.4', '4.5', '4.6']
}

def 'Error in Gradle versions < 3.0'() {
Expand Down