-
Notifications
You must be signed in to change notification settings - Fork 547
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
🤖 Set build config via Sphinx ext #2360
base: devel
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
"""Sphinx extension for setting up the build settings.""" | ||
|
||
import subprocess | ||
from dataclasses import dataclass | ||
from functools import cache | ||
from pathlib import Path | ||
from tomllib import loads as parse_toml_string | ||
from typing import Literal | ||
|
||
from sphinx.application import Sphinx | ||
from sphinx.util import logging | ||
|
||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
DOCSITE_ROOT_DIR = Path(__file__).parents[1].resolve() | ||
DOCSITE_EOL_CONFIG_PATH = DOCSITE_ROOT_DIR / 'end_of_life.toml' | ||
|
||
|
||
@dataclass(frozen=True) | ||
class Distribution: | ||
end_of_life: list[str] | ||
supported: list[str] | ||
|
||
@classmethod | ||
def from_dict(cls, raw_dist: dict[str, list[str]]) -> 'Distribution': | ||
return cls( | ||
**{ | ||
kind.replace('-', '_'): versions | ||
for kind, versions in raw_dist.items() | ||
}, | ||
) | ||
|
||
|
||
EOLConfigType = dict[str, Distribution] | ||
|
||
|
||
@cache | ||
def _read_eol_data() -> EOLConfigType: | ||
raw_config_dict = parse_toml_string(DOCSITE_EOL_CONFIG_PATH.read_text()) | ||
|
||
return { | ||
dist_name: Distribution.from_dict(dist_data) | ||
for dist_name, dist_data in raw_config_dict['distribution'].items() | ||
} | ||
|
||
|
||
@cache | ||
def _is_eol_build(git_branch: str, kind: str) -> bool: | ||
return git_branch in _read_eol_data()[kind].end_of_life | ||
|
||
|
||
@cache | ||
def _get_current_git_branch(): | ||
git_branch_cmd = 'git', 'rev-parse', '--abbrev-ref', 'HEAD' | ||
|
||
try: | ||
return subprocess.check_output(git_branch_cmd, text=True).strip() | ||
except subprocess.CalledProcessError as proc_err: | ||
raise LookupError( | ||
f'Failed to locate current Git branch: {proc_err !s}', | ||
) from proc_err | ||
|
||
|
||
def _set_global_j2_context(app, config): | ||
if 'is_eol' in config.html_context: | ||
raise ValueError( | ||
'`is_eol` found in `html_context` unexpectedly. ' | ||
'It should not be set in `conf.py`.', | ||
) from None | ||
|
||
dist_name = ( | ||
'ansible-core' if app.tags.has('core') | ||
else 'ansible' if app.tags.has('ansible') | ||
else None | ||
) | ||
|
||
if dist_name is None: | ||
return | ||
|
||
try: | ||
git_branch = _get_current_git_branch() | ||
except LookupError as lookup_err: | ||
logger.info(str(lookup_err)) | ||
return | ||
|
||
config.html_context['is_eol'] = _is_eol_build( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @oraNod this is what sets that value into the variable defined in |
||
git_branch=git_branch, kind=dist_name, | ||
) | ||
|
||
|
||
def setup(app: Sphinx) -> dict[str, bool | str]: | ||
"""Initialize the extension. | ||
|
||
:param app: A Sphinx application object. | ||
:returns: Extension metadata as a dict. | ||
""" | ||
|
||
# NOTE: `config-inited` is used because it runs once as opposed to | ||
# NOTE: `html-page-context` that runs per each page. The data we | ||
# NOTE: compute is immutable throughout the build so there's no need | ||
# NOTE: to have a callback that would be executed hundreds of times. | ||
app.connect('config-inited', _set_global_j2_context) | ||
|
||
return { | ||
'parallel_read_safe': True, | ||
'parallel_write_safe': True, | ||
'version': app.config.release, | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
[distribution.ansible] | ||
end-of-life = [ | ||
'stable-2.15', | ||
'stable-2.14', | ||
'stable-2.13', | ||
] | ||
supported = [ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @oraNod did you plan to use this list somehow? I just copied it, but it's not actually used anywhere. |
||
'devel', | ||
'stable-2.18', | ||
'stable-2.17', | ||
'stable-2.16', | ||
] | ||
|
||
[distribution.ansible-core] | ||
end-of-life = [ | ||
'stable-2.15', | ||
'stable-2.14', | ||
'stable-2.13', | ||
] | ||
supported = [ | ||
'devel', | ||
'stable-2.18', | ||
'stable-2.17', | ||
'stable-2.16', | ||
] | ||
Comment on lines
+14
to
+25
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @oraNod things here are the same as in the other mapping. Did you expect them to differ at some point? What's the semantic meaning you were going for? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The dataclass has to have snake_case attrs so this is doing that conversion. It effectively maps
end-of-life
in the TOML config toend_of_life
.