Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

scripts: test_doc_build.py: better control its output

Now that asyncio is supported, allow userspace to adjust
verbosity level and direct the script output to a file.

Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
Signed-off-by: Jonathan Corbet <corbet@lwn.net>
Link: https://lore.kernel.org/r/76c3a64a87a7493ae607d5c7784b3b829affcaf0.1750571906.git.mchehab+huawei@kernel.org

authored by

Mauro Carvalho Chehab and committed by
Jonathan Corbet
fb1e8d12 7649db7d

+51 -27
+51 -27
scripts/test_doc_build.py
··· 2 2 # SPDX-License-Identifier: GPL-2.0 3 3 # Copyright(c) 2025: Mauro Carvalho Chehab <mchehab+huawei@kernel.org> 4 4 # 5 - # pylint: disable=R0903,R0913,R0914,R0917 5 + # pylint: disable=R0903,R0912,R0913,R0914,R0917,C0301 6 6 7 7 """ 8 8 Install minimal supported requirements for different Sphinx versions ··· 104 104 class AsyncCommands: 105 105 """Excecute command synchronously""" 106 106 107 - stdout = None 108 - stderr = None 109 - output = None 107 + def __init__(self, fp=None): 108 + 109 + self.stdout = None 110 + self.stderr = None 111 + self.output = None 112 + self.fp = fp 113 + 114 + def log(self, out, verbose, is_info=True): 115 + if verbose: 116 + if is_info: 117 + print(out.rstrip("\n")) 118 + else: 119 + print(out.rstrip("\n"), file=sys.stderr) 120 + 121 + if self.fp: 122 + self.fp.write(out.rstrip("\n") + "\n") 110 123 111 124 async def _read(self, stream, verbose, is_info): 112 125 """Ancillary routine to capture while displaying""" ··· 128 115 line = await stream.readline() 129 116 if line: 130 117 out = line.decode("utf-8", errors="backslashreplace") 131 - self.output += out 118 + self.log(out, verbose, is_info) 132 119 if is_info: 133 - if verbose: 134 - print(out.rstrip("\n")) 135 - 136 120 self.stdout += out 137 121 else: 138 - if verbose: 139 - print(out.rstrip("\n"), file=sys.stderr) 140 - 141 122 self.stderr += out 142 123 else: 143 124 break ··· 147 140 148 141 self.stdout = "" 149 142 self.stderr = "" 150 - self.output = "" 151 143 152 - if verbose: 153 - print("$ ", " ".join(cmd)) 144 + self.log("$ " + " ".join(cmd), verbose) 154 145 155 146 proc = await asyncio.create_subprocess_exec(cmd[0], 156 147 *cmd[1:], ··· 172 167 173 168 if capture_output: 174 169 if proc.returncode > 0: 175 - print("Error {proc.returncode}", file=sys.stderr) 170 + self.log(f"Error {proc.returncode}", verbose=True, is_info=False) 176 171 return "" 177 172 178 173 return self.output ··· 197 192 self.built_time = {} 198 193 self.first_run = True 199 194 200 - async def _handle_version(self, args, cur_ver, cur_requirements, python_bin): 195 + async def _handle_version(self, args, fp, 196 + cur_ver, cur_requirements, python_bin): 201 197 """Handle a single Sphinx version""" 202 198 203 - cmd = AsyncCommands() 199 + cmd = AsyncCommands(fp) 204 200 205 201 ver = ".".join(map(str, cur_ver)) 206 202 ··· 216 210 venv_dir = f"Sphinx_{ver}" 217 211 req_file = f"requirements_{ver}.txt" 218 212 219 - print(f"\nSphinx {ver} with {python_bin}") 213 + cmd.log(f"\nSphinx {ver} with {python_bin}", verbose=True) 220 214 221 215 # Create venv 222 - await cmd.run([python_bin, "-m", "venv", venv_dir], check=True) 216 + await cmd.run([python_bin, "-m", "venv", venv_dir], 217 + verbose=args.verbose, check=True) 223 218 pip = os.path.join(venv_dir, "bin/pip") 224 219 225 220 # Create install list ··· 230 223 231 224 reqs.append(f"Sphinx=={ver}") 232 225 233 - await cmd.run([pip, "install"] + reqs, check=True, verbose=True) 226 + await cmd.run([pip, "install"] + reqs, check=True, verbose=args.verbose) 234 227 235 228 # Freeze environment 236 229 result = await cmd.run([pip, "freeze"], verbose=False, check=True) ··· 255 248 await cmd.run(["make", "cleandocs"], env=env, check=True) 256 249 make = ["make"] + args.make_args + ["htmldocs"] 257 250 258 - print(f". {bin_dir}/activate") 259 - print(" ".join(make)) 260 - print("deactivate") 261 - await cmd.run(make, env=env, check=True) 251 + if args.verbose: 252 + print(f". {bin_dir}/activate") 253 + await cmd.run(make, env=env, check=True, verbose=True) 254 + if args.verbose: 255 + print("deactivate") 262 256 263 257 end_time = time.time() 264 258 elapsed_time = end_time - start_time ··· 272 264 273 265 self.built_time[ver] = f"{hours:02d}:{minutes:02d}:{seconds:02d}" 274 266 275 - print(f"Finished doc build for Sphinx {ver}. Elapsed time: {self.built_time[ver]}") 267 + cmd.log(f"Finished doc build for Sphinx {ver}. Elapsed time: {self.built_time[ver]}", verbose=True) 276 268 277 269 async def run(self, args): 278 270 """ 279 271 Navigate though multiple Sphinx versions, handling each of them 280 272 on a loop. 281 273 """ 274 + 275 + if args.log: 276 + fp = open(args.log, "w", encoding="utf-8") 277 + if not args.verbose: 278 + args.verbose = False 279 + else: 280 + fp = None 281 + if not args.verbose: 282 + args.verbose = True 282 283 283 284 cur_requirements = {} 284 285 python_bin = MINIMAL_PYTHON_VERSION ··· 307 290 if cur_ver > args.max_version: 308 291 break 309 292 310 - await self._handle_version(args, cur_ver, cur_requirements, 293 + await self._handle_version(args, fp, cur_ver, cur_requirements, 311 294 python_bin) 312 295 313 296 if args.make: ··· 316 299 for ver, elapsed_time in sorted(self.built_time.items()): 317 300 print(f"\tSphinx {ver} elapsed time: {elapsed_time}") 318 301 302 + if fp: 303 + fp.close() 319 304 320 305 def parse_version(ver_str): 321 306 """Convert a version string into a tuple.""" ··· 330 311 331 312 parser = argparse.ArgumentParser(description="Build docs for different sphinx_versions.") 332 313 333 - parser.add_argument('-v', '--version', help='Sphinx single version', 314 + parser.add_argument('-V', '--version', help='Sphinx single version', 334 315 type=parse_version) 335 316 parser.add_argument('--min-version', "--min", help='Sphinx minimal version', 336 317 type=parse_version) ··· 347 328 parser.add_argument('-i', '--wait-input', 348 329 help='Wait for an enter before going to the next version', 349 330 action='store_true') 331 + parser.add_argument('-v', '--verbose', 332 + help='Verbose all commands', 333 + action='store_true') 334 + parser.add_argument('-l', '--log', 335 + help='Log command output on a file') 350 336 351 337 args = parser.parse_args() 352 338