diff --git a/garden-service/src/cli/cli.ts b/garden-service/src/cli/cli.ts index 8f3269a3e2..8bcfa2301b 100644 --- a/garden-service/src/cli/cli.ts +++ b/garden-service/src/cli/cli.ts @@ -67,21 +67,33 @@ const OUTPUT_RENDERERS = { const GLOBAL_OPTIONS_GROUP_NAME = "Global options" const DEFAULT_CLI_LOGGER_TYPE = "fancy" -// For initializing garden without a project config -export const MOCK_CONFIG: ProjectConfig = { - path: process.cwd(), - apiVersion: DEFAULT_API_VERSION, - kind: "Project", - name: "mock-project", - defaultEnvironment: "local", - dotIgnoreFiles: defaultDotIgnoreFiles, - environments: defaultEnvironments, - providers: [ - { - name: "local-kubernetes", - }, - ], - variables: {}, +/** + * Dummy Garden class that doesn't scan for modules nor resolves providers. + * Used by commands that have noProject=true. That is, commands that need + * to run outside of valid Garden projects. + */ +class DummyGarden extends Garden { + async resolveProviders() { + return [] + } + async scanModules() {} +} + +export async function makeDummyGarden(root: string, gardenOpts: GardenOpts) { + const config: ProjectConfig = { + path: root, + apiVersion: DEFAULT_API_VERSION, + kind: "Project", + name: "no-project", + defaultEnvironment: "", + dotIgnoreFiles: defaultDotIgnoreFiles, + environments: defaultEnvironments, + providers: [], + variables: {}, + } + gardenOpts.config = config + + return DummyGarden.factory(root, gardenOpts) } // The help text for these commands is only displayed when calling `garden options`. @@ -285,9 +297,7 @@ export class GardenCli { environmentName: env, log, } - if (command.noProject) { - contextOpts.config = MOCK_CONFIG - } + let garden: Garden let result: any @@ -303,7 +313,11 @@ export class GardenCli { do { try { - garden = await Garden.factory(root, contextOpts) + if (command.noProject) { + garden = await makeDummyGarden(root, contextOpts) + } else { + garden = await Garden.factory(root, contextOpts) + } // Register log file writers. We need to do this after the Garden class is initialised because // the file writers depend on the project root. await this.initFileWriters(logger, garden.projectRoot, garden.gardenDirPath) diff --git a/garden-service/src/commands/migrate.ts b/garden-service/src/commands/migrate.ts index f54e69f394..fa0c910db1 100644 --- a/garden-service/src/commands/migrate.ts +++ b/garden-service/src/commands/migrate.ts @@ -142,7 +142,7 @@ export class MigrateCommand extends Command { await writeFile(path, out) } else { if (configPaths.length > 1) { - log.info(`# Updated config for garden.yml file at path ${path}`) + log.info(`# Updated config for garden.yml file at path ${path}:`) } log.info(out) } diff --git a/garden-service/test/unit/src/cli/cli.ts b/garden-service/test/unit/src/cli/cli.ts new file mode 100644 index 0000000000..63fe2cfee1 --- /dev/null +++ b/garden-service/test/unit/src/cli/cli.ts @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2018 Garden Technologies, Inc. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +import { expect } from "chai" +import { makeDummyGarden } from "../../../../src/cli/cli" +import { getDataDir } from "../../../helpers" + +describe("cli", () => { + describe("makeDummyGarden", () => { + it("should initialise and resolve config graph in a directory with no project", async () => { + const garden = await makeDummyGarden("./foobarbas", {}) + const dg = await garden.getConfigGraph(garden.log) + expect(garden).to.be.ok + expect(await dg.getModules()).to.not.throw + }) + it("should initialise and resolve config graph in a project with invalid config", async () => { + const root = getDataDir("test-project-invalid-config") + const garden = await makeDummyGarden(root, {}) + const dg = await garden.getConfigGraph(garden.log) + expect(garden).to.be.ok + expect(await dg.getModules()).to.not.throw + }) + it("should initialise and resolve config graph in a project with template strings", async () => { + const root = getDataDir("test-project-templated") + const garden = await makeDummyGarden(root, {}) + const dg = await garden.getConfigGraph(garden.log) + expect(garden).to.be.ok + expect(await dg.getModules()).to.not.throw + }) + }) +}) diff --git a/garden-service/test/unit/src/garden.ts b/garden-service/test/unit/src/garden.ts index 2a9c560a8d..345840f080 100644 --- a/garden-service/test/unit/src/garden.ts +++ b/garden-service/test/unit/src/garden.ts @@ -20,7 +20,6 @@ import { testGitUrl, } from "../../helpers" import { getNames, findByName, deepOmitUndefined } from "../../../src/util/util" -import { MOCK_CONFIG } from "../../../src/cli/cli" import { LinkedSource } from "../../../src/config-store" import { ModuleVersion } from "../../../src/vcs/vcs" import { getModuleCacheContext } from "../../../src/types/module" @@ -80,11 +79,6 @@ describe("Garden", () => { expect((actions).actionHandlers.prepareEnvironment["test-plugin-b"]).to.be.ok }) - it("should initialize with MOCK_CONFIG", async () => { - const garden = await Garden.factory("./", { config: MOCK_CONFIG }) - expect(garden).to.be.ok - }) - it("should initialize a project with config files with yaml and yml extensions", async () => { const garden = await makeTestGarden(getDataDir("test-project-yaml-file-extensions")) expect(garden).to.be.ok