From 1a23c67b2d78c03440ccf405ac99caebf28a04b9 Mon Sep 17 00:00:00 2001 From: Titus Wormer Date: Sun, 7 Apr 2024 17:52:39 +0200 Subject: [PATCH] Fix to show vfile message causes nicely --- lib/index.js | 36 ++++++++++++++++++++++++++++-------- test.js | 19 +++++++++++++++++++ 2 files changed, 47 insertions(+), 8 deletions(-) diff --git a/lib/index.js b/lib/index.js index 217a4c4..1e9f7af 100644 --- a/lib/index.js +++ b/lib/index.js @@ -236,10 +236,11 @@ function createByline(state, stats) { * Info passed around. * @param {unknown} cause * Cause. - * @returns {Array} + * @returns {Array | string>} * Lines. */ function createCauseLines(state, cause) { + /** @type {Array | string>} */ const lines = [' ' + state.bold + '[cause]' + state.normalIntensity + ':'] let foundReasonableCause = false @@ -250,15 +251,34 @@ function createCauseLines(state, cause) { if (typeof stackValue === 'string') { foundReasonableCause = true + /** @type {Array | string>} */ + let causeLines + + // Looks like a message. + if ('file' in cause && 'fatal' in cause) { + causeLines = createMessageLine( + state, + /** @type {VFileMessage} */ (cause) + ) + } + // Regular error. + else { + causeLines = stackValue.split(eol) - const stackLines = stackValue.split(eol) - stackLines[0] = ' ' + stackLines[0] - - lines.push(...stackLines) + // Recurse. + if ('cause' in cause && cause.cause) { + causeLines.push(...createCauseLines(state, cause.cause)) + } + } - if ('cause' in cause && cause.cause) { - lines.push(...createCauseLines(state, cause.cause)) + const head = causeLines[0] + if (typeof head === 'string') { + causeLines[0] = ' ' + head + } else { + head[0] = ' ' + head[0] } + + lines.push(...causeLines) } } @@ -345,7 +365,7 @@ function createMessageLine(state, message) { let reason = message.stack || message.message const match = eol.exec(reason) - /** @type {Array} */ + /** @type {Array | string>} */ let rest = [] if (match) { diff --git a/test.js b/test.js index 65fd57d..59d6f57 100644 --- a/test.js +++ b/test.js @@ -10,6 +10,7 @@ import assert from 'node:assert/strict' import test from 'node:test' import strip from 'strip-ansi' import {VFile} from 'vfile' +import {VFileMessage} from 'vfile-message' import {reporter} from 'vfile-reporter' /* eslint-disable no-undef */ @@ -441,6 +442,24 @@ test('reporter', async function () { 'should support a `message.cause`, w/ another cause' ) + file = new VFile() + + file.message('Something failed terribly', { + cause: new VFileMessage('Boom!', {ruleId: 'foo', source: 'bar'}) + }) + + assert.equal( + strip(reporter(file)), + [ + ' warning Something failed terribly', + ' [cause]:', + ' info Boom! foo bar', + '', + '⚠ 1 warning' + ].join('\n'), + 'should support a `message.cause` w/ a message' + ) + file = new VFile() let message = file.message('Something failed terribly') message.cause = 'Boom!'