@@ -28,12 +28,14 @@ class ExitCode(IntFlag):
28
28
NORMAL = 0
29
29
INVALID_UPDATES = 1 << 4
30
30
MISSING_UPDATES = 1 << 5
31
+ NON_UNIQUE_DIRECTIONS = 1 << 6
31
32
32
33
33
34
THIS_SCRIPT_PATH = Path (__file__ )
34
35
RELATIVE_SCRIPT_PATH = THIS_SCRIPT_PATH .relative_to (THIS_SCRIPT_PATH .parent .parent )
35
36
36
37
REDIRECTION_DELAY = 6 # in seconds. Note: at least 6s for accessibility
38
+ REDIRECTION_TITLE = "xkbcommon: Page Redirection"
37
39
38
40
# NOTE: The redirection works with the HTML tag: <meta http-equiv="refresh">.
39
41
# See: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta#http-equiv
@@ -50,7 +52,7 @@ class ExitCode(IntFlag):
50
52
<meta http-equiv="refresh" content="${delay}; url=${canonical}">
51
53
<link href="doxygen.css" rel="stylesheet" type="text/css">
52
54
<link href="doxygen-extra.css" rel="stylesheet" type="text/css">
53
- <title>xkbcommon: Page Redirection </title>
55
+ <title>${title} </title>
54
56
</head>
55
57
<body>
56
58
<div id="top">
@@ -87,6 +89,14 @@ def parse_page_update(update: str) -> Update:
87
89
return updateʹ
88
90
89
91
92
+ def is_page_redirection (path : Path ):
93
+ with path .open ("rt" , encoding = "utf-8" ) as fd :
94
+ for line in fd :
95
+ if REDIRECTION_TITLE in line :
96
+ return True
97
+ return False
98
+
99
+
90
100
def update_registry (registry_path : Path , doc_dir : Path , updates : Sequence [str ]):
91
101
"""
92
102
Update the URL registry by:
@@ -95,21 +105,28 @@ def update_registry(registry_path: Path, doc_dir: Path, updates: Sequence[str]):
95
105
"""
96
106
# Parse updates
97
107
updates_ = dict (map (parse_page_update , updates ))
108
+ # Update
109
+ invalid_updates = set (updates_ )
98
110
# Load previous registry
99
111
with registry_path .open ("rt" , encoding = "utf-8" ) as fd :
100
- registry = yaml .safe_load (fd ) or {}
112
+ registry : dict [ str , list [ str ]] = yaml .safe_load (fd ) or {}
101
113
# Expected updates
102
114
missing_updates = set (file for file in registry if not (doc_dir / file ).is_file ())
103
- # Update
104
- invalid_updates = set (updates_ )
115
+ # Ensure each page is unique
116
+ for d , rs in registry .items ():
117
+ if clashes := frozenset (rs ).intersection (registry ):
118
+ print (
119
+ f"[ERROR] The following redirections of “{ d } ”" ,
120
+ f"clash with canonical directions: { clashes } " ,
121
+ )
122
+ exit (ExitCode .NON_UNIQUE_DIRECTIONS )
105
123
redirections = frozenset (chain (* registry .values ()))
106
124
for file in glob .iglob ("**/*.html" , root_dir = doc_dir , recursive = True ):
107
125
# Skip redirection pages
108
126
if file in redirections :
109
127
continue
110
128
# Get previous entry and potential update
111
- old = updates_ .get (file )
112
- if old :
129
+ if old := updates_ .get (file ):
113
130
# Update old entry
114
131
invalid_updates .remove (file )
115
132
entry = registry .get (old )
@@ -137,8 +154,21 @@ def update_registry(registry_path: Path, doc_dir: Path, updates: Sequence[str]):
137
154
exit_code |= ExitCode .INVALID_UPDATES
138
155
if missing_updates :
139
156
for old in missing_updates :
140
- print (f"[ERROR] “{ old } ” not found and has no update." )
141
- exit_code |= ExitCode .MISSING_UPDATES
157
+ # Handle older Doxygen versions
158
+ old_redirections = registry [old ]
159
+ for r in old_redirections :
160
+ path = doc_dir / r
161
+ if path .is_file () and not is_page_redirection (path ):
162
+ print (
163
+ "[WARNING] Handling old Doxygen version:" ,
164
+ f"use “{ r } ” instead of “{ old } ” for the canonical direction" ,
165
+ )
166
+ missing_updates .remove (old )
167
+ break
168
+ else :
169
+ print (f"[ERROR] “{ old } ” not found and has no update." )
170
+ if missing_updates :
171
+ exit_code |= ExitCode .MISSING_UPDATES
142
172
if exit_code :
143
173
print ("[ERROR] Processing interrupted: please fix the errors above." )
144
174
exit (exit_code .value )
@@ -159,22 +189,36 @@ def generate_redirections(registry_path: Path, doc_dir: Path):
159
189
cool = True
160
190
# Load registry
161
191
with registry_path .open ("rt" , encoding = "utf-8" ) as fd :
162
- registry = yaml .safe_load (fd ) or {}
192
+ registry : dict [ str , list [ str ]] = yaml .safe_load (fd ) or {}
163
193
for canonical , aliases in registry .items ():
164
194
# Check canonical path is up-to-date
165
195
if not (doc_dir / canonical ).is_file ():
166
- cool = False
167
- print (
168
- f"ERROR: missing canonical documentation page “{ canonical } ”. "
169
- f"Please update “{ registry_path } ” using { RELATIVE_SCRIPT_PATH } ”."
170
- )
196
+ # Handle older Doxygen versions
197
+ for r in aliases :
198
+ path = doc_dir / r
199
+ if path .is_file () and not is_page_redirection (path ):
200
+ print (
201
+ "[WARNING] Handling old Doxygen version:" ,
202
+ f"use “{ r } ” instead of “{ canonical } ” for the canonical direction" ,
203
+ )
204
+ canonical = r
205
+ aliases .remove (r )
206
+ break
207
+ else :
208
+ cool = False
209
+ print (
210
+ f"ERROR: missing canonical documentation page “{ canonical } ”. "
211
+ f"Please update “{ registry_path } ” using { RELATIVE_SCRIPT_PATH } ”."
212
+ )
171
213
# Add a redirection page
172
214
for alias in aliases :
173
215
path = doc_dir / alias
174
216
with path .open ("wt" , encoding = "utf-8" ) as fd :
175
217
fd .write (
176
218
REDIRECTION_PAGE_TEMPLATE .substitute (
177
- canonical = canonical , delay = REDIRECTION_DELAY
219
+ canonical = canonical ,
220
+ delay = REDIRECTION_DELAY ,
221
+ title = REDIRECTION_TITLE ,
178
222
)
179
223
)
180
224
if not cool :
0 commit comments