From: intrigeri <intrigeri@debian.org>
Date: Sun, 24 May 2015 14:45:46 +0000
Subject: Build.PL: when a PO_BUILD_DATE environment variable is passed,
 use it to fake the time for running po4a-{translate, updatepo}, xgettext,
 msgmerge and msgfmt.

The build system updates POT files, and in turn .po and .mo files. As a result,
.mo files created as part of the Debian package build process embed timestamps,
which prevent the package from building reproducibly.

With this change in, the Debian packaging can pass whatever $PO_BUILD_DATE it
wants to (most likely: the date of the most recent entry in debian/changelog),
and then the package can be built reproducibly.
---
 Build.PL | 33 ++++++++++++++++++++++-----------
 1 file changed, 22 insertions(+), 11 deletions(-)

diff --git a/Build.PL b/Build.PL
index 76c9fa5..719cc6a 100644
--- a/Build.PL
+++ b/Build.PL
@@ -10,6 +10,8 @@ my $builder = Module::Build->subclass
      class => 'My::Builder',
      code => q{
 	 { use strict;
+         use String::ShellQuote;
+         __PACKAGE__->add_property('po_faketime_cmd');
 	 my $bin_po_dir = 'po';
 	 my $bin_pot_file = 'bin.pot';
 	 my $bin_po_prefix = 'bin.';
@@ -49,7 +51,7 @@ my $builder = Module::Build->subclass
 	     unless ($self->up_to_date(\@files, $bin_pot_path)) {
 		 print "XX Update $bin_pot_path\n";
 		 my $podfiles = join ("", map { " $base_dir/$_" } @files);
-		 system("cd $bin_po_dir; xgettext --copyright-holder=\"Frank Lichtenheld\" --keyword=__g --msgid-bugs-address=frank\@lichtenheld.de -L Perl $podfiles -o $bin_pot_file.new") && die;
+		 system("cd $bin_po_dir; ".$self->po_faketime_str." xgettext --copyright-holder=\"Frank Lichtenheld\" --keyword=__g --msgid-bugs-address=frank\@lichtenheld.de -L Perl $podfiles -o $bin_pot_file.new") && die;
 		 if ( -e $bin_pot_path) {
 		     my $diff = qx(diff -q -I'#:' -I'POT-Creation-Date:' -I'PO-Revision-Date:' $bin_pot_path $bin_pot_path.new);
 		     if ( $diff eq "" ) {
@@ -77,7 +79,8 @@ my $builder = Module::Build->subclass
 		 unless ($self->up_to_date($bin_pot_path,
 					   "$bin_po_dir/$bin_po_prefix$lang.po")) {
 		     print "XX Sync $bin_po_dir/$bin_po_prefix$lang.po: ";
-		     system('msgmerge', "$bin_po_dir/$bin_po_prefix$lang.po",
+		     system(@{$self->po_faketime_cmd},
+                            'msgmerge', "$bin_po_dir/$bin_po_prefix$lang.po",
 			    "$bin_pot_path",
 			    "-o", "$bin_po_dir/$bin_po_prefix$lang.po.new")
 			 && die;
@@ -102,7 +105,7 @@ my $builder = Module::Build->subclass
 					   "blib/po/$lang/LC_MESSAGES/$bin_mo_file.mo")) {
 		     print "X Generate $bin_mo_file.mo for $lang.\n";
 		     system('mkdir', '-p', "blib/po/$lang/LC_MESSAGES") && die;
-		     system('msgfmt', '-o',
+		     system(@{$self->po_faketime_cmd}, 'msgfmt', '-o',
 			    "blib/po/$lang/LC_MESSAGES/$bin_mo_file.mo",
 			    "$bin_po_dir/$bin_po_prefix$lang.po") && die;
 		 } else {
@@ -120,7 +123,7 @@ my $builder = Module::Build->subclass
 	     unless ($self->up_to_date(\@files, $doc_pot_path)) {
 		 my $podfiles = join ("", map {" -m $base_dir/$_" } @files);
 		 print "XX Update documentation pot files: ";
-		 system("cd $doc_po_dir; ${po4a_path}po4a-updatepo -f pod $podfiles -M utf-8 -p $doc_pot_file")
+		 system("cd $doc_po_dir; ".$self->po_faketime_str." ${po4a_path}po4a-updatepo -f pod $podfiles -M utf-8 -p $doc_pot_file")
 		     && die;
 		 my ($atime, $mtime) = (time,time);
 		 utime $atime, $mtime, $doc_pot_path;
@@ -138,8 +141,8 @@ my $builder = Module::Build->subclass
 		 unless ($self->up_to_date($doc_pot_path,
 					   "$doc_po_dir/$doc_po_prefix$lang.po")) {
 		     print "XX Update documentation $doc_po_prefix$lang.po: ";
-
-		     system('msgmerge', "$doc_po_dir/$doc_po_prefix$lang.po",
+		     system(@{$self->po_faketime_cmd},
+                            'msgmerge', "$doc_po_dir/$doc_po_prefix$lang.po",
 			    "$doc_pot_path",
 			    '-o', "$doc_po_dir/$doc_po_prefix$lang.po.new")
 			 && die;
@@ -164,7 +167,7 @@ my $builder = Module::Build->subclass
 					   "blib/po/$lang/LC_MESSAGES/$doc_mo_file.mo")) {
 		     print "X Generate $doc_mo_file.mo for $lang.\n";
 		     system('mkdir', '-p', "blib/po/$lang/LC_MESSAGES") && die;
-		     system('msgfmt', '-o',
+		     system(@{$self->po_faketime_cmd}, 'msgfmt', '-o',
 			    "blib/po/$lang/LC_MESSAGES/$doc_mo_file.mo",
 			    "$doc_po_dir/$doc_po_prefix$lang.po") && die;
 		 } else {
@@ -200,7 +203,7 @@ my $builder = Module::Build->subclass
 	     foreach my $lang (@langs) {
 		 print ("X Translate binary manpages to $lang\n");
 		 foreach my $file (keys(%{$self->script_files()})) {
-		     system("${po4a_path}po4a-translate $options -m $file -p $doc_po_dir/$doc_po_prefix$lang.po -l blib/man/$file")
+		     system($self->po_faketime_str." ${po4a_path}po4a-translate $options -m $file -p $doc_po_dir/$doc_po_prefix$lang.po -l blib/man/$file")
 			 && die;
 		     if (-e "blib/man/$file") {
 			 system("mkdir", "-p", "blib/man/$lang/man1") && die;
@@ -224,7 +227,7 @@ my $builder = Module::Build->subclass
 		 foreach my $file (@{$self->rscan_dir('lib',qr/\.pm$/)}) {
 		     $file =~ /.*\/(.*)\.pm$/;
 		     my $filename = $1;
-		     system("${po4a_path}po4a-translate $options -m $file -p $doc_po_dir/$doc_po_prefix$lang.po -l blib/man/$filename")
+		     system($self->po_faketime_str." ${po4a_path}po4a-translate $options -m $file -p $doc_po_dir/$doc_po_prefix$lang.po -l blib/man/$filename")
 			 && die;
 		     if (-e "blib/man/$filename") {
 			 system ("mkdir", "-p", "blib/man/$lang/man3") && die;
@@ -276,13 +279,20 @@ my $builder = Module::Build->subclass
 		 my $stat = `msgfmt -o /dev/null -c -v --statistics $file 2>&1`;
 		 print "  $lang: $stat";
 	     }
-	 } }
+	 }
+         sub po_faketime_str {
+             my $self = shift;
+             # return '"' . join('" "', @{$self->po_faketime_cmd}) . '"';
+             return shell_quote @{$self->po_faketime_cmd};
+         } }
      },
      );
 
 my $base= $Config::Config{man1dir};
 $base =~ s/\/man\/man1//;
 
+my $po_build_date = $ENV{PO_BUILD_DATE};
+
 my $b = $builder->new
     ( module_name => 'Parse-DebianChangelog',
       license => 'gpl',
@@ -298,5 +308,6 @@ my $b = $builder->new
       install_path => {po => $base.'/locale', man => $base.'/man'},
       create_packlist => 0,
       dist_abstract => 'parse Debian changelogs and output them in other formats',
-      dist_author => ['Frank Lichtenheld <djpig@debian.org>']
+      dist_author => ['Frank Lichtenheld <djpig@debian.org>'],
+      po_faketime_cmd => defined $po_build_date ? ['faketime', '-f', $po_build_date] : [],
       )->create_build_script;
