50
50
51
51
TYPE_CHECKING = False
52
52
if TYPE_CHECKING :
53
- from collections .abc import Iterator , Sequence
53
+ from collections .abc import Iterator , Sequence , Set
54
54
from typing import Literal
55
55
56
56
try :
@@ -1063,7 +1063,9 @@ def build_docs(args: argparse.Namespace) -> bool:
1063
1063
]
1064
1064
del args .branch
1065
1065
del args .languages
1066
- all_built_successfully = True
1066
+
1067
+ build_succeeded = set ()
1068
+ build_failed = set ()
1067
1069
cpython_repo = Repository (
1068
1070
"https://github.com/python/cpython.git" ,
1069
1071
args .build_root / _checkout_name (args .select_output ),
@@ -1083,7 +1085,12 @@ def build_docs(args: argparse.Namespace) -> bool:
1083
1085
builder = DocBuilder (
1084
1086
version , versions , language , languages , cpython_repo , ** vars (args )
1085
1087
)
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
+
1087
1094
logging .root .handlers [0 ].setFormatter (
1088
1095
logging .Formatter ("%(asctime)s %(levelname)s: %(message)s" )
1089
1096
)
@@ -1096,27 +1103,20 @@ def build_docs(args: argparse.Namespace) -> bool:
1096
1103
args .skip_cache_invalidation ,
1097
1104
http ,
1098
1105
)
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 (
1108
1107
args .www_root ,
1109
1108
args .group ,
1110
1109
versions ,
1111
1110
languages ,
1111
+ build_succeeded ,
1112
1112
args .skip_cache_invalidation ,
1113
1113
http ,
1114
1114
)
1115
1115
proofread_canonicals (args .www_root , args .skip_cache_invalidation , http )
1116
1116
1117
1117
logging .info ("Full build done (%s)." , format_seconds (perf_counter () - start_time ))
1118
1118
1119
- return all_built_successfully
1119
+ return len ( build_failed ) == 0
1120
1120
1121
1121
1122
1122
def parse_versions_from_devguide (http : urllib3 .PoolManager ) -> Versions :
@@ -1182,79 +1182,60 @@ def copy_robots_txt(
1182
1182
purge (http , "robots.txt" )
1183
1183
1184
1184
1185
- def major_symlinks (
1185
+ def make_symlinks (
1186
1186
www_root : Path ,
1187
1187
group : str ,
1188
1188
versions : Versions ,
1189
1189
languages : Languages ,
1190
+ successful_builds : Set [tuple [str , str ]],
1190
1191
skip_cache_invalidation : bool ,
1191
1192
http : urllib3 .PoolManager ,
1192
1193
) -> None :
1193
- """Maintains the /2/ and /3 / symlinks for each language.
1194
+ """Maintains the /2/, /3/, and /dev / symlinks for each language.
1194
1195
1195
1196
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/
1199
1202
"""
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
+ )
1242
1220
1243
1221
1244
1222
def symlink (
1245
1223
www_root : Path ,
1246
- language : Language ,
1224
+ language_tag : str ,
1247
1225
directory : str ,
1248
1226
name : str ,
1249
1227
group : str ,
1250
1228
skip_cache_invalidation : bool ,
1251
1229
http : urllib3 .PoolManager ,
1252
1230
) -> None :
1253
1231
"""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/
1255
1234
path = www_root
1235
+ logging .debug (msg , name , directory )
1256
1236
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 } " )
1258
1239
link = path / name
1259
1240
directory_path = path / directory
1260
1241
if not directory_path .exists ():
@@ -1266,7 +1247,7 @@ def symlink(
1266
1247
link .symlink_to (directory )
1267
1248
run (["chown" , "-h" , f":{ group } " , str (link )])
1268
1249
if not skip_cache_invalidation :
1269
- surrogate_key = f"{ language . tag } /{ name } "
1250
+ surrogate_key = f"{ language_tag } /{ name } "
1270
1251
purge_surrogate_key (http , surrogate_key )
1271
1252
1272
1253
0 commit comments