Skip to content

Commit bcb3652

Browse files
committed
devcontainer up cwd and test
1 parent 98c3316 commit bcb3652

File tree

2 files changed

+52
-6
lines changed

2 files changed

+52
-6
lines changed

src/spec-node/devContainersSpecCLI.ts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ function provisionOptions(y: Argv) {
103103
'docker-compose-path': { type: 'string', description: 'Docker Compose CLI path.' },
104104
'container-data-folder': { type: 'string', description: 'Container data folder where user data inside the container will be stored.' },
105105
'container-system-data-folder': { type: 'string', description: 'Container system data folder where system data inside the container will be stored.' },
106-
'workspace-folder': { type: 'string', description: 'Workspace folder path. The devcontainer.json will be looked up relative to this path.' },
106+
'workspace-folder': { type: 'string', description: 'Workspace folder path. The devcontainer.json will be looked up relative to this path. If not provided, defaults to the current directory.' },
107107
'workspace-mount-consistency': { choices: ['consistent' as 'consistent', 'cached' as 'cached', 'delegated' as 'delegated'], default: 'cached' as 'cached', description: 'Workspace mount consistency.' },
108108
'gpu-availability': { choices: ['all' as 'all', 'detect' as 'detect', 'none' as 'none'], default: 'detect' as 'detect', description: 'Availability of GPUs in case the dev container requires any. `all` expects a GPU to be available.' },
109109
'mount-workspace-git-root': { type: 'boolean', default: true, description: 'Mount the workspace using its Git root.' },
@@ -148,11 +148,9 @@ function provisionOptions(y: Argv) {
148148
if (idLabels?.some(idLabel => !/.+=.+/.test(idLabel))) {
149149
throw new Error('Unmatched argument format: id-label must match <name>=<value>');
150150
}
151-
if (!(argv['workspace-folder'] || argv['id-label'])) {
152-
throw new Error('Missing required argument: workspace-folder or id-label');
153-
}
154-
if (!(argv['workspace-folder'] || argv['override-config'])) {
155-
throw new Error('Missing required argument: workspace-folder or override-config');
151+
// Default workspace-folder to current directory if not provided and no id-label or override-config
152+
if (!argv['workspace-folder'] && !argv['id-label'] && !argv['override-config']) {
153+
argv['workspace-folder'] = process.cwd();
156154
}
157155
const mounts = (argv.mount && (Array.isArray(argv.mount) ? argv.mount : [argv.mount])) as string[] | undefined;
158156
if (mounts?.some(mount => !mountRegex.test(mount))) {

src/test/cli.up.test.ts

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,4 +310,52 @@ describe('Dev Containers CLI', function () {
310310
await shellExec(`docker rm -f ${response.containerId}`);
311311
});
312312
});
313+
314+
describe('Command up with default workspace', () => {
315+
it('should create and start container using current directory config', async () => {
316+
const testFolder = `${__dirname}/configs/image`;
317+
const absoluteTmpPath = path.resolve(__dirname, 'tmp');
318+
const absoluteCli = `npx --prefix ${absoluteTmpPath} devcontainer`;
319+
const originalCwd = process.cwd();
320+
let containerId: string | null = null;
321+
try {
322+
process.chdir(testFolder);
323+
const res = await shellExec(`${absoluteCli} up`);
324+
const response = JSON.parse(res.stdout);
325+
containerId = response.containerId;
326+
assert.equal(response.outcome, 'success');
327+
assert.ok(containerId);
328+
} finally {
329+
process.chdir(originalCwd);
330+
if (containerId) {
331+
await shellExec(`docker rm -f ${containerId}`);
332+
}
333+
}
334+
});
335+
336+
it('should fail gracefully when no config in current directory', async () => {
337+
const tempDir = path.join(os.tmpdir(), 'devcontainer-up-test-' + Date.now());
338+
await shellExec(`mkdir -p ${tempDir}`);
339+
const absoluteTmpPath = path.resolve(__dirname, 'tmp');
340+
const absoluteCli = `npx --prefix ${absoluteTmpPath} devcontainer`;
341+
const originalCwd = process.cwd();
342+
try {
343+
process.chdir(tempDir);
344+
let success = false;
345+
try {
346+
await shellExec(`${absoluteCli} up`);
347+
success = true;
348+
} catch (error) {
349+
assert.equal(error.error.code, 1, 'Should fail with exit code 1');
350+
const res = JSON.parse(error.stdout);
351+
assert.equal(res.outcome, 'error');
352+
assert.match(res.message, /Dev container config .* not found/);
353+
}
354+
assert.equal(success, false, 'expect non-successful call');
355+
} finally {
356+
process.chdir(originalCwd);
357+
await shellExec(`rm -rf ${tempDir}`);
358+
}
359+
});
360+
});
313361
});

0 commit comments

Comments
 (0)