From 3913f55736bbc60f3aaf7bc448520e778163df5e Mon Sep 17 00:00:00 2001 From: Christof Marti Date: Thu, 30 May 2024 11:37:20 +0200 Subject: [PATCH] Fix support for project name attribute (#831) --- CHANGELOG.md | 3 ++ package.json | 2 +- src/spec-node/dockerCompose.ts | 14 ++++++++-- src/test/cli.up.test.ts | 28 ++++++++++++++++++- .../.devcontainer/devcontainer.json | 5 ++++ .../.devcontainer/docker-compose.yml | 11 ++++++++ .../.devcontainer/devcontainer.json | 5 ++++ .../.devcontainer/docker-compose.yml | 8 ++++++ 8 files changed, 72 insertions(+), 4 deletions(-) create mode 100644 src/test/configs/compose-with-name-and-custom-yaml/.devcontainer/devcontainer.json create mode 100644 src/test/configs/compose-with-name-and-custom-yaml/.devcontainer/docker-compose.yml create mode 100644 src/test/configs/compose-without-name/.devcontainer/devcontainer.json create mode 100644 src/test/configs/compose-without-name/.devcontainer/docker-compose.yml diff --git a/CHANGELOG.md b/CHANGELOG.md index 698af47a7..1bb3c8a13 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,9 @@ Notable changes. ## May 2024 +### [0.62.0] +- Fix support for project name attribute. (https://github.com/devcontainers/cli/issues/831) + ### [0.61.0] - Use --depth 1 to make dotfiles install process faster (https://github.com/devcontainers/cli/pull/830) - Enable --cache-to and --cache-from in devcontainer up (https://github.com/devcontainers/cli/pull/813) diff --git a/package.json b/package.json index d2e46ac7c..b92284d82 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@devcontainers/cli", "description": "Dev Containers CLI", - "version": "0.61.0", + "version": "0.62.0", "bin": { "devcontainer": "devcontainer.js" }, diff --git a/src/spec-node/dockerCompose.ts b/src/spec-node/dockerCompose.ts index 8c0a410c1..150e3aac6 100644 --- a/src/spec-node/dockerCompose.ts +++ b/src/spec-node/dockerCompose.ts @@ -653,8 +653,18 @@ export async function getProjectName(params: DockerCLIParameters | DockerResolve throw err; } } - if (composeConfig?.name) { - return toProjectName(composeConfig.name, newProjectName); + for (let i = composeFiles.length - 1; i >= 0; i--) { + try { + const fragment = yaml.load((await cliHost.readFile(composeFiles[i])).toString()) || {} as any; + if (fragment.name) { + return toProjectName(fragment.name, newProjectName); + } + } catch (error) { + // fallback when parsing fails due to custom yaml tags (e.g., !reset) + if (composeConfig?.name && composeConfig.name !== 'devcontainer') { + return toProjectName(composeConfig.name, newProjectName); + } + } } const configDir = workspace.configFolderPath; const workingDir = composeFiles[0] ? cliHost.path.dirname(composeFiles[0]) : cliHost.cwd; // From https://github.com/docker/compose/blob/79557e3d3ab67c3697641d9af91866d7e400cfeb/compose/config/config.py#L290 diff --git a/src/test/cli.up.test.ts b/src/test/cli.up.test.ts index cd678edeb..765541103 100644 --- a/src/test/cli.up.test.ts +++ b/src/test/cli.up.test.ts @@ -92,7 +92,7 @@ describe('Dev Containers CLI', function () { assert.equal(upResult!.outcome, 'success'); }); }); - describe('for docker-compose with image without features with custom project name', () => { + describe('for minimal docker-compose with custom project name', () => { let upResult: UpResult | null = null; const testFolder = `${__dirname}/configs/compose-with-name`; before(async () => { @@ -105,6 +105,32 @@ describe('Dev Containers CLI', function () { assert.equal(upResult!.composeProjectName, 'custom-project-name'); }); }); + describe('for minimal docker-compose with custom project name and custom yaml', () => { + let upResult: UpResult | null = null; + const testFolder = `${__dirname}/configs/compose-with-name-and-custom-yaml`; + before(async () => { + // build and start the container + upResult = await devContainerUp(cli, testFolder, { 'logLevel': 'trace', extraArgs: `--docker-compose-path trigger-compose-v2` }); + }); + after(async () => await devContainerDown({ composeProjectName: upResult?.composeProjectName })); + it('should succeed', () => { + assert.equal(upResult!.outcome, 'success'); + assert.equal(upResult!.composeProjectName, 'custom-project-name-custom-yaml'); + }); + }); + describe('for minimal docker-compose without custom project name', () => { + let upResult: UpResult | null = null; + const testFolder = `${__dirname}/configs/compose-without-name`; + before(async () => { + // build and start the container + upResult = await devContainerUp(cli, testFolder, { 'logLevel': 'trace', extraArgs: `--docker-compose-path trigger-compose-v2` }); + }); + after(async () => await devContainerDown({ composeProjectName: upResult?.composeProjectName })); + it('should succeed', () => { + assert.equal(upResult!.outcome, 'success'); + assert.equal(upResult!.composeProjectName, 'compose-without-name_devcontainer'); + }); + }); // Additional tests to verify the handling of persisted files describe('for docker-compose with Dockerfile with features', () => { diff --git a/src/test/configs/compose-with-name-and-custom-yaml/.devcontainer/devcontainer.json b/src/test/configs/compose-with-name-and-custom-yaml/.devcontainer/devcontainer.json new file mode 100644 index 000000000..7b42997d3 --- /dev/null +++ b/src/test/configs/compose-with-name-and-custom-yaml/.devcontainer/devcontainer.json @@ -0,0 +1,5 @@ +{ + "dockerComposeFile": "docker-compose.yml", + "service": "app", + "workspaceFolder": "/workspace" +} \ No newline at end of file diff --git a/src/test/configs/compose-with-name-and-custom-yaml/.devcontainer/docker-compose.yml b/src/test/configs/compose-with-name-and-custom-yaml/.devcontainer/docker-compose.yml new file mode 100644 index 000000000..f1eb307cd --- /dev/null +++ b/src/test/configs/compose-with-name-and-custom-yaml/.devcontainer/docker-compose.yml @@ -0,0 +1,11 @@ +version: '3.8' + +name: custom-project-name-custom-yaml + +services: + app: + image: ubuntu:latest + ports: !reset [] + volumes: + - ..:/workspace:cached + command: sleep infinity diff --git a/src/test/configs/compose-without-name/.devcontainer/devcontainer.json b/src/test/configs/compose-without-name/.devcontainer/devcontainer.json new file mode 100644 index 000000000..7b42997d3 --- /dev/null +++ b/src/test/configs/compose-without-name/.devcontainer/devcontainer.json @@ -0,0 +1,5 @@ +{ + "dockerComposeFile": "docker-compose.yml", + "service": "app", + "workspaceFolder": "/workspace" +} \ No newline at end of file diff --git a/src/test/configs/compose-without-name/.devcontainer/docker-compose.yml b/src/test/configs/compose-without-name/.devcontainer/docker-compose.yml new file mode 100644 index 000000000..b2e568e5b --- /dev/null +++ b/src/test/configs/compose-without-name/.devcontainer/docker-compose.yml @@ -0,0 +1,8 @@ +version: '3.8' + +services: + app: + image: ubuntu:latest + volumes: + - ..:/workspace:cached + command: sleep infinity