From 86bb66f394c997bdd3c116414152c0c07e901af3 Mon Sep 17 00:00:00 2001 From: Shumail Mohyuddin Date: Tue, 25 Jul 2023 12:42:58 +0200 Subject: [PATCH] fix(config): throw error if multiple project configs are found throw error if multiple project configs are found across multiple files in a dir (e.g. in garden.yml and project.garden.yml) --- core/src/config/base.ts | 20 ++++++++++++++++--- .../garden.yml | 13 ++++++++++++ .../project.garden.yml | 13 ++++++++++++ core/test/unit/src/config/base.ts | 11 ++++++++-- 4 files changed, 52 insertions(+), 5 deletions(-) create mode 100644 core/test/data/test-project-multiple-project-configs/garden.yml create mode 100644 core/test/data/test-project-multiple-project-configs/project.garden.yml diff --git a/core/src/config/base.ts b/core/src/config/base.ts index c893fb6ab2..6da09afbe7 100644 --- a/core/src/config/base.ts +++ b/core/src/config/base.ts @@ -457,26 +457,40 @@ export async function findProjectConfig({ }): Promise { let sepCount = path.split(sep).length - 1 + let allProjectSpecs: GardenResource[] = [] + for (let i = 0; i < sepCount; i++) { const configFiles = (await listDirectory(path, { recursive: false })).filter(isConfigFilename) for (const configFile of configFiles) { const resources = await loadConfigResources(log, path, join(path, configFile), allowInvalid) - const projectSpecs = resources.filter((s) => s.kind === "Project") + let projectSpecs = resources.filter((s) => s.kind === "Project") if (projectSpecs.length > 1 && !allowInvalid) { throw new ConfigurationError({ - message: `Multiple project declarations found in ${path}`, + message: `Multiple project declarations found in ${path}/${configFile}`, detail: { projectSpecs, }, }) } else if (projectSpecs.length > 0) { - return projectSpecs[0] + allProjectSpecs = allProjectSpecs.concat(projectSpecs) } } + if (allProjectSpecs.length > 1 && !allowInvalid) { + const configPaths = allProjectSpecs.map((i) => `- ${(i as ProjectConfig).configPath}`) + throw new ConfigurationError({ + message: `Multiple project declarations found at paths:\n${configPaths.join("\n")}`, + detail: { + allProjectSpecs, + }, + }) + } else if (allProjectSpecs.length === 1) { + return allProjectSpecs[0] + } + if (!scan) { break } diff --git a/core/test/data/test-project-multiple-project-configs/garden.yml b/core/test/data/test-project-multiple-project-configs/garden.yml new file mode 100644 index 0000000000..a22fee4e67 --- /dev/null +++ b/core/test/data/test-project-multiple-project-configs/garden.yml @@ -0,0 +1,13 @@ +apiVersion: garden.io/v1 +kind: Project +name: another-test-project +environments: + - name: local + - name: other +providers: + - name: test-plugin + environments: [local] + - name: test-plugin-b + environments: [local] +variables: + some: variable diff --git a/core/test/data/test-project-multiple-project-configs/project.garden.yml b/core/test/data/test-project-multiple-project-configs/project.garden.yml new file mode 100644 index 0000000000..e91654cb24 --- /dev/null +++ b/core/test/data/test-project-multiple-project-configs/project.garden.yml @@ -0,0 +1,13 @@ +apiVersion: garden.io/v1 +kind: Project +name: test-project +environments: + - name: local + - name: other +providers: + - name: test-plugin + environments: [local] + - name: test-plugin-b + environments: [local] +variables: + some: variable diff --git a/core/test/unit/src/config/base.ts b/core/test/unit/src/config/base.ts index 630d9964dc..ba29c9402a 100644 --- a/core/test/unit/src/config/base.ts +++ b/core/test/unit/src/config/base.ts @@ -32,6 +32,7 @@ const projectPathMultipleModules = getDataDir("test-projects", "multiple-module- const modulePathAMultiple = resolve(projectPathMultipleModules, "module-a") const projectPathDuplicateProjects = getDataDir("test-project-duplicate-project-config") +const projectPathMultipleProjects = getDataDir("test-project-multiple-project-configs") const logger = getRootLogger() const log = logger.createLog() @@ -580,9 +581,15 @@ describe("findProjectConfig", async () => { expect(project && project.path).to.eq(customConfigPath) }) - it("should throw an error if multiple projects are found", async () => { + it("should throw an error if multiple projects are found in same config file", async () => { await expectError(async () => await findProjectConfig({ log, path: projectPathDuplicateProjects }), { - contains: "Multiple project declarations found", + contains: "Multiple project declarations found in", + }) + }) + + it("should throw an error if multiple projects are found in multiple config files", async () => { + await expectError(async () => await findProjectConfig({ log, path: projectPathMultipleProjects }), { + contains: "Multiple project declarations found at paths", }) }) })