Duplicate Code Opportunity
Summary
- Pattern: The
docker compose down -v -t 1 invocation block (5 lines of execa options) is duplicated between the normal container stop path and the startup-retry teardown path
- Locations:
src/container-cleanup.ts lines 187–193, src/container-lifecycle.ts lines 221–228
- Impact: If the compose-down invocation needs to change (e.g. different timeout, additional flags, env override), both sites must be updated consistently; a mismatch could leave orphaned containers or volumes
Evidence
src/container-cleanup.ts lines 187–193 (the primary stop path):
await execa('docker', ['compose', 'down', '-v', '-t', '1'], {
cwd: workDir,
stdout: process.stderr,
stderr: 'inherit',
env: getLocalDockerEnv(),
});
src/container-lifecycle.ts lines 221–228 (the retry-cleanup path):
await execa('docker', ['compose', 'down', '-v', '-t', '1'], {
cwd: workDir,
stdout: process.stderr,
stderr: 'inherit',
env: getLocalDockerEnv(),
reject: false,
});
Both sites compose identical arguments and options (the reject: false difference is intentional for best-effort cleanup before retry, but the core invocation pattern is the same).
Suggested Refactoring
Extract a shared helper runComposeDown(workDir, opts?) in src/container-cleanup.ts or a new src/compose-utils.ts:
export async function runComposeDown(
workDir: string,
opts: { reject?: boolean } = {},
): Promise<void> {
await execa('docker', ['compose', 'down', '-v', '-t', '1'], {
cwd: workDir,
stdout: process.stderr,
stderr: 'inherit',
env: getLocalDockerEnv(),
reject: opts.reject ?? true,
});
}
container-cleanup.ts and container-lifecycle.ts then call runComposeDown(workDir) and runComposeDown(workDir, { reject: false }) respectively.
Affected Files
src/container-cleanup.ts — lines 187–193
src/container-lifecycle.ts — lines 221–228
Effort Estimate
Low
Detected by Duplicate Code Detector workflow. Run date: 2026-05-21
Generated by Duplicate Code Detector · ● 10.6M · ◷
Duplicate Code Opportunity
Summary
docker compose down -v -t 1invocation block (5 lines of execa options) is duplicated between the normal container stop path and the startup-retry teardown pathsrc/container-cleanup.tslines 187–193,src/container-lifecycle.tslines 221–228Evidence
src/container-cleanup.tslines 187–193 (the primary stop path):src/container-lifecycle.tslines 221–228 (the retry-cleanup path):Both sites compose identical arguments and options (the
reject: falsedifference is intentional for best-effort cleanup before retry, but the core invocation pattern is the same).Suggested Refactoring
Extract a shared helper
runComposeDown(workDir, opts?)insrc/container-cleanup.tsor a newsrc/compose-utils.ts:container-cleanup.tsandcontainer-lifecycle.tsthen callrunComposeDown(workDir)andrunComposeDown(workDir, { reject: false })respectively.Affected Files
src/container-cleanup.ts— lines 187–193src/container-lifecycle.ts— lines 221–228Effort Estimate
Low
Detected by Duplicate Code Detector workflow. Run date: 2026-05-21