( workspaceFolder: string, timeoutMs = 10_000 )
| 507 | * The devcontainer CLI only returns container ID, so we query Docker directly. |
| 508 | */ |
| 509 | export async function getDevcontainerContainerName( |
| 510 | workspaceFolder: string, |
| 511 | timeoutMs = 10_000 |
| 512 | ): Promise<string | null> { |
| 513 | // The devcontainer CLI labels containers with the workspace folder path |
| 514 | const labelValue = workspaceFolder; |
| 515 | |
| 516 | return new Promise((resolve) => { |
| 517 | const proc = spawn( |
| 518 | "docker", |
| 519 | ["ps", "--format", "{{.Names}}", "--filter", `label=devcontainer.local_folder=${labelValue}`], |
| 520 | { |
| 521 | stdio: ["ignore", "pipe", "pipe"], |
| 522 | timeout: timeoutMs, |
| 523 | } |
| 524 | ); |
| 525 | |
| 526 | let stdout = ""; |
| 527 | proc.stdout?.on("data", (data: Buffer) => { |
| 528 | stdout += data.toString(); |
| 529 | }); |
| 530 | |
| 531 | proc.on("error", () => { |
| 532 | resolve(null); |
| 533 | }); |
| 534 | |
| 535 | proc.on("close", (code) => { |
| 536 | if (code === 0 && stdout.trim()) { |
| 537 | // Return first container name (there should only be one) |
| 538 | resolve(stdout.trim().split("\n")[0]); |
| 539 | } else { |
| 540 | resolve(null); |
| 541 | } |
| 542 | }); |
| 543 | }); |
| 544 | } |
| 545 | |
| 546 | export async function stopDevcontainer(workspacePath: string): Promise<DevcontainerStopResult> { |
| 547 | const labelValue = workspacePath; |
no test coverage detected