diff --git a/garden-service/src/actions.ts b/garden-service/src/actions.ts index 657f2c32d5..090972c68b 100644 --- a/garden-service/src/actions.ts +++ b/garden-service/src/actions.ts @@ -72,7 +72,7 @@ import { mapValues, values, keyBy, omit } from "lodash" import { Omit } from "./util/util" import { RuntimeContext } from "./types/service" import { processServices, ProcessResults } from "./process" -import { getTasksForModule } from "./tasks/helpers" +import { getDependantTasksForModule } from "./tasks/helpers" import { LogEntry } from "./logger/log-entry" import { createPluginContext } from "./plugin-context" import { CleanupEnvironmentParams } from "./types/plugin/params" @@ -364,7 +364,7 @@ export class ActionHelper implements TypeGuard { garden: this.garden, log, watch: false, - handler: async (module) => getTasksForModule({ + handler: async (module) => getDependantTasksForModule({ garden: this.garden, log, module, diff --git a/garden-service/src/commands/deploy.ts b/garden-service/src/commands/deploy.ts index bd841d1316..bd7e507e89 100644 --- a/garden-service/src/commands/deploy.ts +++ b/garden-service/src/commands/deploy.ts @@ -18,7 +18,7 @@ import { StringsParameter, } from "./base" import { hotReloadAndLog, validateHotReloadOpt } from "./helpers" -import { getTasksForModule, getHotReloadModuleNames } from "../tasks/helpers" +import { getDependantTasksForModule, getHotReloadModuleNames } from "../tasks/helpers" import { TaskResults } from "../task-graph" import { processServices } from "../process" import { logHeader } from "../logger/util" @@ -108,7 +108,7 @@ export class DeployCommand extends Command { logFooter, services, watch, - handler: async (module) => getTasksForModule({ + handler: async (module) => getDependantTasksForModule({ garden, log, module, @@ -121,7 +121,7 @@ export class DeployCommand extends Command { if (hotReloadModuleNames.has(module.name)) { await hotReloadAndLog(garden, log, module) } - return getTasksForModule({ + return getDependantTasksForModule({ garden, log, module, hotReloadServiceNames, force: true, forceBuild: opts["force-build"], fromWatch: true, includeDependants: true, }) diff --git a/garden-service/src/commands/dev.ts b/garden-service/src/commands/dev.ts index 5f9217d32a..b876edd813 100644 --- a/garden-service/src/commands/dev.ts +++ b/garden-service/src/commands/dev.ts @@ -17,7 +17,7 @@ import { join } from "path" import { BaseTask } from "../tasks/base" import { hotReloadAndLog, validateHotReloadOpt } from "./helpers" -import { getTasksForModule, getHotReloadModuleNames } from "../tasks/helpers" +import { getDependantTasksForModule, getHotReloadModuleNames } from "../tasks/helpers" import { Command, CommandResult, @@ -110,7 +110,7 @@ export class DevCommand extends Command { const testTasks: BaseTask[] = flatten(await Bluebird.map( testModules, m => getTestTasks({ garden, log, module: m }))) - return testTasks.concat(await getTasksForModule({ + return testTasks.concat(await getDependantTasksForModule({ garden, log, module, diff --git a/garden-service/src/tasks/helpers.ts b/garden-service/src/tasks/helpers.ts index d7a66c84df..6ff4dab82e 100644 --- a/garden-service/src/tasks/helpers.ts +++ b/garden-service/src/tasks/helpers.ts @@ -9,15 +9,13 @@ import { flatten, intersection } from "lodash" import { DeployTask } from "./deploy" import { BuildTask } from "./build" -import { TaskTask } from "./task" import { Garden } from "../garden" import { Module } from "../types/module" import { Service } from "../types/service" -import { Task } from "../types/task" import { DependencyGraphNode } from "../dependency-graph" import { LogEntry } from "../logger/log-entry" -export async function getTasksForModule( +export async function getDependantTasksForModule( { garden, log, module, hotReloadServiceNames, force = false, forceBuild = false, fromWatch = false, includeDependants = false }: { @@ -29,12 +27,10 @@ export async function getTasksForModule( let buildTasks: BuildTask[] = [] let dependantBuildModules: Module[] = [] let services: Service[] = [] - let tasks: Task[] = [] if (!includeDependants) { buildTasks.push(new BuildTask({ garden, log, module, force: true, fromWatch, hotReloadServiceNames })) services = module.services - tasks = module.tasks } else { const hotReloadModuleNames = await getHotReloadModuleNames(garden, hotReloadServiceNames) const dg = await garden.getDependencyGraph() @@ -49,13 +45,12 @@ export async function getTasksForModule( dependantBuildModules = serviceDeps.build services = serviceDeps.service - tasks = serviceDeps.task } else { const dependants = await dg.getDependantsForModule(module, dependantFilterFn) + buildTasks.push(new BuildTask({ garden, log, module, force: true, fromWatch, hotReloadServiceNames })) dependantBuildModules = dependants.build services = module.services.concat(dependants.service) - tasks = module.tasks.concat(dependants.task) } } @@ -65,11 +60,8 @@ export async function getTasksForModule( const deployTasks = services .map(service => new DeployTask({ garden, log, service, force, forceBuild, fromWatch, hotReloadServiceNames })) - const taskTasks = tasks - .map(task => new TaskTask({ garden, log, task, force, forceBuild })) - - const outputTasks = [...buildTasks, ...deployTasks, ...taskTasks] - log.silly(`getTasksForModule called for module ${module.name}, returning the following tasks:`) + const outputTasks = [...buildTasks, ...deployTasks] + log.silly(`getDependantTasksForModule called for module ${module.name}, returning the following tasks:`) log.silly(` ${outputTasks.map(t => t.getBaseKey()).join(", ")}`) return outputTasks diff --git a/garden-service/test/src/commands/deploy.ts b/garden-service/test/src/commands/deploy.ts index 919f2fed29..24cd63c316 100644 --- a/garden-service/test/src/commands/deploy.ts +++ b/garden-service/test/src/commands/deploy.ts @@ -96,7 +96,7 @@ describe("DeployCommand", () => { const log = garden.log const command = new DeployCommand() - const { result } = await command.action({ + const { result, errors } = await command.action({ garden, log, args: { @@ -110,6 +110,10 @@ describe("DeployCommand", () => { }, }) + if (errors) { + throw errors[0] + } + expect(taskResultOutputs(result!)).to.eql({ "build.module-a": { fresh: true, buildLog: "A" }, "build.module-b": { fresh: true, buildLog: "B" }, @@ -131,7 +135,7 @@ describe("DeployCommand", () => { const log = garden.log const command = new DeployCommand() - const { result } = await command.action({ + const { result, errors } = await command.action({ garden, log, args: { @@ -145,6 +149,10 @@ describe("DeployCommand", () => { }, }) + if (errors) { + throw errors[0] + } + expect(taskResultOutputs(result!)).to.eql({ "build.module-a": { fresh: true, buildLog: "A" }, "build.module-b": { fresh: true, buildLog: "B" }, diff --git a/garden-service/test/src/tasks/helpers.ts b/garden-service/test/src/tasks/helpers.ts index aff2da525e..4749bc283f 100644 --- a/garden-service/test/src/tasks/helpers.ts +++ b/garden-service/test/src/tasks/helpers.ts @@ -4,14 +4,14 @@ import { flatten, uniq } from "lodash" import { resolve } from "path" import { Garden } from "../../../src/garden" import { makeTestGarden, dataDir } from "../../helpers" -import { getTasksForModule } from "../../../src/tasks/helpers" +import { getDependantTasksForModule } from "../../../src/tasks/helpers" import { BaseTask } from "../../../src/tasks/base" import { LogEntry } from "../../../src/logger/log-entry" -async function sortedBaseKeysWithDependencies(tasks: BaseTask[]): Promise { +async function sortedBaseKeysdependencyTasks(tasks: BaseTask[]): Promise { const dependencies = await Bluebird.map(tasks, async (t) => t.getDependencies(), { concurrency: 1 }) - const tasksWithDependencies = flatten([tasks].concat(dependencies)) - return sortedBaseKeys(tasksWithDependencies) + const tasksdependencyTasks = flatten([tasks].concat(dependencies)) + return sortedBaseKeys(tasksdependencyTasks) } function sortedBaseKeys(tasks: BaseTask[]): string[] { @@ -31,13 +31,13 @@ describe("TaskHelpers", () => { * Note: Since we also test with dependencies included in the task lists generated , these tests also check the * getDependencies methods of the task classes in question. */ - describe("getTasksForModule", () => { + describe("getDependantTasksForModule", () => { it("returns the correct set of tasks for the changed module", async () => { const module = await garden.getModule("good-morning") await garden.getDependencyGraph() - const tasks = await getTasksForModule({ + const tasks = await getDependantTasksForModule({ garden, log, module, hotReloadServiceNames: [], force: true, forceBuild: true, fromWatch: false, includeDependants: false, }) @@ -45,10 +45,9 @@ describe("TaskHelpers", () => { expect(sortedBaseKeys(tasks)).to.eql([ "build.good-morning", "deploy.good-morning", - "task.good-morning-task", ]) - expect(await sortedBaseKeysWithDependencies(tasks)).to.eql([ + expect(await sortedBaseKeysdependencyTasks(tasks)).to.eql([ "build.build-dependency", "build.good-morning", "deploy.good-morning", @@ -61,130 +60,95 @@ describe("TaskHelpers", () => { const expectedBaseKeysByChangedModule = [ { moduleName: "build-dependency", - withoutDependencies: [ + expected: [ "build.build-dependency", "deploy.build-dependency", "build.good-morning", "deploy.good-morning", - "task.good-morning-task", "build.build-dependant", "deploy.build-dependant", "deploy.service-dependant", - "task.dependant-task", - "deploy.service-dependant2", - "task.dependant-task2", - ].sort(), - withDependencies: [ - "build.build-dependency", + ], + dependencyTasks: [ "push.build-dependency", - "deploy.build-dependency", - - "build.good-morning", "push.good-morning", - "deploy.good-morning", - "task.good-morning-task", - - "build.build-dependant", "push.build-dependant", - "deploy.build-dependant", - - "build.service-dependant", "push.service-dependant", - "deploy.service-dependant", - "task.dependant-task", - - "build.service-dependant2", "push.service-dependant2", - "deploy.service-dependant2", - "task.dependant-task2", - ].sort(), + + "task.good-morning-task", + ], }, { moduleName: "good-morning", - withoutDependencies: [ + expected: [ "build.good-morning", "deploy.good-morning", - "task.good-morning-task", "build.build-dependant", "deploy.build-dependant", "deploy.service-dependant", - "task.dependant-task", - "deploy.service-dependant2", - "task.dependant-task2", - ].sort(), - withDependencies: [ + ], + dependencyTasks: [ "build.build-dependency", - "build.good-morning", "push.good-morning", - "deploy.good-morning", - "task.good-morning-task", - - "build.build-dependant", "push.build-dependant", - "deploy.build-dependant", - - "build.service-dependant", "push.service-dependant", - "deploy.service-dependant", - "task.dependant-task", - - "build.service-dependant2", "push.service-dependant2", - "deploy.service-dependant2", - "task.dependant-task2", - ].sort(), + + "task.good-morning-task", + ], }, { moduleName: "good-evening", - withoutDependencies: ["build.good-evening", "deploy.good-evening"], - withDependencies: ["build.good-evening", "push.good-evening", "deploy.good-evening"].sort(), + expected: [ + "build.good-evening", + "deploy.good-evening", + ], + dependencyTasks: [ + "push.good-evening", + ], }, { moduleName: "build-dependant", - withoutDependencies: ["build.build-dependant", "deploy.build-dependant"], - withDependencies: [ - "build.good-morning", - + expected: [ "build.build-dependant", - "push.build-dependant", "deploy.build-dependant", - ].sort(), + ], + dependencyTasks: [ + "build.good-morning", + "push.build-dependant", + ], }, { moduleName: "service-dependant", - withoutDependencies: [ + expected: [ "build.service-dependant", "deploy.service-dependant", - "task.dependant-task", ], - withDependencies: [ + dependencyTasks: [ "deploy.good-morning", - - "build.service-dependant", "push.service-dependant", - "deploy.service-dependant", - "task.dependant-task", - ].sort(), + ], }, ] - for (const { moduleName, withoutDependencies, withDependencies } of expectedBaseKeysByChangedModule) { + for (const { moduleName, expected, dependencyTasks } of expectedBaseKeysByChangedModule) { it(`returns the correct set of tasks for ${moduleName} and its dependants`, async () => { const module = await garden.getModule(moduleName) - const tasks = await getTasksForModule({ + const tasks = await getDependantTasksForModule({ garden, log, module, hotReloadServiceNames: [], force: true, forceBuild: true, fromWatch: true, includeDependants: true, }) - expect(sortedBaseKeys(tasks)).to.eql(withoutDependencies) - expect(await sortedBaseKeysWithDependencies(tasks)).to.eql(withDependencies) + expect(sortedBaseKeys(tasks)).to.eql(expected.sort()) + expect(await sortedBaseKeysdependencyTasks(tasks)).to.eql(expected.concat(dependencyTasks).sort()) }) } @@ -195,65 +159,66 @@ describe("TaskHelpers", () => { const expectedBaseKeysByChangedModule = [ { moduleName: "build-dependency", - withoutDependencies: ["build.build-dependency", "deploy.build-dependency"], - withDependencies: ["build.build-dependency", "push.build-dependency", "deploy.build-dependency"].sort(), + expected: [ + "build.build-dependency", + "deploy.build-dependency", + ], + dependencyTasks: [ + "push.build-dependency", + ], }, { moduleName: "good-morning", - withoutDependencies: [ + expected: [ "deploy.service-dependant", - "task.dependant-task", - "deploy.service-dependant2", - "task.dependant-task2", - ].sort(), - withDependencies: [ - "build.service-dependant", + ], + dependencyTasks: [ "push.service-dependant", - "deploy.service-dependant", - "task.dependant-task", - - "build.service-dependant2", "push.service-dependant2", - "deploy.service-dependant2", - "task.dependant-task2", - ].sort(), + ], }, { moduleName: "good-evening", - withoutDependencies: ["build.good-evening", "deploy.good-evening"], - withDependencies: ["build.good-evening", "push.good-evening", "deploy.good-evening"].sort(), + expected: [ + "build.good-evening", + "deploy.good-evening", + ], + dependencyTasks: [ + "push.good-evening", + ], }, { moduleName: "build-dependant", - withoutDependencies: ["build.build-dependant", "deploy.build-dependant"], - withDependencies: [ + expected: [ "build.build-dependant", - "push.build-dependant", "deploy.build-dependant", - ].sort(), + ], + dependencyTasks: [ + "push.build-dependant", + ], }, { moduleName: "service-dependant", - withoutDependencies: ["build.service-dependant", "deploy.service-dependant", "task.dependant-task"], - withDependencies: [ + expected: [ "build.service-dependant", - "push.service-dependant", "deploy.service-dependant", - "task.dependant-task", - ].sort(), + ], + dependencyTasks: [ + "push.service-dependant", + ], }, ] - for (const { moduleName, withoutDependencies, withDependencies } of expectedBaseKeysByChangedModule) { + for (const { moduleName, expected, dependencyTasks } of expectedBaseKeysByChangedModule) { it(`returns the correct set of tasks for ${moduleName} and its dependants`, async () => { const module = await garden.getModule(moduleName) - const tasks = await getTasksForModule({ + const tasks = await getDependantTasksForModule({ garden, log, module, hotReloadServiceNames: ["good-morning"], force: true, forceBuild: true, fromWatch: true, includeDependants: true, }) - expect(sortedBaseKeys(tasks)).to.eql(withoutDependencies) - expect(await sortedBaseKeysWithDependencies(tasks)).to.eql(withDependencies) + expect(sortedBaseKeys(tasks)).to.eql(expected.sort()) + expect(await sortedBaseKeysdependencyTasks(tasks)).to.eql(expected.concat(dependencyTasks).sort()) }) }