diff --git a/src/main/java/org/codehaus/plexus/archiver/AbstractArchiver.java b/src/main/java/org/codehaus/plexus/archiver/AbstractArchiver.java index d5f80c17b..7b38a937f 100755 --- a/src/main/java/org/codehaus/plexus/archiver/AbstractArchiver.java +++ b/src/main/java/org/codehaus/plexus/archiver/AbstractArchiver.java @@ -1257,4 +1257,45 @@ public String getOverrideGroupName() { return overrideGroupName; } + + @Override + public void configureReproducible( Date lastModifiedDate ) + { + // 1. force last modified date + setLastModifiedDate( normalizeLastModifiedDate( lastModifiedDate ) ); + + // 2. sort filenames in each directory when scanning filesystem + setFilenameComparator( new Comparator() + { + @Override + public int compare( String s1, String s2 ) + { + return s1.compareTo( s2 ); + } + } ); + + // 3. ignore file/directory mode from filesystem, since they may vary based on local user umask + // notice: this overrides execute bit on Unix (that is already ignored on Windows) + setFileMode( Archiver.DEFAULT_FILE_MODE ); + setDirectoryMode( Archiver.DEFAULT_DIR_MODE ); + + // 4. ignore uid/gid from filesystem (for tar) + setOverrideUid( 0 ); + setOverrideUserName( "root" ); // is it possible to avoid this, like "tar --numeric-owner"? + setOverrideGid( 0 ); + setOverrideGroupName( "root" ); + } + + /** + * Normalize last modified time value to get reproducible archive entries, based on + * archive binary format (tar uses UTC timestamp but zip uses local time then requires + * tweaks to make the value reproducible whatever the current timezone is). + * + * @param lastModifiedDate + * @return + */ + protected Date normalizeLastModifiedDate( Date lastModifiedDate ) + { + return lastModifiedDate; + } } diff --git a/src/main/java/org/codehaus/plexus/archiver/Archiver.java b/src/main/java/org/codehaus/plexus/archiver/Archiver.java index b6d9d8581..3c9442a36 100644 --- a/src/main/java/org/codehaus/plexus/archiver/Archiver.java +++ b/src/main/java/org/codehaus/plexus/archiver/Archiver.java @@ -415,6 +415,9 @@ ResourceIterator getResources() Date getLastModifiedDate(); /** + * Set filename comparator, used to sort file entries when scanning directories since File.list() does not + * guarantee any order. + * * @since 4.2.0 */ void setFilenameComparator( Comparator filenameComparator ); @@ -458,4 +461,18 @@ ResourceIterator getResources() * @since 4.2.0 */ String getOverrideGroupName(); + + /** + * Configure the archiver to create archives in a reproducible way (see