diff --git a/core/src/actions/helpers.ts b/core/src/actions/helpers.ts
index 4f9b514942..1e054c7a48 100644
--- a/core/src/actions/helpers.ts
+++ b/core/src/actions/helpers.ts
@@ -101,18 +101,6 @@ export async function warnOnLinkedActions(garden: Garden, log: Log, actions: Act
}
}
-const displayStates = {
- failed: "in a failed state",
- unknown: "in an unknown state",
-}
-
-/**
- * Just to make action states look nicer in print.
- */
-export function displayState(state: ActionState) {
- return displayStates[state] || state.replace("-", " ")
-}
-
/**
* Get the state of an Action
*/
diff --git a/core/src/commands/base.ts b/core/src/commands/base.ts
index afe14920d2..8045b30bfa 100644
--- a/core/src/commands/base.ts
+++ b/core/src/commands/base.ts
@@ -323,7 +323,7 @@ export abstract class Command<
}).href
const cloudLog = log.createLog({ name: getCloudLogSectionName(distroName) })
- cloudLog.info(`View command results at: ${styles.highlight(commandResultUrl)}\n`)
+ cloudLog.info(`View command results at: ${styles.link(commandResultUrl)}\n`)
}
let analytics: AnalyticsHandler | undefined
diff --git a/core/src/garden.ts b/core/src/garden.ts
index 95dbfbb162..618e9e4593 100644
--- a/core/src/garden.ts
+++ b/core/src/garden.ts
@@ -1831,7 +1831,7 @@ export const resolveGardenParams = profileAsync(async function _resolveGardenPar
const isCommunityEdition = !config.domain
const cloudLog = log.createLog({ name: getCloudLogSectionName(distroName) })
- cloudLog.verbose(`Connecting to ${distroName}...`)
+ cloudLog.info(`Connecting to ${distroName}...`)
cloudProject = await getCloudProject({
cloudApi,
diff --git a/core/src/logger/renderers.ts b/core/src/logger/renderers.ts
index d643bc36ee..f3a6928403 100644
--- a/core/src/logger/renderers.ts
+++ b/core/src/logger/renderers.ts
@@ -18,12 +18,12 @@ import { highlightYaml, safeDumpYaml } from "../util/serialization.js"
import type { Logger } from "./logger.js"
import { logLevelMap, LogLevel } from "./logger.js"
import { toGardenError } from "../exceptions.js"
-import type { Styles } from "./styles.js"
import { styles } from "./styles.js"
+import type { Chalk } from "chalk"
type RenderFn = (entry: LogEntry, logger: Logger) => string
-export const SECTION_PADDING = 20
+export const SECTION_PADDING = 25
export function padSection(section: string, width: number = SECTION_PADDING) {
const diff = width - stringWidth(section)
@@ -92,7 +92,7 @@ export function renderTimestamp(entry: LogEntry, logger: Logger): string {
}
export function getStyle(level: LogLevel) {
- let style: Styles
+ let style: Chalk
if (level === LogLevel.error) {
style = styles.error
} else if (level === LogLevel.warn) {
@@ -116,20 +116,15 @@ export function getSection(entry: LogEntry): string | null {
export function renderMsg(entry: LogEntry): string {
const { context, level } = entry
- const msg = resolveMsg(entry)
- const { origin } = context
+ const msg = resolveMsg(entry) || ""
const style = getStyle(level)
- if (!msg) {
- return ""
- }
+ // For log levels higher than "info" we print the log level name.
+ const logLevelName = entry.level > LogLevel.info ? `[${logLevelMap[entry.level]}] ` : ""
- // TODO: @eysi Should we strip here?
- // if (level > LogLevel.info) {
- // msg = stripAnsi(msg)
- // }
+ const origin = context.origin ? `[${styles.italic(context.origin)}] ` : ""
- return style(origin ? `[${styles.italic(origin)}] ` + msg : msg)
+ return style(`${logLevelName}${origin}${msg}`)
}
export function renderData(entry: LogEntry): string {
@@ -146,31 +141,12 @@ export function renderData(entry: LogEntry): string {
export function renderSection(entry: LogEntry): string {
const { msg } = entry
- let section = getSection(entry)
-
- // For log levels higher than "info" we print the log level name.
- // This should technically happen when we render the symbol but it's harder
- // to deal with the padding that way.
- const logLevelName = styles.secondary(`[${logLevelMap[entry.level]}]`)
-
- // Just print the log level name directly without padding. E.g:
- // ℹ api → Deploying version v-37d6c44559...
- // [verbose] Some verbose level stuff that doesn't have a section
- if (!section && entry.level > LogLevel.info) {
- return logLevelName + " "
- }
-
- // Print the log level name after the section name to preserve alignment. E.g.:
- // ℹ api → Deploying version v-37d6c44559...
- // ℹ api [verbose] → Some verbose level stuff that has a section
- if (entry.level > LogLevel.info) {
- section = section ? `${section} ${logLevelName}` : logLevelName
- }
+ const section = getSection(entry)
if (section && msg) {
- return `${styles.section(padSection(section))} ${styles.accent.bold("→")} `
+ return `${padSection(styles.section(section))} ${styles.accent.bold("→")} `
} else if (section) {
- return styles.section(padSection(section))
+ return padSection(styles.section(section))
}
return ""
}
diff --git a/core/src/logger/styles.ts b/core/src/logger/styles.ts
index 74d299613e..11b6420b47 100644
--- a/core/src/logger/styles.ts
+++ b/core/src/logger/styles.ts
@@ -8,39 +8,18 @@
import chalk from "chalk"
-// Helper types for ensuring the consumer of the "styles" map defined below
-// can only call the allowed keys when chaining styles.
-// Otherwise you could do something like `styles.primary.red` and "break out"
-// of the pre-defined styles.
-//
-// Requires and ugly cast in the maps below but I couldn't find a more elegant
-// way to do this with just Typescript.
-type ThemeKey =
- | "primary"
- | "secondary"
- | "accent"
- | "highlight"
- | "highlightSecondary"
- | "warning"
- | "error"
- | "success"
-type StyleKey = "bold" | "underline" | "italic" | "link" | "section" | "command"
-type StyleFn = (s: string) => string
-
-export type Styles = StyleFn & { [key in ThemeKey | StyleKey]: Styles }
-
/**
* A map of all the colors we use to render text in the terminal.
*/
const theme = {
- primary: chalk.grey as unknown as Styles,
- secondary: chalk.grey as unknown as Styles,
- accent: chalk.white as unknown as Styles,
- highlight: chalk.cyan as unknown as Styles,
- highlightSecondary: chalk.magenta as unknown as Styles,
- warning: chalk.yellow as unknown as Styles,
- error: chalk.red as unknown as Styles,
- success: chalk.green as unknown as Styles,
+ primary: chalk.grey,
+ secondary: chalk.grey,
+ accent: chalk.white,
+ highlight: chalk.cyan,
+ highlightSecondary: chalk.magenta,
+ warning: chalk.yellow,
+ error: chalk.red,
+ success: chalk.green,
}
/**
@@ -63,10 +42,10 @@ const theme = {
*/
export const styles = {
...theme,
- bold: chalk.bold as unknown as Styles,
- underline: chalk.underline as unknown as Styles,
- italic: chalk.italic as unknown as Styles,
- link: theme.highlight.underline as unknown as Styles,
- section: theme.highlight.italic as unknown as Styles,
- command: theme.highlightSecondary.bold as unknown as Styles,
+ bold: chalk.bold,
+ underline: chalk.underline,
+ italic: chalk.italic,
+ link: theme.highlight.underline,
+ section: theme.highlight.italic,
+ command: theme.highlightSecondary.bold,
}
diff --git a/core/src/logger/util.ts b/core/src/logger/util.ts
index 7566279906..16f3099868 100644
--- a/core/src/logger/util.ts
+++ b/core/src/logger/util.ts
@@ -10,8 +10,8 @@ import hasAnsi from "has-ansi"
import dedent from "dedent"
import stringWidth from "string-width"
import { DEFAULT_BROWSER_DIVIDER_WIDTH } from "../constants.js"
-import type { Styles } from "./styles.js"
import { styles } from "./styles.js"
+import type { Chalk } from "chalk"
// Add platforms/terminals?
export function envSupportsEmoji() {
@@ -74,7 +74,7 @@ interface DividerOpts {
width?: number
char?: string
titlePadding?: number
- color?: Styles
+ color?: Chalk
title?: string
padding?: number
}
@@ -144,7 +144,7 @@ export function renderMessageWithDivider({
prefix: string
msg: string
isError: boolean
- color?: Styles
+ color?: Chalk
}) {
// Allow overwriting color as an escape hatch. Otherwise defaults to white or red in case of errors.
const msgColor = color || (isError ? styles.error : styles.accent)
diff --git a/core/src/plugins/kubernetes/container/build/common.ts b/core/src/plugins/kubernetes/container/build/common.ts
index eea6254b0d..59ca5020d2 100644
--- a/core/src/plugins/kubernetes/container/build/common.ts
+++ b/core/src/plugins/kubernetes/container/build/common.ts
@@ -32,6 +32,7 @@ import { getRunningDeploymentPod } from "../../util.js"
import { buildSyncVolumeName, dockerAuthSecretKey, k8sUtilImageName, rsyncPortName } from "../../constants.js"
import { styles } from "../../../../logger/styles.js"
import type { StringMap } from "../../../../config/common.js"
+import { LogLevel } from "../../../../logger/logger.js"
export const inClusterBuilderServiceAccount = "garden-in-cluster-builder"
export const sharedBuildSyncDeploymentName = "garden-build-sync"
@@ -95,8 +96,11 @@ export async function syncToBuildSync(params: SyncToSharedBuildSyncParams) {
// Sync using mutagen
const key = `k8s--build-sync--${ctx.environmentName}--${namespace}--${action.name}--${randomString(8)}`
const targetPath = `/data/${ctx.workingCopyId}/${action.name}`
+ // We print the sync logs from Mutagen at a higher level for builds
+ const mutagenLog = log.createLog({ fixLevel: LogLevel.verbose })
+ const mutagen = new Mutagen({ ctx, log: mutagenLog })
- const mutagen = new Mutagen({ ctx, log })
+ const syncLog = log.createLog().info(`Syncing build context to cluster...`)
// Make sure the target path exists
const runner = new PodRunner({
@@ -153,7 +157,7 @@ export async function syncToBuildSync(params: SyncToSharedBuildSyncParams) {
log.debug(`Sync connection terminated`)
}
- log.info("File sync to cluster complete")
+ syncLog.success("File sync to cluster complete")
return { contextRelPath, contextPath, dataPath }
}
diff --git a/core/src/plugins/kubernetes/nginx/default-backend.ts b/core/src/plugins/kubernetes/nginx/default-backend.ts
index a3aca3935a..0589e45e90 100644
--- a/core/src/plugins/kubernetes/nginx/default-backend.ts
+++ b/core/src/plugins/kubernetes/nginx/default-backend.ts
@@ -11,7 +11,6 @@ import type { Log } from "../../../logger/log-entry.js"
import type { DeployState } from "../../../types/service.js"
import { KubeApi } from "../api.js"
import { checkResourceStatus, waitForResources } from "../status/status.js"
-import chalk from "chalk"
import type { KubernetesDeployment, KubernetesService } from "../types.js"
import { defaultGardenIngressControllerDefaultBackendImage } from "../constants.js"
import { GardenIngressComponent } from "./ingress-controller-base.js"
@@ -51,7 +50,7 @@ export class GardenDefaultBackend extends GardenIngressComponent {
const { deployment } = defaultBackendGetManifests(ctx)
const deploymentStatus = await checkResourceStatus({ api, namespace, manifest: deployment, log })
- log.debug(chalk.yellow(`Status of ingress controller default-backend: ${deploymentStatus}`))
+ log.debug(`Status of ingress controller default-backend: ${deploymentStatus}`)
return deploymentStatus.state
}
diff --git a/core/src/plugins/kubernetes/nginx/nginx-helm.ts b/core/src/plugins/kubernetes/nginx/nginx-helm.ts
index 5e3e6bb7eb..f1d39bfea8 100644
--- a/core/src/plugins/kubernetes/nginx/nginx-helm.ts
+++ b/core/src/plugins/kubernetes/nginx/nginx-helm.ts
@@ -6,7 +6,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
-import chalk from "chalk"
import type { Log } from "../../../logger/log-entry.js"
import type { DeployState } from "../../../types/service.js"
import type { KubernetesPluginContext } from "../config.js"
@@ -106,7 +105,7 @@ export abstract class HelmGardenIngressController extends GardenIngressComponent
const releaseStatus = statusRes.info?.status || "unknown"
if (releaseStatus !== "deployed") {
- log.debug(chalk.yellow(`Helm release status for ${HELM_INGRESS_NGINX_RELEASE_NAME}: ${releaseStatus}`))
+ log.debug(`Helm release status for ${HELM_INGRESS_NGINX_RELEASE_NAME}: ${releaseStatus}`)
return helmStatusMap[releaseStatus] || "unknown"
}
@@ -116,7 +115,7 @@ export abstract class HelmGardenIngressController extends GardenIngressComponent
const deploymentStatus = await checkResourceStatus({ api, namespace, manifest: nginxHelmMainResource, log })
return deploymentStatus.state
} catch (error) {
- log.debug(chalk.yellow(`Helm release ${HELM_INGRESS_NGINX_RELEASE_NAME} missing.`))
+ log.debug(`Helm release ${HELM_INGRESS_NGINX_RELEASE_NAME} missing.`)
return "missing"
}
}
diff --git a/core/src/plugins/kubernetes/nginx/nginx-kind.ts b/core/src/plugins/kubernetes/nginx/nginx-kind.ts
index c14c782ede..6d7cd1758d 100644
--- a/core/src/plugins/kubernetes/nginx/nginx-kind.ts
+++ b/core/src/plugins/kubernetes/nginx/nginx-kind.ts
@@ -10,7 +10,6 @@ import type { Log } from "../../../logger/log-entry.js"
import type { KubernetesPluginContext } from "../config.js"
import { KubeApi } from "../api.js"
import { checkResourceStatus, waitForResources } from "../status/status.js"
-import chalk from "chalk"
import { apply, deleteResources } from "../kubectl.js"
import type { DeployState } from "../../../types/service.js"
import { kindNginxGetManifests } from "./nginx-kind-manifests.js"
@@ -61,7 +60,7 @@ export class KindGardenIngressController extends GardenIngressComponent {
const deploymentStatus = await checkResourceStatus({ api, namespace, manifest: nginxKindMainResource, log })
- log.debug(chalk.yellow(`Status of ingress controller: ${deploymentStatus.state}`))
+ log.debug(`Status of ingress controller: ${deploymentStatus.state}`)
return deploymentStatus.state
}
diff --git a/core/src/plugins/kubernetes/nginx/nginx-microk8s.ts b/core/src/plugins/kubernetes/nginx/nginx-microk8s.ts
index d9b73f30a2..11f6a4ae3d 100644
--- a/core/src/plugins/kubernetes/nginx/nginx-microk8s.ts
+++ b/core/src/plugins/kubernetes/nginx/nginx-microk8s.ts
@@ -8,7 +8,6 @@
import type { Log } from "../../../logger/log-entry.js"
import { exec } from "../../../util/util.js"
-import chalk from "chalk"
import type { KubernetesPluginContext } from "../config.js"
import { type DeployState } from "../../../types/service.js"
import { configureMicrok8sAddons } from "../local/microk8s.js"
@@ -50,7 +49,7 @@ export class Microk8sGardenIngressController extends GardenIngressComponent {
const statusCommandResult = await exec("microk8s", ["status", "--format", "short"])
const status = statusCommandResult.stdout
const addonEnabled = status.includes("core/ingress: enabled")
- log.debug(chalk.yellow(`Status of microk8s ingress controller addon: ${addonEnabled ? "enabled" : "disabled"}`))
+ log.debug(`Status of microk8s ingress controller addon: ${addonEnabled ? "enabled" : "disabled"}`)
return addonEnabled ? "ready" : "missing"
}
diff --git a/core/src/plugins/kubernetes/nginx/nginx-minikube.ts b/core/src/plugins/kubernetes/nginx/nginx-minikube.ts
index 1411ba621d..dbd3869f87 100644
--- a/core/src/plugins/kubernetes/nginx/nginx-minikube.ts
+++ b/core/src/plugins/kubernetes/nginx/nginx-minikube.ts
@@ -9,7 +9,6 @@
import type { Log } from "../../../logger/log-entry.js"
import type { DeployState } from "../../../types/service.js"
import { exec } from "../../../util/util.js"
-import chalk from "chalk"
import type { KubernetesPluginContext } from "../config.js"
import { KubeApi } from "../api.js"
import { checkResourceStatus, waitForResources } from "../status/status.js"
@@ -45,7 +44,7 @@ export class MinikubeGardenIngressController extends GardenIngressComponent {
const addonEnabled = minikubeAddons.ingress.Status === "enabled"
if (!addonEnabled) {
- log.debug(chalk.yellow("Status of minikube ingress controller addon: missing"))
+ log.debug("Status of minikube ingress controller addon: missing")
return "missing"
}
//check if ingress controller deployment is ready
@@ -55,7 +54,7 @@ export class MinikubeGardenIngressController extends GardenIngressComponent {
manifest: nginxKindMainResource,
log,
})
- log.debug(chalk.yellow(`Status of minikube ingress controller addon: ${deploymentStatus.state}`))
+ log.debug(`Status of minikube ingress controller addon: ${deploymentStatus.state}`)
return deploymentStatus.state
}
diff --git a/core/src/tasks/base.ts b/core/src/tasks/base.ts
index 6b96ea435b..ad83f924a4 100644
--- a/core/src/tasks/base.ts
+++ b/core/src/tasks/base.ts
@@ -34,6 +34,7 @@ import {
makeActionProcessingPayload,
makeActionGetStatusPayload,
} from "../events/util.js"
+import { styles } from "../logger/styles.js"
export function makeBaseKey(type: string, name: string) {
return `${type}.${name}`
@@ -376,13 +377,56 @@ const actionKindToEventNameMap = {
run: "runStatus",
} satisfies { [key in ExecuteActionTaskType]: ActionStatusEventName }
+const displayStates = {
+ failed: "in a failed state",
+ unknown: "in an unknown state",
+}
+
+/**
+ * Just to make action states look nicer in print.
+ */
+function displayState(state: ActionState): string {
+ return displayStates[state] || state.replace("-", " ")
+}
+
+/*+
+ * Map of log strings used for logging the action lifecycle.
+ */
+const actionLogStrings = {
+ Build: {
+ ready: "built",
+ notReady: "will be built",
+ force: "rebuild",
+ running: "Building",
+ },
+ Deploy: {
+ ready: "deployed",
+ notReady: "will be deployed",
+ force: "redeploy",
+ running: "Deploying",
+ },
+ Test: {
+ ready: "run",
+ notReady: "test will be run",
+ force: "rerun test",
+ running: "Testing",
+ },
+ Run: {
+ ready: "run",
+ notReady: "will be run",
+ force: "rerun",
+ running: "Running",
+ },
+}
+
/**
* Decorator function for emitting status events to Cloud when calling the
- * getStatus method on ExecutionAction tasks.
+ * getStatus method on ExecutionAction tasks and for logging the operation lifecycle
+ * to the terminal.
*
* The wrapper emits the appropriate events before and after the inner function execution.
*/
-export function emitGetStatusEvents<
+export function logAndEmitGetStatusEvents<
A extends Action,
R extends ValidExecutionActionResultType = {
state: ActionState
@@ -403,16 +447,20 @@ export function emitGetStatusEvents<
descriptor.value = async function (this: ExecuteActionTask, ...args: [ActionTaskStatusParams]) {
const statusOnly = args[0].statusOnly
-
// We don't emit events when just checking the status
if (statusOnly) {
const result = (await method.apply(this, args)) as R & ExecuteActionOutputs
return result
}
- const actionKind = this.action.kind.toLowerCase() as Lowercase
- const eventName = actionKindToEventNameMap[actionKind]
+ const log = this.log.createLog()
+ const actionKindLowercased = this.action.kind.toLowerCase() as Lowercase
+ const eventName = actionKindToEventNameMap[actionKindLowercased]
const startedAt = new Date().toISOString()
+ const styledName = styles.highlight(this.action.name)
+ const logStrings = actionLogStrings[this.action.kind]
+
+ log.info(`Getting status for ${this.action.kind} ${styledName} (type ${styles.highlight(this.action.type)})...`)
// First we emit the "getting-status" event
this.garden.events.emit(
@@ -428,6 +476,16 @@ export function emitGetStatusEvents<
try {
const result = (await method.apply(this, args)) as R & ExecuteActionOutputs
+ const willRerun = this.force && !statusOnly
+ if (result.state === "ready" && !willRerun) {
+ log.success({ msg: `Already ${logStrings.ready}`, showDuration: false })
+ } else if (result.state === "ready" && willRerun) {
+ log.info(`${styledName} is already ${logStrings.ready}, will force ${logStrings.force}`)
+ } else {
+ const stateStr = result.detail?.state || displayState(result.state)
+ log.warn(`Status is '${stateStr}', ${styledName} ${logStrings.notReady}`)
+ }
+
// Then an event with the results if the status was successfully retrieved...
const donePayload = makeActionCompletePayload({
result,
@@ -443,6 +501,9 @@ export function emitGetStatusEvents<
return result
} catch (err) {
// ...otherwise we emit a "failed" event
+
+ // The error proper is logged downstream
+ log.error("Failed")
this.garden.events.emit(
eventName,
makeActionFailedPayload({
@@ -463,11 +524,12 @@ export function emitGetStatusEvents<
/**
* Decorator function for emitting status events to Cloud when calling the
- * process method on ExecutionAction tasks.
+ * process method on ExecutionAction tasks and for logging the operation lifecycle
+ * to the terminal.
*
* The wrapper emits the appropriate events before and after the inner function execution.
*/
-export function emitProcessingEvents<
+export function logAndEmitProcessingEvents<
A extends Action,
R extends ValidExecutionActionResultType = {
state: ActionState
@@ -492,6 +554,14 @@ export function emitProcessingEvents<
const actionKind = this.action.kind.toLowerCase() as Lowercase
const eventName = actionKindToEventNameMap[actionKind]
const startedAt = new Date().toISOString()
+ const log = this.log.createLog()
+ const version = this.action.versionString()
+ const logStrings = actionLogStrings[this.action.kind]
+ log.info(
+ `${logStrings.running} ${styles.highlight(this.action.name)} (type ${styles.highlight(
+ this.action.type
+ )}) at version ${styles.highlight(version)}...`
+ )
// First we emit the "processing" event
this.garden.events.emit(
@@ -518,10 +588,14 @@ export function emitProcessingEvents<
}) as Events[typeof eventName]
this.garden.events.emit(eventName, donePayload)
+ log.success("Done")
return result
} catch (err) {
// ...otherwise we emit a "failed" event
+
+ // The error proper is logged downstream
+ log.error("Failed")
this.garden.events.emit(
eventName,
makeActionFailedPayload({
diff --git a/core/src/tasks/build.ts b/core/src/tasks/build.ts
index 46f11a1ac7..945d6eb0e5 100644
--- a/core/src/tasks/build.ts
+++ b/core/src/tasks/build.ts
@@ -7,7 +7,7 @@
*/
import type { BaseActionTaskParams, ActionTaskProcessParams, ActionTaskStatusParams } from "../tasks/base.js"
-import { ExecuteActionTask, emitGetStatusEvents, emitProcessingEvents } from "../tasks/base.js"
+import { ExecuteActionTask, logAndEmitGetStatusEvents, logAndEmitProcessingEvents } from "../tasks/base.js"
import { Profile } from "../util/profiling.js"
import type { BuildAction, BuildActionConfig, ResolvedBuildAction } from "../actions/build.js"
import pluralize from "pluralize"
@@ -38,7 +38,7 @@ export class BuildTask extends ExecuteActionTask {
}
},
})
- @(emitGetStatusEvents)
+ @(logAndEmitGetStatusEvents)
async getStatus({ statusOnly, dependencyResults }: ActionTaskStatusParams) {
const router = await this.garden.getActionRouter()
const action = this.getResolvedAction(this.action, dependencyResults)
@@ -47,7 +47,6 @@ export class BuildTask extends ExecuteActionTask {
const status = output.result
if (status.state === "ready" && !statusOnly && !this.force) {
- this.log.info(`Already built`)
await this.ensureBuildContext(action)
}
@@ -65,7 +64,7 @@ export class BuildTask extends ExecuteActionTask {
}
},
})
- @(emitProcessingEvents)
+ @(logAndEmitProcessingEvents)
async process({ dependencyResults }: ActionTaskProcessParams) {
const router = await this.garden.getActionRouter()
const action = this.getResolvedAction(this.action, dependencyResults)
@@ -87,7 +86,6 @@ export class BuildTask extends ExecuteActionTask {
log,
})
)
- log.success(`Done`)
return {
...result,
@@ -95,8 +93,6 @@ export class BuildTask extends ExecuteActionTask {
executedAction: resolvedActionToExecuted(action, { status: result }),
}
} catch (err) {
- log.error(`Build failed`)
-
throw err
}
}
diff --git a/core/src/tasks/deploy.ts b/core/src/tasks/deploy.ts
index 0dc99ff344..e83be4d4e1 100644
--- a/core/src/tasks/deploy.ts
+++ b/core/src/tasks/deploy.ts
@@ -7,12 +7,12 @@
*/
import type { BaseActionTaskParams, BaseTask, ActionTaskProcessParams, ActionTaskStatusParams } from "./base.js"
-import { ExecuteActionTask, emitGetStatusEvents, emitProcessingEvents } from "./base.js"
+import { ExecuteActionTask, logAndEmitGetStatusEvents, logAndEmitProcessingEvents } from "./base.js"
import { getLinkUrl } from "../types/service.js"
import { Profile } from "../util/profiling.js"
import type { DeployAction } from "../actions/deploy.js"
import type { DeployStatus } from "../plugin/handlers/Deploy/get-status.js"
-import { displayState, resolvedActionToExecuted } from "../actions/helpers.js"
+import { resolvedActionToExecuted } from "../actions/helpers.js"
import type { PluginEventBroker } from "../plugin-context.js"
import type { ActionLog } from "../logger/log-entry.js"
import { OtelTraced } from "../util/open-telemetry/decorators.js"
@@ -65,7 +65,7 @@ export class DeployTask extends ExecuteActionTask {
}
},
})
- @(emitGetStatusEvents)
+ @(logAndEmitGetStatusEvents)
async getStatus({ statusOnly, dependencyResults }: ActionTaskStatusParams) {
const log = this.log.createLog()
const action = this.getResolvedAction(this.action, dependencyResults)
@@ -82,14 +82,8 @@ export class DeployTask extends ExecuteActionTask {
status.state = "not-ready"
}
- if (!statusOnly && !this.force) {
- if (status.state === "ready") {
- log.success({ msg: `Already deployed`, showDuration: false })
- printIngresses(status, log)
- } else {
- const state = status.detail?.state || displayState(status.state)
- log.info(state)
- }
+ if (!statusOnly && !this.force && status.state === "ready") {
+ printIngresses(status, log)
}
const executedAction = resolvedActionToExecuted(action, { status })
@@ -113,7 +107,7 @@ export class DeployTask extends ExecuteActionTask {
}
},
})
- @(emitProcessingEvents)
+ @(logAndEmitProcessingEvents)
async process({ dependencyResults, status }: ActionTaskProcessParams) {
const action = this.getResolvedAction(this.action, dependencyResults)
const version = action.versionString()
@@ -121,7 +115,6 @@ export class DeployTask extends ExecuteActionTask {
const router = await this.garden.getActionRouter()
const log = this.log.createLog()
- log.info(`Deploying version ${version}...`)
try {
const output = await router.deploy.deploy({
@@ -133,12 +126,9 @@ export class DeployTask extends ExecuteActionTask {
})
status = output.result
} catch (err) {
- log.error(`Failed`)
throw err
}
- log.success(`Done`)
-
const executedAction = resolvedActionToExecuted(action, { status })
printIngresses(status, log)
diff --git a/core/src/tasks/run.ts b/core/src/tasks/run.ts
index 455e7f0a43..2a290eaaa8 100644
--- a/core/src/tasks/run.ts
+++ b/core/src/tasks/run.ts
@@ -7,7 +7,7 @@
*/
import type { BaseActionTaskParams, ActionTaskProcessParams, ActionTaskStatusParams } from "./base.js"
-import { ExecuteActionTask, emitGetStatusEvents, emitProcessingEvents } from "./base.js"
+import { ExecuteActionTask, logAndEmitGetStatusEvents, logAndEmitProcessingEvents } from "./base.js"
import { Profile } from "../util/profiling.js"
import type { RunAction } from "../actions/run.js"
import type { GetRunResult } from "../plugin/handlers/Run/get-result.js"
@@ -46,9 +46,8 @@ export class RunTask extends ExecuteActionTask {
}
},
})
- @(emitGetStatusEvents)
- async getStatus({ statusOnly, dependencyResults }: ActionTaskStatusParams) {
- this.log.verbose("Checking status...")
+ @(logAndEmitGetStatusEvents)
+ async getStatus({ dependencyResults }: ActionTaskStatusParams) {
const router = await this.garden.getActionRouter()
const action = this.getResolvedAction(this.action, dependencyResults)
@@ -60,8 +59,6 @@ export class RunTask extends ExecuteActionTask {
log: this.log,
})
- this.log.verbose(`Status check complete`)
-
if (status.detail === null) {
return {
...status,
@@ -71,18 +68,12 @@ export class RunTask extends ExecuteActionTask {
}
}
- if (status.state === "ready" && !statusOnly && !this.force) {
- this.log.success("Already complete")
- }
-
return {
...status,
version: action.versionString(),
executedAction: resolvedActionToExecuted(action, { status }),
}
} catch (err) {
- this.log.error(`Failed getting status`)
-
throw err
}
}
@@ -98,12 +89,10 @@ export class RunTask extends ExecuteActionTask {
}
},
})
- @(emitProcessingEvents)
+ @(logAndEmitProcessingEvents)
async process({ dependencyResults }: ActionTaskProcessParams) {
const action = this.getResolvedAction(this.action, dependencyResults)
-
- const taskLog = this.log.createLog().info("Running...")
-
+ const taskLog = this.log.createLog()
const actions = await this.garden.getActionRouter()
let status: GetRunResult
@@ -117,14 +106,9 @@ export class RunTask extends ExecuteActionTask {
})
status = output.result
} catch (err) {
- taskLog.error(`Failed running ${action.name}`)
-
throw err
}
- if (status.state === "ready") {
- taskLog.success(`Done`)
- } else {
- taskLog.error(`Failed!`)
+ if (status.state !== "ready") {
if (status.detail?.diagnosticErrorMsg) {
this.log.debug(`Additional context for the error:\n\n${status.detail.diagnosticErrorMsg}`)
}
diff --git a/core/src/tasks/test.ts b/core/src/tasks/test.ts
index 3132accb9a..0c34c46c89 100644
--- a/core/src/tasks/test.ts
+++ b/core/src/tasks/test.ts
@@ -7,7 +7,7 @@
*/
import type { BaseActionTaskParams, ActionTaskProcessParams, ActionTaskStatusParams } from "../tasks/base.js"
-import { ExecuteActionTask, emitGetStatusEvents, emitProcessingEvents } from "../tasks/base.js"
+import { ExecuteActionTask, logAndEmitGetStatusEvents, logAndEmitProcessingEvents } from "../tasks/base.js"
import { Profile } from "../util/profiling.js"
import { resolvedActionToExecuted } from "../actions/helpers.js"
import type { TestAction } from "../actions/test.js"
@@ -64,9 +64,8 @@ export class TestTask extends ExecuteActionTask {
}
},
})
- @(emitGetStatusEvents)
+ @(logAndEmitGetStatusEvents)
async getStatus({ dependencyResults }: ActionTaskStatusParams) {
- this.log.verbose("Checking status...")
const action = this.getResolvedAction(this.action, dependencyResults)
const router = await this.garden.getActionRouter()
@@ -76,17 +75,12 @@ export class TestTask extends ExecuteActionTask {
action,
})
- this.log.verbose("Status check complete")
-
const testResult = status?.detail
const version = action.versionString()
const executedAction = resolvedActionToExecuted(action, { status })
if (testResult && testResult.success) {
- if (!this.force) {
- this.log.success("Already passed")
- }
return {
...status,
version,
@@ -111,12 +105,10 @@ export class TestTask extends ExecuteActionTask {
}
},
})
- @(emitProcessingEvents)
+ @(logAndEmitProcessingEvents)
async process({ dependencyResults }: ActionTaskProcessParams) {
const action = this.getResolvedAction(this.action, dependencyResults)
- this.log.info(`Running...`)
-
const router = await this.garden.getActionRouter()
let status: GetTestResult
@@ -130,12 +122,9 @@ export class TestTask extends ExecuteActionTask {
})
status = output.result
} catch (err) {
- this.log.error(`Failed running test`)
-
throw err
}
if (status.detail?.success) {
- this.log.success(`Success`)
} else {
const exitCode = status.detail?.exitCode
const failedMsg = !!exitCode ? `Failed with code ${exitCode}!` : `Failed!`
diff --git a/core/test/unit/src/logger/renderers.ts b/core/test/unit/src/logger/renderers.ts
index 3cdcb365e5..590cffdbb8 100644
--- a/core/test/unit/src/logger/renderers.ts
+++ b/core/test/unit/src/logger/renderers.ts
@@ -17,7 +17,6 @@ import {
formatForJson,
SECTION_PADDING,
renderData,
- padSection,
renderSection,
} from "../../../../src/logger/renderers.js"
import { GenericGardenError } from "../../../../src/exceptions.js"
@@ -121,17 +120,7 @@ describe("renderers", () => {
it("should print the log level if it's higher then 'info'", () => {
const entry = logger.createLog().debug({ msg: "hello world" }).getLatestEntry()
- expect(formatForTerminal(entry, logger)).to.equal(
- `${styles.primary("[debug]")} ${styles.primary("hello world")}\n`
- )
- })
- it("should print the log level if it's higher then 'info' after the section if there is one", () => {
- const entry = logger.createLog({ name: "foo" }).debug("hello world").getLatestEntry()
-
- const section = `foo ${styles.primary("[debug]")}`
- expect(formatForTerminal(entry, logger)).to.equal(
- `${logSymbols["info"]} ${styles.highlight.italic(padSection(section))} → ${styles.primary("hello world")}\n`
- )
+ expect(formatForTerminal(entry, logger)).to.equal(`${styles.secondary("[debug] hello world")}\n`)
})
context("basic", () => {
before(() => {
@@ -142,7 +131,7 @@ describe("renderers", () => {
const entry = logger.createLog().info("hello world").getLatestEntry()
expect(formatForTerminal(entry, logger)).to.equal(
- `${styles.primary(format(now, "HH:mm:ss"))} ${styles.primary("hello world")}\n`
+ `${styles.secondary(format(now, "HH:mm:ss"))} ${styles.primary("hello world")}\n`
)
})
after(() => {