diff --git a/garden-service/src/commands/run/task.ts b/garden-service/src/commands/run/task.ts index a1c81a46a9..af81f74dd0 100644 --- a/garden-service/src/commands/run/task.ts +++ b/garden-service/src/commands/run/task.ts @@ -51,7 +51,7 @@ export class RunTaskCommand extends Command { async action( { garden, log, headerLog, footerLog, args, opts }: CommandParams, - ): Promise> { + ): Promise> { const graph = await garden.getConfigGraph() const task = await graph.getTask(args.task) @@ -62,7 +62,7 @@ export class RunTaskCommand extends Command { const taskTask = await TaskTask.factory({ garden, graph, task, log, force: true, forceBuild: opts["force-build"] }) const result = (await garden.processTasks([taskTask]))[taskTask.getKey()] - if (!result.error) { + if (result && !result.error) { log.info("") // TODO: The command will need to be updated to stream logs: see https://github.com/garden-io/garden/issues/630. // It's ok with the current providers but the shape might change in the future. diff --git a/garden-service/src/garden.ts b/garden-service/src/garden.ts index 3a2cb85b8f..3dac9074da 100644 --- a/garden-service/src/garden.ts +++ b/garden-service/src/garden.ts @@ -499,14 +499,14 @@ export class Garden { const failed = Object.values(taskResults).filter(r => r && r.error) if (failed.length) { - const messages = failed.map(r => `- ${r.name}: ${r.error!.message}`) + const messages = failed.map(r => `- ${r!.name}: ${r!.error!.message}`) throw new PluginError( `Failed resolving one or more provider configurations:\n${messages.join("\n")}`, { rawConfigs, taskResults, messages }, ) } - const providers: Provider[] = Object.values(taskResults).map(result => result.output) + const providers: Provider[] = Object.values(taskResults).map(result => result!.output) await Bluebird.map(providers, async (provider) => Bluebird.map(provider.moduleConfigs, async (moduleConfig) => { diff --git a/garden-service/src/plugins/kubernetes/init.ts b/garden-service/src/plugins/kubernetes/init.ts index bd8db58393..a143384a9f 100644 --- a/garden-service/src/plugins/kubernetes/init.ts +++ b/garden-service/src/plugins/kubernetes/init.ts @@ -153,7 +153,7 @@ export async function prepareSystem( } const serviceStatuses: ServiceStatusMap = (status.detail && status.detail.serviceStatuses) || {} - const serviceStates = Object.values(serviceStatuses).map(s => s.state!) + const serviceStates = Object.values(serviceStatuses).map(s => (s && s.state) || "unknown") const combinedState = combineStates(serviceStates) const remoteCluster = provider.name !== "local-kubernetes" diff --git a/garden-service/src/plugins/kubernetes/status/service.ts b/garden-service/src/plugins/kubernetes/status/service.ts index 1e442c0d5e..e34a807784 100644 --- a/garden-service/src/plugins/kubernetes/status/service.ts +++ b/garden-service/src/plugins/kubernetes/status/service.ts @@ -47,7 +47,7 @@ export async function waitForServiceEndpoints( while (true) { const endpoints = await api.core.readNamespacedEndpoints(serviceName, serviceNamespace) - const addresses = flatten(endpoints.subsets!.map(subset => subset.addresses || [])) + const addresses = flatten((endpoints.subsets || []).map(subset => subset.addresses || [])) const routedPods = addresses .filter(a => a.targetRef!.kind === "Pod" && readyPodNames.includes(a.targetRef!.name!)) diff --git a/garden-service/src/plugins/kubernetes/system.ts b/garden-service/src/plugins/kubernetes/system.ts index cd298836ac..2e58cb4040 100644 --- a/garden-service/src/plugins/kubernetes/system.ts +++ b/garden-service/src/plugins/kubernetes/system.ts @@ -150,7 +150,7 @@ export async function getSystemServiceStatus( const actions = await sysGarden.getActionHelper() const serviceStatuses = await actions.getServiceStatuses({ log, serviceNames }) - const state = combineStates(values(serviceStatuses).map(s => s.state || "unknown")) + const state = combineStates(values(serviceStatuses).map(s => (s && s.state) || "unknown")) // Add the Kubernetes dashboard to the Garden dashboard if (serviceNames.includes("kubernetes-dashboard")) { diff --git a/garden-service/src/task-graph.ts b/garden-service/src/task-graph.ts index f84bbe8657..da56d0bd91 100644 --- a/garden-service/src/task-graph.ts +++ b/garden-service/src/task-graph.ts @@ -37,7 +37,7 @@ export interface TaskResult { * the result from the last processed is used (hence only one key-value pair here per key). */ export interface TaskResults { - [key: string]: TaskResult + [key: string]: TaskResult | null } const DEFAULT_CONCURRENCY = 6 diff --git a/garden-service/src/tasks/base.ts b/garden-service/src/tasks/base.ts index 2ed85d955b..7dbc0c4cff 100644 --- a/garden-service/src/tasks/base.ts +++ b/garden-service/src/tasks/base.ts @@ -79,19 +79,19 @@ export abstract class BaseTask { } export function getServiceStatuses(dependencyResults: TaskResults): { [name: string]: ServiceStatus } { - const getServiceStatusResults = pickBy(dependencyResults, r => r.type === "get-service-status") - const deployResults = pickBy(dependencyResults, r => r.type === "deploy") + const getServiceStatusResults = pickBy(dependencyResults, r => r && r.type === "get-service-status") + const deployResults = pickBy(dependencyResults, r => r && r.type === "deploy") // DeployTask results take precedence over GetServiceStatusTask results, because status changes after deployment const combined = { ...getServiceStatusResults, ...deployResults } - const statuses = mapValues(combined, r => r.output as ServiceStatus) + const statuses = mapValues(combined, r => r!.output as ServiceStatus) return mapKeys(statuses, (_, key) => splitLast(key, ".")[1]) } export function getRunTaskResults(dependencyResults: TaskResults): { [name: string]: RunTaskResult } { - const storedResults = pickBy(dependencyResults, r => r.type === "get-task-result") - const runResults = pickBy(dependencyResults, r => r.type === "task") + const storedResults = pickBy(dependencyResults, r => r && r.type === "get-task-result") + const runResults = pickBy(dependencyResults, r => r && r.type === "task") // TaskTask results take precedence over GetTaskResultTask results const combined = { ...storedResults, ...runResults } - const results = mapValues(combined, r => r.output as RunTaskResult) + const results = mapValues(combined, r => r!.output as RunTaskResult) return mapKeys(results, (_, key) => splitLast(key, ".")[1]) } diff --git a/garden-service/src/tasks/resolve-provider.ts b/garden-service/src/tasks/resolve-provider.ts index 0a154f8cf7..9d7eca89bf 100644 --- a/garden-service/src/tasks/resolve-provider.ts +++ b/garden-service/src/tasks/resolve-provider.ts @@ -81,7 +81,7 @@ export class ResolveProviderTask extends BaseTask { } async process(dependencyResults: TaskResults) { - const resolvedProviders: Provider[] = Object.values(dependencyResults).map(result => result.output) + const resolvedProviders: Provider[] = Object.values(dependencyResults).map(result => result && result.output) const context = new ProviderConfigContext(this.garden.environmentName, this.garden.projectName, resolvedProviders) diff --git a/garden-service/test/helpers.ts b/garden-service/test/helpers.ts index 2492aa9bfe..167cd0e310 100644 --- a/garden-service/test/helpers.ts +++ b/garden-service/test/helpers.ts @@ -386,7 +386,7 @@ export async function expectError(fn: Function, typeOrCallback?: string | ((err: } export function taskResultOutputs(results: TaskResults) { - return mapValues(results, r => r.output) + return mapValues(results, r => r && r.output) } export const cleanProject = async (gardenDirPath: string) => { diff --git a/garden-service/test/unit/src/plugins/exec.ts b/garden-service/test/unit/src/plugins/exec.ts index 4f92d62ede..4daa62e4bf 100644 --- a/garden-service/test/unit/src/plugins/exec.ts +++ b/garden-service/test/unit/src/plugins/exec.ts @@ -149,7 +149,7 @@ describe("exec plugin", () => { const results = await _garden.processTasks([taskTask]) // Task A echoes "task-a-output" and Task B echoes the output from Task A - expect(results["task.task-b"].output.outputs.log).to.equal("task-a-output") + expect(results["task.task-b"]!.output.outputs.log).to.equal("task-a-output") }) describe("getBuildStatus", () => { diff --git a/garden-service/test/unit/src/plugins/terraform/terraform.ts b/garden-service/test/unit/src/plugins/terraform/terraform.ts index e0336100ad..098d42264b 100644 --- a/garden-service/test/unit/src/plugins/terraform/terraform.ts +++ b/garden-service/test/unit/src/plugins/terraform/terraform.ts @@ -90,6 +90,6 @@ describe("Terraform module type", () => { it("should expose runtime outputs to template contexts", async () => { const result = await runTestTask() - expect(result["task.test-task"].output.outputs.log).to.equal("input: foo") + expect(result["task.test-task"]!.output.outputs.log).to.equal("input: foo") }) })