1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
|
Author: Reiner Herrmann <reiner@reiner-h.de>, Kenneth J. Pronovici <pronovic@debian.org>
Description: Use SOURCE_DATE_EPOCH, if available, rather than the current date.
A lot of Debian packages rely on Epydoc during their build process. By
default, Eypdoc-generated documentation is "unreproducible", meaning that the
content of the generated files changes from build to build even if the source
tree does not.
.
This patch changes Epydoc to use a deterministic date taken from environment
variable SOURCE_DATE_EPOCH, instead of using the current date. This helps
make the Epydoc-generated documentation more predictible.
.
This patch was contributed by the Debian Reproducible Builds effort [1].
[1]: https://wiki.debian.org/ReproducibleBuilds/TimestampsProposal
Bug: https://sourceforge.net/p/epydoc/bugs/368/
Bug-Debian: http://bugs.debian.org/790899
Forwarded: https://sourceforge.net/p/epydoc/bugs/368/
Last-Update: 2015-07-12
Index: epydoc-3.0.1+dfsg/epydoc/docwriter/html.py
===================================================================
--- epydoc-3.0.1+dfsg.orig/epydoc/docwriter/html.py
+++ epydoc-3.0.1+dfsg/epydoc/docwriter/html.py
@@ -433,6 +433,14 @@ class HTMLWriter:
and d.container == doc]
self.indexed_docs.sort()
+ # set build time
+ self._build_time = time.gmtime()
+ if os.environ.has_key('SOURCE_DATE_EPOCH'):
+ try:
+ self._build_time = time.gmtime(int(os.environ['SOURCE_DATE_EPOCH']))
+ except ValueError:
+ pass
+
# Figure out the url for the top page.
self._top_page_url = self._find_top_page(self._top_page)
@@ -1780,7 +1788,7 @@ class HTMLWriter:
>>> #endif
Generated by Epydoc $epydoc.__version__$
>>> if self._include_build_time:
- on $time.asctime()$
+ on $time.asctime(self._build_time)$
>>> #endif
>>> if self._include_log:
</a>
Index: epydoc-3.0.1+dfsg/epydoc/docwriter/latex.py
===================================================================
--- epydoc-3.0.1+dfsg.orig/epydoc/docwriter/latex.py
+++ epydoc-3.0.1+dfsg/epydoc/docwriter/latex.py
@@ -14,7 +14,7 @@ this module is the L{LatexWriter} class.
"""
__docformat__ = 'epytext en'
-import os.path, sys, time, re, textwrap, codecs
+import os.path, os, sys, time, re, textwrap, codecs
from epydoc.apidoc import *
from epydoc.compat import *
@@ -1099,6 +1099,12 @@ class LatexWriter:
#////////////////////////////////////////////////////////////
def write_header(self, out, where):
+ build_time = time.gmtime()
+ if os.environ.has_key('SOURCE_DATE_EPOCH'):
+ try:
+ build_time = time.gmtime(int(os.environ['SOURCE_DATE_EPOCH']))
+ except ValueError:
+ pass
out('%\n% API Documentation')
if self._prj_name: out(' for %s' % self._prj_name)
if isinstance(where, APIDoc):
@@ -1106,7 +1112,7 @@ class LatexWriter:
else:
out('\n%% %s' % where)
out('\n%%\n%% Generated by epydoc %s\n' % epydoc.__version__)
- out('%% [%s]\n%%\n' % time.asctime(time.localtime(time.time())))
+ out('%% [%s]\n%%\n' % time.asctime(build_time))
def write_start_of(self, out, section_name):
out('\n' + 75*'%' + '\n')
Index: epydoc-3.0.1+dfsg/man/epydoc.1
===================================================================
--- epydoc-3.0.1+dfsg.orig/man/epydoc.1
+++ epydoc-3.0.1+dfsg/man/epydoc.1
@@ -62,6 +62,32 @@ method, and function has a docstring des
.B \-\-tests
option can be used to specify additional tests to perform.
.PP
+.\" ==== REPRODUCIBLE BUILD BEHAVIOR ===============
+.SH REPRODUCIBLE BUILD BEHAVIOR
+.PP
+Using the current date within Epydoc-generated documentation results in
+documentation that is "unreproducible", meaning that the content of the files
+changes from build to build even if the source tree does not. To make it
+easier to generate reproducible builds, this version of Epydoc supports two
+features: the
+.B \-\-no\-include\-build\-time
+option and the
+.B SOURCE_DATE_EPOCH
+environment variable.
+.PP
+The
+.B \-\-no\-include\-build\-time
+option can be used when you know up-front that you do not need build timestamps
+in your generated documentation. The
+.B SOURCE_DATE_EPOCH
+environment variable is intended for use by packaging systems, such as the Debian
+build process. Packaging systems will set
+.B SOURCE_DATE_EPOCH
+to a sensible timestamp that is somehow related to the state of the source
+tree, and that timestamp will be used by Eypdoc rather than the current
+timestamp. Builds using
+.B SOURCE_DATE_EPOCH
+will thus be reproducible.
.\" ================== OPTIONS ====================
.SH OPTIONS
Epydoc's options are divided into six categories: basic options,
|