mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Merge pull request #2503 from JojoBoulix/stable
Extend SOURCE_DATE_EPOCH support
This commit is contained in:
commit
20719f0b00
@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from os import path, walk
|
from os import path, walk, getenv
|
||||||
from codecs import open
|
from codecs import open
|
||||||
from time import time
|
from time import time
|
||||||
from datetime import datetime, tzinfo, timedelta
|
from datetime import datetime, tzinfo, timedelta
|
||||||
@ -130,6 +130,12 @@ class I18nBuilder(Builder):
|
|||||||
timestamp = time()
|
timestamp = time()
|
||||||
tzdelta = datetime.fromtimestamp(timestamp) - \
|
tzdelta = datetime.fromtimestamp(timestamp) - \
|
||||||
datetime.utcfromtimestamp(timestamp)
|
datetime.utcfromtimestamp(timestamp)
|
||||||
|
# set timestamp from SOURCE_DATE_EPOCH if set
|
||||||
|
# see https://reproducible-builds.org/specs/source-date-epoch/
|
||||||
|
source_date_epoch = getenv('SOURCE_DATE_EPOCH')
|
||||||
|
if source_date_epoch is not None:
|
||||||
|
timestamp = float(source_date_epoch)
|
||||||
|
tzdelta = 0
|
||||||
|
|
||||||
|
|
||||||
class LocalTimeZone(tzinfo):
|
class LocalTimeZone(tzinfo):
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import re
|
import re
|
||||||
from os import path, environ
|
from os import path, environ, getenv
|
||||||
import shlex
|
import shlex
|
||||||
|
|
||||||
from six import PY2, PY3, iteritems, string_types, binary_type, text_type, integer_types
|
from six import PY2, PY3, iteritems, string_types, binary_type, text_type, integer_types
|
||||||
@ -19,8 +19,10 @@ from sphinx.errors import ConfigError
|
|||||||
from sphinx.locale import l_
|
from sphinx.locale import l_
|
||||||
from sphinx.util.osutil import make_filename, cd
|
from sphinx.util.osutil import make_filename, cd
|
||||||
from sphinx.util.pycompat import execfile_, NoneType
|
from sphinx.util.pycompat import execfile_, NoneType
|
||||||
|
from sphinx.util.i18n import format_date
|
||||||
|
|
||||||
nonascii_re = re.compile(br'[\x80-\xff]')
|
nonascii_re = re.compile(br'[\x80-\xff]')
|
||||||
|
copyright_year_re = re.compile(r'^((\d{4}-)?)(\d{4})(?=[ ,])')
|
||||||
|
|
||||||
CONFIG_SYNTAX_ERROR = "There is a syntax error in your configuration file: %s"
|
CONFIG_SYNTAX_ERROR = "There is a syntax error in your configuration file: %s"
|
||||||
if PY3:
|
if PY3:
|
||||||
@ -298,6 +300,15 @@ class Config(object):
|
|||||||
self.setup = config.get('setup', None)
|
self.setup = config.get('setup', None)
|
||||||
self.extensions = config.get('extensions', [])
|
self.extensions = config.get('extensions', [])
|
||||||
|
|
||||||
|
# correct values of copyright year that are not coherent with
|
||||||
|
# the SOURCE_DATE_EPOCH environment variable (if set)
|
||||||
|
# See https://reproducible-builds.org/specs/source-date-epoch/
|
||||||
|
if getenv('SOURCE_DATE_EPOCH') is not None:
|
||||||
|
for k in ('copyright', 'epub_copyright'):
|
||||||
|
if k in config:
|
||||||
|
config[k] = copyright_year_re.sub('\g<1>%s' % format_date('%Y'),
|
||||||
|
config[k])
|
||||||
|
|
||||||
def check_types(self, warn):
|
def check_types(self, warn):
|
||||||
# check all values for deviation from the default value's type, since
|
# check all values for deviation from the default value's type, since
|
||||||
# that can result in TypeErrors all over the place
|
# that can result in TypeErrors all over the place
|
||||||
|
@ -14,7 +14,6 @@ import os
|
|||||||
import re
|
import re
|
||||||
import warnings
|
import warnings
|
||||||
from os import path
|
from os import path
|
||||||
from time import gmtime
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
|
|
||||||
@ -188,7 +187,7 @@ def format_date(format, date=None, language=None, warn=None):
|
|||||||
# See https://wiki.debian.org/ReproducibleBuilds/TimestampsProposal
|
# See https://wiki.debian.org/ReproducibleBuilds/TimestampsProposal
|
||||||
source_date_epoch = os.getenv('SOURCE_DATE_EPOCH')
|
source_date_epoch = os.getenv('SOURCE_DATE_EPOCH')
|
||||||
if source_date_epoch is not None:
|
if source_date_epoch is not None:
|
||||||
date = gmtime(float(source_date_epoch))
|
date = datetime.utcfromtimestamp(float(source_date_epoch))
|
||||||
else:
|
else:
|
||||||
date = datetime.now()
|
date = datetime.now()
|
||||||
|
|
||||||
|
3
tests/roots/test-correct-year/conf.py
Normal file
3
tests/roots/test-correct-year/conf.py
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
|
||||||
|
copyright = u'2006-2009, Author'
|
||||||
|
|
4
tests/roots/test-correct-year/contents.rst
Normal file
4
tests/roots/test-correct-year/contents.rst
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
=================
|
||||||
|
test-correct-year
|
||||||
|
=================
|
||||||
|
|
49
tests/test_correct_year.py
Normal file
49
tests/test_correct_year.py
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
test_correct_year
|
||||||
|
~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Test copyright year adjustment
|
||||||
|
|
||||||
|
:copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
|
||||||
|
:license: BSD, see LICENSE for details.
|
||||||
|
"""
|
||||||
|
import os
|
||||||
|
|
||||||
|
from util import TestApp
|
||||||
|
|
||||||
|
|
||||||
|
def test_correct_year():
|
||||||
|
try:
|
||||||
|
# save current value of SOURCE_DATE_EPOCH
|
||||||
|
sde = os.environ.pop('SOURCE_DATE_EPOCH',None)
|
||||||
|
|
||||||
|
# test with SOURCE_DATE_EPOCH unset: no modification
|
||||||
|
app = TestApp(buildername='html',testroot='correct-year')
|
||||||
|
app.builder.build_all()
|
||||||
|
content = (app.outdir / 'contents.html').text()
|
||||||
|
app.cleanup()
|
||||||
|
assert '2006-2009' in content
|
||||||
|
|
||||||
|
# test with SOURCE_DATE_EPOCH set: copyright year should be
|
||||||
|
# updated
|
||||||
|
os.environ['SOURCE_DATE_EPOCH'] = "1293840000"
|
||||||
|
app = TestApp(buildername='html',testroot='correct-year')
|
||||||
|
app.builder.build_all()
|
||||||
|
content = (app.outdir / 'contents.html').text()
|
||||||
|
app.cleanup()
|
||||||
|
assert '2006-2011' in content
|
||||||
|
|
||||||
|
os.environ['SOURCE_DATE_EPOCH'] = "1293839999"
|
||||||
|
app = TestApp(buildername='html',testroot='correct-year')
|
||||||
|
app.builder.build_all()
|
||||||
|
content = (app.outdir / 'contents.html').text()
|
||||||
|
app.cleanup()
|
||||||
|
assert '2006-2010' in content
|
||||||
|
|
||||||
|
finally:
|
||||||
|
# Restores SOURCE_DATE_EPOCH
|
||||||
|
if sde == None:
|
||||||
|
os.environ.pop('SOURCE_DATE_EPOCH',None)
|
||||||
|
else:
|
||||||
|
os.environ['SOURCE_DATE_EPOCH'] = sde
|
Loading…
Reference in New Issue
Block a user