From bac4f7466eb0d517a4d7b76ae14b323d902eedad Mon Sep 17 00:00:00 2001 From: Emanuele Libralato Date: Fri, 17 Jan 2020 13:13:40 +0100 Subject: [PATCH] refactor(logger): add dataFormat to LogEntry Add the possibility of passing a dataFormat field as LogEntryParams to allow choosing the render methord for the data field. Allowed options are "json" and "yaml". Default remains "yaml" --- garden-service/src/logger/log-entry.ts | 4 +++ garden-service/src/logger/renderers.ts | 9 +++-- .../test/unit/src/logger/log-entry.ts | 7 ++++ .../test/unit/src/logger/renderers.ts | 34 +++++++++++++++++++ 4 files changed, 51 insertions(+), 3 deletions(-) diff --git a/garden-service/src/logger/log-entry.ts b/garden-service/src/logger/log-entry.ts index 86e566731f..f43000f79f 100644 --- a/garden-service/src/logger/log-entry.ts +++ b/garden-service/src/logger/log-entry.ts @@ -41,6 +41,7 @@ interface MessageBase { symbol?: LogSymbol append?: boolean data?: any + dataFormat?: "json" | "yaml" maxSectionWidth?: number } @@ -55,6 +56,7 @@ export interface UpdateLogEntryParams extends MessageBase { export interface LogEntryParams extends UpdateLogEntryParams { error?: GardenError data?: any // to be rendered as e.g. YAML or JSON + dataFormat?: "json" | "yaml" // how to render the data object indent?: number childEntriesInheritLevel?: boolean fromStdStream?: boolean @@ -107,6 +109,7 @@ export class LogEntry extends LogNode { symbol: params.symbol, status: params.level === LogLevel.error ? "error" : params.status, data: params.data, + dataFormat: params.dataFormat, maxSectionWidth: params.maxSectionWidth, }) } @@ -130,6 +133,7 @@ export class LogEntry extends LogNode { status: updateParams.status || messageState.status, symbol: updateParams.symbol || messageState.symbol, data: updateParams.data || messageState.data, + dataFormat: updateParams.dataFormat || messageState.dataFormat, // Next state does not inherit the append field append: updateParams.append, timestamp: Date.now(), diff --git a/garden-service/src/logger/renderers.ts b/garden-service/src/logger/renderers.ts index cbb6ca42b4..dd0e166281 100644 --- a/garden-service/src/logger/renderers.ts +++ b/garden-service/src/logger/renderers.ts @@ -152,12 +152,15 @@ export function renderMsg(entry: LogEntry): string { } export function renderData(entry: LogEntry): string { - const { data } = entry.getMessageState() + const { data, dataFormat } = entry.getMessageState() if (!data) { return "" } - const asYaml = yaml.safeDump(data, { noRefs: true, skipInvalid: true }) - return highlightYaml(asYaml) + if (!dataFormat || dataFormat === "yaml") { + const asYaml = yaml.safeDump(data, { noRefs: true, skipInvalid: true }) + return highlightYaml(asYaml) + } + return JSON.stringify(data, null, 2) } export function renderSection(entry: LogEntry): string { diff --git a/garden-service/test/unit/src/logger/log-entry.ts b/garden-service/test/unit/src/logger/log-entry.ts index 556cfe1143..e2a03302c2 100644 --- a/garden-service/test/unit/src/logger/log-entry.ts +++ b/garden-service/test/unit/src/logger/log-entry.ts @@ -66,6 +66,7 @@ describe("LogEntry", () => { symbol: undefined, status: undefined, data: undefined, + dataFormat: undefined, append: undefined, maxSectionWidth: undefined, } @@ -86,6 +87,7 @@ describe("LogEntry", () => { symbol: "info", status: "done", data: { some: "data" }, + dataFormat: "json", metadata: { task: taskMetadata }, maxSectionWidth: 8, }) @@ -98,6 +100,7 @@ describe("LogEntry", () => { symbol: "info", status: "done", data: { some: "data" }, + dataFormat: "json", append: undefined, timestamp, maxSectionWidth: 8, @@ -126,6 +129,7 @@ describe("LogEntry", () => { symbol: "info", status: "done", data: { some: "data" }, + dataFormat: undefined, append: undefined, timestamp, maxSectionWidth: 0, @@ -162,6 +166,7 @@ describe("LogEntry", () => { symbol: "info", status: "done", data: { some: "data" }, + dataFormat: undefined, append: undefined, timestamp, maxSectionWidth: 8, @@ -173,6 +178,7 @@ describe("LogEntry", () => { symbol: "info", status: "done", data: { some: "data_updated" }, + dataFormat: undefined, append: undefined, timestamp, maxSectionWidth: 10, @@ -184,6 +190,7 @@ describe("LogEntry", () => { symbol: "info", status: "done", data: { some: "data_updated" }, + dataFormat: undefined, append: undefined, timestamp, maxSectionWidth: 0, diff --git a/garden-service/test/unit/src/logger/renderers.ts b/garden-service/test/unit/src/logger/renderers.ts index b75aaef3db..38bd6cdc97 100644 --- a/garden-service/test/unit/src/logger/renderers.ts +++ b/garden-service/test/unit/src/logger/renderers.ts @@ -11,12 +11,15 @@ import { formatForJson, renderSection, MAX_SECTION_WIDTH, + renderData, } from "../../../../src/logger/renderers" import { GardenError } from "../../../../src/exceptions" import dedent = require("dedent") import { TaskMetadata } from "../../../../src/logger/log-entry" import logSymbols = require("log-symbols") import stripAnsi = require("strip-ansi") +import yaml from "js-yaml" +import { highlightYaml } from "../../../../src/util/util" const logger: any = getLogger() @@ -234,4 +237,35 @@ describe("renderers", () => { }) }) }) + describe.only("renderData", () => { + const sampleData = { + key: "value", + key2: { + value: [ + { + key1: "value", + key2: 3, + }, + ], + }, + } + it("should render an empty string when no data is passed", () => { + const entry = logger.placeholder() + expect(renderData(entry)).to.eql("") + }) + it("should render yaml by default if data is passed", () => { + const entry = logger.info({ data: sampleData }) + const dataAsYaml = yaml.safeDump(sampleData, { noRefs: true, skipInvalid: true }) + expect(renderData(entry)).to.eql(highlightYaml(dataAsYaml)) + }) + it('should render yaml if dataFormat is "yaml"', () => { + const entry = logger.info({ data: sampleData, dataFormat: "yaml" }) + const dataAsYaml = yaml.safeDump(sampleData, { noRefs: true, skipInvalid: true }) + expect(renderData(entry)).to.eql(highlightYaml(dataAsYaml)) + }) + it('should render json if dataFormat is "json"', () => { + const entry = logger.info({ data: sampleData, dataFormat: "json" }) + expect(renderData(entry)).to.eql(JSON.stringify(sampleData, null, 2)) + }) + }) })