Skip to content

Commit a6c458d

Browse files
authored
Only recreate a symlink when the relevant version has changed (#257)
1 parent 1a8a586 commit a6c458d

File tree

1 file changed

+45
-64
lines changed

1 file changed

+45
-64
lines changed

build_docs.py

+45-64
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@
5050

5151
TYPE_CHECKING = False
5252
if TYPE_CHECKING:
53-
from collections.abc import Iterator, Sequence
53+
from collections.abc import Iterator, Sequence, Set
5454
from typing import Literal
5555

5656
try:
@@ -1063,7 +1063,9 @@ def build_docs(args: argparse.Namespace) -> bool:
10631063
]
10641064
del args.branch
10651065
del args.languages
1066-
all_built_successfully = True
1066+
1067+
build_succeeded = set()
1068+
build_failed = set()
10671069
cpython_repo = Repository(
10681070
"https://github.com/python/cpython.git",
10691071
args.build_root / _checkout_name(args.select_output),
@@ -1083,7 +1085,12 @@ def build_docs(args: argparse.Namespace) -> bool:
10831085
builder = DocBuilder(
10841086
version, versions, language, languages, cpython_repo, **vars(args)
10851087
)
1086-
all_built_successfully &= builder.run(http)
1088+
built_successfully = builder.run(http)
1089+
if built_successfully:
1090+
build_succeeded.add((version.name, language.tag))
1091+
else:
1092+
build_failed.add((version.name, language.tag))
1093+
10871094
logging.root.handlers[0].setFormatter(
10881095
logging.Formatter("%(asctime)s %(levelname)s: %(message)s")
10891096
)
@@ -1096,27 +1103,20 @@ def build_docs(args: argparse.Namespace) -> bool:
10961103
args.skip_cache_invalidation,
10971104
http,
10981105
)
1099-
major_symlinks(
1100-
args.www_root,
1101-
args.group,
1102-
versions,
1103-
languages,
1104-
args.skip_cache_invalidation,
1105-
http,
1106-
)
1107-
dev_symlink(
1106+
make_symlinks(
11081107
args.www_root,
11091108
args.group,
11101109
versions,
11111110
languages,
1111+
build_succeeded,
11121112
args.skip_cache_invalidation,
11131113
http,
11141114
)
11151115
proofread_canonicals(args.www_root, args.skip_cache_invalidation, http)
11161116

11171117
logging.info("Full build done (%s).", format_seconds(perf_counter() - start_time))
11181118

1119-
return all_built_successfully
1119+
return len(build_failed) == 0
11201120

11211121

11221122
def parse_versions_from_devguide(http: urllib3.PoolManager) -> Versions:
@@ -1182,79 +1182,60 @@ def copy_robots_txt(
11821182
purge(http, "robots.txt")
11831183

11841184

1185-
def major_symlinks(
1185+
def make_symlinks(
11861186
www_root: Path,
11871187
group: str,
11881188
versions: Versions,
11891189
languages: Languages,
1190+
successful_builds: Set[tuple[str, str]],
11901191
skip_cache_invalidation: bool,
11911192
http: urllib3.PoolManager,
11921193
) -> None:
1193-
"""Maintains the /2/ and /3/ symlinks for each language.
1194+
"""Maintains the /2/, /3/, and /dev/ symlinks for each language.
11941195
11951196
Like:
1196-
- /3/ → /3.9/
1197-
- /fr/3/ → /fr/3.9/
1198-
- /es/3/ → /es/3.9/
1197+
- /2/ → /2.7/
1198+
- /3/ → /3.12/
1199+
- /dev/ → /3.14/
1200+
- /fr/3/ → /fr/3.12/
1201+
- /es/dev/ → /es/3.14/
11991202
"""
1200-
logging.info("Creating major version symlinks...")
1201-
current_stable = versions.current_stable.name
1202-
for language in languages:
1203-
symlink(
1204-
www_root,
1205-
language,
1206-
current_stable,
1207-
"3",
1208-
group,
1209-
skip_cache_invalidation,
1210-
http,
1211-
)
1212-
symlink(www_root, language, "2.7", "2", group, skip_cache_invalidation, http)
1213-
1214-
1215-
def dev_symlink(
1216-
www_root: Path,
1217-
group,
1218-
versions,
1219-
languages,
1220-
skip_cache_invalidation: bool,
1221-
http: urllib3.PoolManager,
1222-
) -> None:
1223-
"""Maintains the /dev/ symlinks for each language.
1224-
1225-
Like:
1226-
- /dev/ → /3.11/
1227-
- /fr/dev/ → /fr/3.11/
1228-
- /es/dev/ → /es/3.11/
1229-
"""
1230-
logging.info("Creating development version symlinks...")
1231-
current_dev = versions.current_dev.name
1232-
for language in languages:
1233-
symlink(
1234-
www_root,
1235-
language,
1236-
current_dev,
1237-
"dev",
1238-
group,
1239-
skip_cache_invalidation,
1240-
http,
1241-
)
1203+
logging.info("Creating major and development version symlinks...")
1204+
for symlink_name, symlink_target in (
1205+
("3", versions.current_stable.name),
1206+
("2", "2.7"),
1207+
("dev", versions.current_dev.name),
1208+
):
1209+
for language in languages:
1210+
if (symlink_target, language.tag) in successful_builds:
1211+
symlink(
1212+
www_root,
1213+
language.tag,
1214+
symlink_target,
1215+
symlink_name,
1216+
group,
1217+
skip_cache_invalidation,
1218+
http,
1219+
)
12421220

12431221

12441222
def symlink(
12451223
www_root: Path,
1246-
language: Language,
1224+
language_tag: str,
12471225
directory: str,
12481226
name: str,
12491227
group: str,
12501228
skip_cache_invalidation: bool,
12511229
http: urllib3.PoolManager,
12521230
) -> None:
12531231
"""Used by major_symlinks and dev_symlink to maintain symlinks."""
1254-
if language.tag == "en": # English is rooted on /, no /en/
1232+
msg = "Creating symlink from %s to %s"
1233+
if language_tag == "en": # English is rooted on /, no /en/
12551234
path = www_root
1235+
logging.debug(msg, name, directory)
12561236
else:
1257-
path = www_root / language.tag
1237+
path = www_root / language_tag
1238+
logging.debug(msg, f"{language_tag}/{name}", f"{language_tag}/{directory}")
12581239
link = path / name
12591240
directory_path = path / directory
12601241
if not directory_path.exists():
@@ -1266,7 +1247,7 @@ def symlink(
12661247
link.symlink_to(directory)
12671248
run(["chown", "-h", f":{group}", str(link)])
12681249
if not skip_cache_invalidation:
1269-
surrogate_key = f"{language.tag}/{name}"
1250+
surrogate_key = f"{language_tag}/{name}"
12701251
purge_surrogate_key(http, surrogate_key)
12711252

12721253

0 commit comments

Comments
 (0)