(def, exec)
| 191 | |
| 192 | /** Probe a single tool. Returns { key, found, version }. */ |
| 193 | export async function probeOne(def, exec) { |
| 194 | const run = exec || defaultExec; |
| 195 | let r; |
| 196 | try { |
| 197 | r = await run(def.cmd, def.args); |
| 198 | } catch (e) { |
| 199 | r = { error: e, stdout: "", stderr: "" }; |
| 200 | } |
| 201 | const text = ((r.stdout || "") + "\n" + (r.stderr || "")).trim(); |
| 202 | // ENOENT means the binary isn't on PATH at all. |
| 203 | if (r.error && r.error.code === "ENOENT") return { key: def.key, found: false, version: null }; |
| 204 | if (r.error && !text) return { key: def.key, found: false, version: null }; |
| 205 | const version = parseToolVersion(def.key, text); |
| 206 | if (r.error) { |
| 207 | // Non-zero exit. Genuine `--version` calls exit 0, so only trust this if a |
| 208 | // real version number came back. This rejects the macOS `java` stub, which |
| 209 | // exits 1 with "Unable to locate a Java Runtime" when no JDK is installed. |
| 210 | if (!(version && /\d/.test(version))) return { key: def.key, found: false, version: null }; |
| 211 | } |
| 212 | return { key: def.key, found: true, version }; |
| 213 | } |
| 214 | |
| 215 | /** Probe every tool and build the readiness report. Impure (spawns processes). */ |
| 216 | export async function runDoctor(scan, opts = {}) { |
no test coverage detected