GNU bug report logs - #34223
Fixing timestamps in archives.

Previous Next

Package: guix-patches;

Reported by: Tim Gesthuizen <tim.gesthuizen <at> yahoo.de>

Date: Sun, 27 Jan 2019 18:00:02 UTC

Severity: normal

To reply to this bug, email your comments to 34223 AT debbugs.gnu.org.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to guix-patches <at> gnu.org:
bug#34223; Package guix-patches. (Sun, 27 Jan 2019 18:00:03 GMT) Full text and rfc822 format available.

Acknowledgement sent to Tim Gesthuizen <tim.gesthuizen <at> yahoo.de>:
New bug report received and forwarded. Copy sent to guix-patches <at> gnu.org. (Sun, 27 Jan 2019 18:00:03 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Tim Gesthuizen <tim.gesthuizen <at> yahoo.de>
To: Ludovic Courtès <ludo <at> gnu.org>, guix-patches <at> gnu.org
Subject: Fixing timestamps in archives.
Date: Sun, 27 Jan 2019 18:58:38 +0100
[Message part 1 (text/plain, inline)]
Hi Ludo,

as discussed before I have looked into the problems of timestamps in the
zip files.
I looked at the way this is solved in ant-build-system with jar files
and thought that this could be done in a more elegant way.
Because of this I wrote a simple frontend for LibArchive in C that
repacks archives and sets their timestamps to zero and disables
compression as it is done in the ant-build-system.
Creative as I am the program is called repack.
You find a git repository attached with the history of the repack program.
The attached patches add repack to Guix and use it for pwsafe and the
ant-build-system.

This is a work in progress version: If you like these changes I will
work on missing details so that we can add it, otherwise now would be a
good point to stop development on these changes.
I can still fall back to the variant that ant-build-system uses now for
pwsafe.

It would be nice if you could find the time to review everything and
tell me what you think about the patches.
The changes trigger a lot of rebuilds so it will take some time to build
dependencies of the required programs.

The repack tar contains a bare git repository with the program.
Because I could not yet find a place to host the repository you need to
unpack it somewhere, create an archive with the source code and change
the guix definition of repack to use that source.

Tim.
[0001-gnu-Add-repack.patch (text/x-patch, attachment)]
[0002-guix-utils-Add-repack-archives.patch (text/x-patch, attachment)]
[0003-gnu-pwsafe-Remove-timestamps-from-zip-files.patch (text/x-patch, attachment)]
[0004-guix-ant-Use-repack.patch (text/x-patch, attachment)]
[0005-guix-ant-build-system-Use-repack-archives.patch (text/x-patch, attachment)]
[0006-gnu-ant-bootstrap-Use-strip-jar-timestamps.patch (text/x-patch, attachment)]
[0007-gnu-icedtea-8-Use-repack.patch (text/x-patch, attachment)]
[0008-gnu-openjdk9-Use-repack-for-repacking-zips.patch (text/x-patch, attachment)]
[0009-gnu-openjdk-Use-repack-for-repacking-zips.patch (text/x-patch, attachment)]
[0010-gnu-ant-java8-Use-repack-for-repacking-archives.patch (text/x-patch, attachment)]
[0011-gnu-ant-Use-repack-for-repacking-archives.patch (text/x-patch, attachment)]
[repack.tar.xz (application/x-xz, attachment)]
[signature.asc (application/pgp-signature, attachment)]

Information forwarded to guix-patches <at> gnu.org:
bug#34223; Package guix-patches. (Sat, 16 Feb 2019 22:37:01 GMT) Full text and rfc822 format available.

Message #8 received at 34223 <at> debbugs.gnu.org (full text, mbox):

From: Ludovic Courtès <ludo <at> gnu.org>
To: Tim Gesthuizen <tim.gesthuizen <at> yahoo.de>
Cc: 34223 <at> debbugs.gnu.org
Subject: Re: [bug#34223] Fixing timestamps in archives.
Date: Sat, 16 Feb 2019 23:35:50 +0100
[Message part 1 (text/plain, inline)]
Hi Tim,

Sorry for the delay!

Tim Gesthuizen <tim.gesthuizen <at> yahoo.de> skribis:

> as discussed before I have looked into the problems of timestamps in the
> zip files.
> I looked at the way this is solved in ant-build-system with jar files
> and thought that this could be done in a more elegant way.
> Because of this I wrote a simple frontend for LibArchive in C that
> repacks archives and sets their timestamps to zero and disables
> compression as it is done in the ant-build-system.
> Creative as I am the program is called repack.
> You find a git repository attached with the history of the repack program.
> The attached patches add repack to Guix and use it for pwsafe and the
> ant-build-system.

Nice work!  It’s great that libarchive doesn’t need to actually extract
the zip file to operate on it.

Overall I think the approach of factorizing archive-timestamp-resetting
in one place and using it everywhere (‘ant-build-system’ and all) is the
right thing to do.

However, I’m not sure whether we should introduce a new program for this
purpose.  I believe ‘strip-nondeterminism’¹ (in Perl) by fellow
Reproducible Builds hackers also addresses this problem, so it may be
wiser to use it.

But really, since (guix build utils) already implements a significant
subset of ‘strip-nondeterminism’, it would be even better if could avoid
to shell out to a C or Perl program.

I played a bit with this idea and, as an example, the attached file
allows you to traverse the list of entries in a zip file (it uses
‘guile-bytestructures’).  Specifically, you can get the list of file
names in a zip file by running:

  (call-with-input-file "something.zip"
    (lambda (port)
      (fold-entries cons '() port)))

Resetting timestamps should be just as simple.

How about taking this route?

Thanks,
Ludo’.

¹ https://salsa.debian.org/reproducible-builds/strip-nondeterminism

[zip.scm (text/plain, inline)]
(define-module (guix zip)
  #:use-module (rnrs bytevectors)
  #:use-module (rnrs io ports)
  #:use-module (bytestructures guile)
  #:use-module (ice-9 match)
  #:export (fold-entries))

(define <file-header>
  ;; File header, see
  ;; <https://en.wikipedia.org/wiki/Zip_(file_format)#File_headers>.
  (bs:struct #t                                   ;packed
             `((signature ,uint32le)
               (version-needed ,uint16le)
               (flags ,uint16le)
               (compression ,uint16le)
               (modification-time ,uint16le)
               (modification-date ,uint16le)
               (crc32 ,uint32le)
               (compressed-size ,uint32le)
               (uncompressed-size ,uint32le)
               (file-name-length ,uint16le)
               (extra-field-length ,uint16le))))

(define-bytestructure-accessors <file-header>
  file-header-unwrap file-header-ref set-file-header!)

(define (fold-entries proc seed port)
  "Fold PROC over all the entries in the zip file at PORT."
  (let loop ((result seed))
    (match (get-bytevector-n port (bytestructure-descriptor-size
                                   <file-header>))
      ((? bytevector? bv)
       (match (file-header-ref bv signature)
         (#x04034b50                              ;local file header
          (let* ((len  (file-header-ref bv file-name-length))
                 (name (utf8->string (get-bytevector-n port len))))
            (set-port-position! port
                                (+ (file-header-ref bv extra-field-length)
                                   (file-header-ref bv compressed-size)
                                   (port-position port)))
            (loop (proc name result))))
         (#x02014b50                               ;central directory record
          result)
         (#x06054b50                          ;end of central directory record
          result)))
      ((? eof-object?)
       result))))

Information forwarded to guix-patches <at> gnu.org:
bug#34223; Package guix-patches. (Sun, 17 Feb 2019 07:43:01 GMT) Full text and rfc822 format available.

Message #11 received at 34223 <at> debbugs.gnu.org (full text, mbox):

From: Julien Lepiller <julien <at> lepiller.eu>
To: Ludovic Courtès <ludo <at> gnu.org>,
 Tim Gesthuizen <tim.gesthuizen <at> yahoo.de>
Cc: 34223 <at> debbugs.gnu.org
Subject: Re: [bug#34223] Fixing timestamps in archives.
Date: Sun, 17 Feb 2019 08:42:09 +0100
Le 16 février 2019 23:35:50 GMT+01:00, "Ludovic Courtès" <ludo <at> gnu.org> a écrit :
>Hi Tim,
>
>Sorry for the delay!
>
>Tim Gesthuizen <tim.gesthuizen <at> yahoo.de> skribis:
>
>> as discussed before I have looked into the problems of timestamps in
>the
>> zip files.
>> I looked at the way this is solved in ant-build-system with jar files
>> and thought that this could be done in a more elegant way.
>> Because of this I wrote a simple frontend for LibArchive in C that
>> repacks archives and sets their timestamps to zero and disables
>> compression as it is done in the ant-build-system.
>> Creative as I am the program is called repack.
>> You find a git repository attached with the history of the repack
>program.
>> The attached patches add repack to Guix and use it for pwsafe and the
>> ant-build-system.
>
>Nice work!  It’s great that libarchive doesn’t need to actually extract
>the zip file to operate on it.
>
>Overall I think the approach of factorizing archive-timestamp-resetting
>in one place and using it everywhere (‘ant-build-system’ and all) is
>the
>right thing to do.
>
>However, I’m not sure whether we should introduce a new program for
>this
>purpose.  I believe ‘strip-nondeterminism’¹ (in Perl) by fellow
>Reproducible Builds hackers also addresses this problem, so it may be
>wiser to use it.
>
>But really, since (guix build utils) already implements a significant
>subset of ‘strip-nondeterminism’, it would be even better if could
>avoid
>to shell out to a C or Perl program.
>
>I played a bit with this idea and, as an example, the attached file
>allows you to traverse the list of entries in a zip file (it uses
>‘guile-bytestructures’).  Specifically, you can get the list of file
>names in a zip file by running:
>
>  (call-with-input-file "something.zip"
>    (lambda (port)
>      (fold-entries cons '() port)))
>
>Resetting timestamps should be just as simple.
>
>How about taking this route?
>
>Thanks,
>Ludo’.
>
>¹ https://salsa.debian.org/reproducible-builds/strip-nondeterminism

One of the reasons why we extract jar files is to remove compression, because the content might have store references that would be hidden, so grafting for instance wouldn't work.




Information forwarded to guix-patches <at> gnu.org:
bug#34223; Package guix-patches. (Mon, 18 Feb 2019 20:10:02 GMT) Full text and rfc822 format available.

Message #14 received at 34223 <at> debbugs.gnu.org (full text, mbox):

From: Tim Gesthuizen <tim.gesthuizen <at> yahoo.de>
To: Ludovic Courtès <ludo <at> gnu.org>
Cc: 34223 <at> debbugs.gnu.org
Subject: Re: [bug#34223] Fixing timestamps in archives.
Date: Mon, 18 Feb 2019 21:07:03 +0100
Hi Ludo,

> Sorry for the delay!

No problem! I have very little time anyway.

> Nice work!  It’s great that libarchive doesn’t need to actually extract
> the zip file to operate on it.
>
> Overall I think the approach of factorizing archive-timestamp-resetting
> in one place and using it everywhere (‘ant-build-system’ and all) is the
> right thing to do.
>
> However, I’m not sure whether we should introduce a new program for this
> purpose.  I believe ‘strip-nondeterminism’¹ (in Perl) by fellow
> Reproducible Builds hackers also addresses this problem, so it may be
> wiser to use it.

I also think so. If there is already another program that does the job
we should probably use it.

> But really, since (guix build utils) already implements a significant
> subset of ‘strip-nondeterminism’, it would be even better if could avoid
> to shell out to a C or Perl program.
>
> I played a bit with this idea and, as an example, the attached file
> allows you to traverse the list of entries in a zip file (it uses
> ‘guile-bytestructures’).  Specifically, you can get the list of file
> names in a zip file by running:
>
>   (call-with-input-file "something.zip"
>     (lambda (port)
>       (fold-entries cons '() port)))
>
> Resetting timestamps should be just as simple.
>
> How about taking this route?

I also thought about taking this route.
There are some problems with it though:

- As Julien pointed out, the archive contents need to be uncompressed.
  This makes the problem much more complex and keeps us from writing
  a partial ZIP parser that replaces the timestamps in place.
- While it would be quite elegant to just implement the parser in
  Scheme it would be redundant. After all we are developing a package
  manager so we should use it.
  This approach would be more attractive if there would be a Guile
  library for this.
  The best solution would be creating a proper library for handling
  archives when going with Scheme.
- Maintaining a ZIP parser in Guix is a burden we should not take.
- We need to care about a lot of details (ZIP64, probably more exotic
  extensions).

I would be fine with writing an own parser in Scheme but I would like to
point out that in every other place in Guix we are using external tools
for handling archives (AFAIK).

I am not quite sure which version would be the best, so I am open for
other opinions on this.
Maybe you could rephrase your position taking the compression problem
into consideration.

Tim.




Information forwarded to guix-patches <at> gnu.org:
bug#34223; Package guix-patches. (Mon, 18 Feb 2019 22:25:02 GMT) Full text and rfc822 format available.

Message #17 received at 34223 <at> debbugs.gnu.org (full text, mbox):

From: Ludovic Courtès <ludo <at> gnu.org>
To: Tim Gesthuizen <tim.gesthuizen <at> yahoo.de>
Cc: 34223 <at> debbugs.gnu.org
Subject: Re: [bug#34223] Fixing timestamps in archives.
Date: Mon, 18 Feb 2019 23:24:11 +0100
Hello,

Tim Gesthuizen <tim.gesthuizen <at> yahoo.de> skribis:

>> I played a bit with this idea and, as an example, the attached file
>> allows you to traverse the list of entries in a zip file (it uses
>> ‘guile-bytestructures’).  Specifically, you can get the list of file
>> names in a zip file by running:
>>
>>   (call-with-input-file "something.zip"
>>     (lambda (port)
>>       (fold-entries cons '() port)))
>>
>> Resetting timestamps should be just as simple.
>>
>> How about taking this route?
>
> I also thought about taking this route.
> There are some problems with it though:
>
> - As Julien pointed out, the archive contents need to be uncompressed.
>   This makes the problem much more complex and keeps us from writing
>   a partial ZIP parser that replaces the timestamps in place.

True, I had overlooked that.  In that case, we should definitely unpack
and repack using the ‘zip’ package (I wasn’t suggesting to write a
complete ‘zip’ implementation; I do think it would be valuable in the
long term, but it’s a project for another time, no question here.)

In that case though, it probably doesn’t buy us much to use libarchive
in a separate C program, WDYT?  Should we just stick to the current
approach that invokes ‘unzip’ and ‘zip’?

Thanks,
Ludo’.




Information forwarded to guix-patches <at> gnu.org:
bug#34223; Package guix-patches. (Fri, 01 Mar 2019 23:24:01 GMT) Full text and rfc822 format available.

Message #20 received at 34223 <at> debbugs.gnu.org (full text, mbox):

From: Tim Gesthuizen <tim.gesthuizen <at> yahoo.de>
To: Ludovic Courtès <ludo <at> gnu.org>
Cc: 34223 <at> debbugs.gnu.org
Subject: Re: [bug#34223] Fixing timestamps in archives.
Date: Sat, 02 Mar 2019 00:23:30 +0100
[Message part 1 (text/plain, inline)]
Hi Ludo,

Sorry for the delay!

Ludovic Courtès writes:
> In that case though, it probably doesn’t buy us much to use libarchive
> in a separate C program, WDYT?  Should we just stick to the current
> approach that invokes ‘unzip’ and ‘zip’?

This seems to be the best choice.
Maybe we want to reevaluate when there is a proper ZIP-library for
guile.

I have attached patches that isolate repack-archive from the
ant-build-system and use it for pwsafe.
I only builded some java packages so I don't know if something
else might be broken because of the changes.

Tim.

[0001-guix-Generalize-zip-repacking.patch (text/x-patch, inline)]
From fe8e4da34a0806d6f444d2fce572a2a39533f0fc Mon Sep 17 00:00:00 2001
From: Tim Gesthuizen <tim.gesthuizen <at> yahoo.de>
Date: Fri, 1 Mar 2019 23:39:14 +0100
Subject: [PATCH 1/2] guix: Generalize zip repacking

Move repack-archive into an own module and change ant-build-system
and icedtea accordingly.

* Makefile.am: Add archives.scm.
* gnu/packages/java.scm (icedtea-8): Add unzip to the native-inputs.
* guix/build-system/ant.scm (default-unzip): New function.
  (lower): Add unzip parameter and add it to the build-inputs.
* guix/build/ant-build-system.scm (strip-jar-timestamps): Remove
  repack-archive declaration.
* guix/build/archives.scm: New file.
  (repack-archive): New function.
---
 Makefile.am                     |  2 ++
 gnu/packages/java.scm           |  5 ++-
 guix/build-system/ant.scm       | 10 ++++++
 guix/build/ant-build-system.scm | 38 +++-------------------
 guix/build/archives.scm         | 56 +++++++++++++++++++++++++++++++++
 5 files changed, 77 insertions(+), 34 deletions(-)
 create mode 100644 guix/build/archives.scm

diff --git a/Makefile.am b/Makefile.am
index fec9800ce..c6dad9bb5 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -13,6 +13,7 @@
 # Copyright © 2018 Julien Lepiller <julien <at> lepiller.eu>
 # Copyright © 2018 Oleg Pykhalov <go.wigust <at> gmail.com>
 # Copyright © 2018 Alex Vong <alexvong1995 <at> gmail.com>
+# Copyright © 2019 Tim Gesthuizen <tim.gesthuizen <at> yahoo.de>
 #
 # This file is part of GNU Guix.
 #
@@ -153,6 +154,7 @@ MODULES =					\
   guix/build/font-build-system.scm		\
   guix/build/go-build-system.scm		\
   guix/build/asdf-build-system.scm		\
+  guix/build/archives.scm                       \
   guix/build/git.scm				\
   guix/build/hg.scm				\
   guix/build/glib-or-gtk-build-system.scm	\
diff --git a/gnu/packages/java.scm b/gnu/packages/java.scm
index 974756900..fea7d20b7 100644
--- a/gnu/packages/java.scm
+++ b/gnu/packages/java.scm
@@ -10,6 +10,7 @@
 ;;; Copyright © 2018 Gábor Boskovits <boskovits <at> gmail.com>
 ;;; Copyright © 2018 Chris Marusich <cmmarusich <at> gmail.com>
 ;;; Copyright © 2018 Efraim Flashner <efraim <at> flashner.co.il>
+;;; Copyright © 2019 Tim Gesthuizen <tim.gesthuizen <at> yahoo.de
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -1549,6 +1550,7 @@ IcedTea build harness.")
        `(#:imported-modules
          ((guix build ant-build-system)
           (guix build syscalls)
+          (guix build archives)
           ,@%gnu-build-system-modules)
          ,@(substitute-keyword-arguments (package-arguments icedtea-7)
              ((#:modules modules)
@@ -1672,7 +1674,8 @@ new Date();"))
                  "0k33anxdzw1icn072wynfmmdjhsv50hay0j1sfkfxny12rb3vgdy"))
          ,@(fold alist-delete (package-native-inputs icedtea-7)
                  '("jdk" "openjdk-src" "corba-drop" "jaxp-drop" "jaxws-drop"
-                   "jdk-drop" "langtools-drop" "hotspot-drop")))))))
+                   "jdk-drop" "langtools-drop" "hotspot-drop"))
+         ("unzip" ,unzip))))))
 
 (define-public openjdk9
   (package
diff --git a/guix/build-system/ant.scm b/guix/build-system/ant.scm
index b5626bd42..e4cd4c1f7 100644
--- a/guix/build-system/ant.scm
+++ b/guix/build-system/ant.scm
@@ -1,5 +1,6 @@
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2016 Ricardo Wurmus <rekado <at> elephly.net>
+;;; Copyright © 2019 Tim Gesthuizen <tim.gesthuizen <at> yahoo.de>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -41,6 +42,7 @@
   `((guix build ant-build-system)
     (guix build java-utils)
     (guix build syscalls)
+    (guix build archives)
     ,@%gnu-build-system-modules))
 
 (define (default-jdk)
@@ -61,11 +63,18 @@
   (let ((zip-mod (resolve-interface '(gnu packages compression))))
     (module-ref zip-mod 'zip)))
 
+(define (default-unzip)
+  "Return the default UNZIP package."
+  ;; Lazily resolve the binding to avoid a circular dependency.
+  (let ((zip-mod (resolve-interface '(gnu packages compression))))
+    (module-ref zip-mod 'unzip)))
+
 (define* (lower name
                 #:key source inputs native-inputs outputs system target
                 (jdk (default-jdk))
                 (ant (default-ant))
                 (zip (default-zip))
+                (unzip (default-unzip))
                 #:allow-other-keys
                 #:rest arguments)
   "Return a bag for NAME."
@@ -86,6 +95,7 @@
          (build-inputs `(("jdk" ,jdk "jdk")
                          ("ant" ,ant)
                          ("zip" ,zip)
+                         ("unzip" ,unzip)
                          ,@native-inputs))
          (outputs outputs)
          (build ant-build)
diff --git a/guix/build/ant-build-system.scm b/guix/build/ant-build-system.scm
index d79a2d55e..fbde6fae7 100644
--- a/guix/build/ant-build-system.scm
+++ b/guix/build/ant-build-system.scm
@@ -1,5 +1,6 @@
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2016, 2018 Ricardo Wurmus <rekado <at> elephly.net>
+;;; Copyright © 2019 Tim Gesthuizen <tim.gesthuizen <at> yahoo.de>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -20,6 +21,7 @@
   #:use-module ((guix build gnu-build-system) #:prefix gnu:)
   #:use-module (guix build syscalls)
   #:use-module (guix build utils)
+  #:use-module (guix build archives)
   #:use-module (sxml simple)
   #:use-module (ice-9 match)
   #:use-module (ice-9 ftw)
@@ -185,44 +187,14 @@ dependencies of this jar file."
             outputs)
   #t)
 
-(define* (strip-jar-timestamps #:key outputs
+(define* (strip-jar-timestamps #:key outputs (unzip "unzip") (zip "zip")
                                #:allow-other-keys)
   "Unpack all jar archives, reset the timestamp of all contained files, and
 repack them.  This is necessary to ensure that archives are reproducible."
-  (define (repack-archive jar)
-    (format #t "repacking ~a\n" jar)
-    (let* ((dir (mkdtemp! "jar-contents.XXXXXX"))
-           (manifest (string-append dir "/META-INF/MANIFEST.MF")))
-      (with-directory-excursion dir
-        (invoke "jar" "xf" jar))
-      (delete-file jar)
-      ;; XXX: copied from (gnu build install)
-      (for-each (lambda (file)
-                  (let ((s (lstat file)))
-                    (unless (eq? (stat:type s) 'symlink)
-                      (utime file 0 0 0 0))))
-                (find-files dir #:directories? #t))
-
-      ;; The jar tool will always set the timestamp on the manifest file
-      ;; and the containing directory to the current time, even when we
-      ;; reuse an existing manifest file.  To avoid this we use "zip"
-      ;; instead of "jar".  It is important that the manifest appears
-      ;; first.
-      (with-directory-excursion dir
-        (let* ((files (find-files "." ".*" #:directories? #t))
-               ;; To ensure that the reference scanner can detect all
-               ;; store references in the jars we disable compression
-               ;; with the "-0" option.
-               (command (if (file-exists? manifest)
-                            `("zip" "-0" "-X" ,jar ,manifest ,@files)
-                            `("zip" "-0" "-X" ,jar ,@files))))
-          (apply invoke command)))
-      (utime jar 0 0)
-      #t))
-
   (for-each (match-lambda
               ((output . directory)
-               (for-each repack-archive (find-files directory "\\.jar$"))))
+               (for-each repack-archive
+                         (find-files directory "\\.jar$"))))
             outputs)
   #t)
 
diff --git a/guix/build/archives.scm b/guix/build/archives.scm
new file mode 100644
index 000000000..d2c4815bd
--- /dev/null
+++ b/guix/build/archives.scm
@@ -0,0 +1,56 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2019 Tim Gesthuizen <tim.gesthuizen <at> yahoo.de>
+;;;
+;;; This file is part of GNU Guix.
+;;;
+;;; GNU Guix is free software; you can redistribute it and/or modify it
+;;; under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 3 of the License, or (at
+;;; your option) any later version.
+;;;
+;;; GNU Guix is distributed in the hope that it will be useful, but
+;;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
+
+
+(define-module (guix build archives)
+  #:use-module (ice-9 format)
+  #:use-module (guix build utils)
+  #:use-module (guix build syscalls)
+  #:export (repack-archive))
+
+(define* (repack-archive archive
+                         #:key (unzip "unzip") (zip "zip"))
+  (format #t "repacking ~a\n" archive)
+  (let* ((dir (mkdtemp! "archive-contents.XXXXXX"))
+         (manifest (string-append dir "/META-INF/MANIFEST.MF")))
+    (with-directory-excursion dir
+      (invoke unzip archive))
+    (delete-file archive)
+    ;; XXX: copied from (gnu build install)
+    (for-each (lambda (file)
+                (let ((s (lstat file)))
+                  (unless (eq? (stat:type s) 'symlink)
+                    (utime file 0 0 0 0))))
+              (find-files dir #:directories? #t))
+
+    ;; The archive tool will always set the timestamp on the manifest file
+    ;; and the containing directory to the current time, even when we
+    ;; reuse an existing manifest file.  To avoid this we use "zip"
+    ;; instead of "archive".  It is important that the manifest appears
+    ;; first.
+    (with-directory-excursion dir
+      (let* ((files (find-files "." ".*" #:directories? #t))
+             ;; To ensure that the reference scanner can detect all
+             ;; store references in the archives we disable compression
+             ;; with the "-0" option.
+             (command (if (file-exists? manifest)
+                          `(,zip "-0" "-X" ,archive ,manifest ,@files)
+                          `(,zip "-0" "-X" ,archive ,@files))))
+        (apply invoke command)))
+    (utime archive 0 0)
+    #t))
-- 
2.20.1

[0002-gnu-pwsafe-Make-zip-archives-deterministic.patch (text/x-patch, inline)]
From 0bb0420dfdeb992b3ceafc815d42e6f403520b8d Mon Sep 17 00:00:00 2001
From: Tim Gesthuizen <tim.gesthuizen <at> yahoo.de>
Date: Sat, 2 Mar 2019 00:10:19 +0100
Subject: [PATCH 2/2] gnu: pwsafe: Make zip archives deterministic

* gnu/packages/password-utils.scm (pwsafe):
  [native-inputs]: Add unzip.
  [arguments]: Add a phase for resetting zip timestamps.
---
 gnu/packages/password-utils.scm | 17 ++++++++++++++---
 1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/gnu/packages/password-utils.scm b/gnu/packages/password-utils.scm
index 9fd5a6ff0..52870050e 100644
--- a/gnu/packages/password-utils.scm
+++ b/gnu/packages/password-utils.scm
@@ -21,7 +21,7 @@
 ;;; Copyright © 2018 Arun Isaac <arunisaac <at> systemreboot.net>
 ;;; Copyright © 2018 Pierre Neidhardt <mail <at> ambrevar.xyz>
 ;;; Copyright © 2018 Amirouche Boubekki <amirouche <at> hypermove.net>
-;;; Copyright © 2018 Tim Gesthuizen <tim.gesthuizen <at> yahoo.de>
+;;; Copyright © 2018, 2019 Tim Gesthuizen <tim.gesthuizen <at> yahoo.de>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -190,7 +190,8 @@ algorithms AES or Twofish.")
     (build-system cmake-build-system)
     (native-inputs `(("gettext" ,gettext-minimal)
                      ("perl" ,perl)
-                     ("zip" ,zip)))
+                     ("zip" ,zip)
+                     ("unzip" ,unzip)))
     (inputs `(("curl" ,curl)
               ("file" ,file)
               ("gtest" ,googletest)
@@ -201,7 +202,10 @@ algorithms AES or Twofish.")
               ("qrencode" ,qrencode)
               ("wxwidgets" ,wxwidgets)
               ("xerces-c" ,xerces-c)))
-    (arguments '(#:configure-flags (list "-DNO_GTEST=YES")
+    (arguments `(#:configure-flags (list "-DNO_GTEST=YES")
+                 #:imported-modules ((guix build syscalls)
+                                     (guix build archives)
+                                     ,@%cmake-build-system-modules)
                  #:phases (modify-phases %standard-phases
                             (add-after 'unpack 'add-gtest
                               (lambda* (#:key inputs #:allow-other-keys)
@@ -219,6 +223,13 @@ add_subdirectory(src/test)\n" cmake-port)
                                   (("/usr/bin/file")
                                    (string-append (assoc-ref inputs "file")
                                                   "/bin/file")))
+                                #t))
+                            (add-after 'install 'repack-archives
+                              (lambda* (#:key outputs #:allow-other-keys)
+                                (use-modules ((guix build archives)))
+                                (for-each repack-archive
+                                          (find-files (assoc-ref outputs "out")
+                                                      "\\.zip$"))
                                 #t)))))
     (synopsis "Password safe with automatic input and key generation")
     (description "pwsafe is a password manager originally designed by Bruce
-- 
2.20.1


This bug report was last modified 6 years and 104 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.