Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support placeholders for years in copyright #12910

Merged
merged 11 commits into from
Oct 4, 2024
3 changes: 1 addition & 2 deletions doc/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

import os
import re
import time
from typing import TYPE_CHECKING

from sphinx import __display_version__
Expand All @@ -27,7 +26,7 @@
exclude_patterns = ['_build']

project = 'Sphinx'
copyright = f'2007-{time.strftime("%Y")}, the Sphinx developers'
copyright = '2007-%Y, the Sphinx developers'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Although I think we should support this templating for other projects, I have a strong preference for using constant/static copyright notices where possible (although I fully admit that adding supporting tooling to detect cases where they're out-of-date could be useful).

Given that, and the fact that we update most of the copyright notices throughout the codebase manually each year, I wonder whether we should do the same here.

Suggested change
copyright = '2007-%Y, the Sphinx developers'
copyright = '2007-2024, the Sphinx developers'

release = version = __display_version__
show_authors = True
nitpicky = True
Expand Down
27 changes: 19 additions & 8 deletions sphinx/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -626,27 +626,38 @@ def correct_copyright_year(_app: Sphinx, config: Config) -> None:
See https://reproducible-builds.org/specs/source-date-epoch/
"""
if source_date_epoch := int(getenv('SOURCE_DATE_EPOCH', '0')):
source_date_epoch_year = time.gmtime(source_date_epoch).tm_year
replace_year = time.gmtime(source_date_epoch).tm_year
else:
return
jayaddison marked this conversation as resolved.
Show resolved Hide resolved
replace_year = time.gmtime().tm_year

# If the current year is the replacement year, there's no work to do.
# We also skip replacement years that are in the future.
current_year = time.localtime().tm_year
if current_year <= source_date_epoch_year:
if current_year <= replace_year:
return

current_yr = str(current_year)
replace_yr = str(source_date_epoch_year)
replace_yr = str(replace_year)
year_short = str(replace_year % 100)
for k in ('copyright', 'epub_copyright'):
if k in config:
value: str | Sequence[str] = config[k]
if isinstance(value, str):
config[k] = _substitute_copyright_year(value, current_yr, replace_yr)
if '%y' in value or '%Y' in value:
# new-style placeholder replacement
config[k] = value.replace('%Y', replace_yr).replace('%y', year_short)
else:
config[k] = _substitute_copyright_year(value, current_yr, replace_yr)
else:
items = (
_substitute_copyright_year(x, current_yr, replace_yr) for x in value
)
if any('%y' in line or '%Y' in line for line in value):
# new-style placeholder replacement
items = (
x.replace('%Y', replace_yr).replace('%y', year_short) for x in value
)
else:
items = (
_substitute_copyright_year(x, current_yr, replace_yr) for x in value
)
config[k] = type(value)(items) # type: ignore[call-arg]


Expand Down