| 243 | |
| 244 | |
| 245 | def software_versions(commands: dict[str, list[str]]) -> dict[str, str | None]: |
| 246 | versions: dict[str, str | None] = {} |
| 247 | for name, cmd in commands.items(): |
| 248 | if not command_path(cmd[0]): |
| 249 | versions[name] = None |
| 250 | continue |
| 251 | result = run_cmd(cmd, Path.cwd(), timeout=30) |
| 252 | detail = result.get("stdout_tail") or result.get("error") or "" |
| 253 | versions[name] = "\n".join(str(detail).splitlines()[:3]).strip() or None |
| 254 | return versions |
| 255 | |
| 256 | |
| 257 | def _iter_existing_paths(value: Any) -> list[Path]: |