UNPKG

@atomist/sdm

Version:

Atomist Software Delivery Machine SDK

88 lines 3.65 kB
"use strict"; /* * Copyright © 2020 Atomist, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ Object.defineProperty(exports, "__esModule", { value: true }); exports.NpmLogInterpreter = void 0; const logger_1 = require("@atomist/automation-client/lib/util/logger"); const strip_ansi_1 = require("strip-ansi"); const NpmLogInterpreter = log => { if (!log) { return undefined; } const lines = removeBlanksFromEnd(removeNpmFooter(log.split("\n").map(strip_ansi_1.default).map(stripLogPrefix))); const defaultMessage = lastOccurrenceOf(/^ERROR:/, lines) || "Error"; const defaultLines = lines.slice(-15); const recognizedInterpretation = recognizeMochaTest(lines) || recognizeNpmRunError(lines) || {}; const relevantLines = recognizedInterpretation.relevantLines || defaultLines; return { message: recognizedInterpretation.message || defaultMessage, relevantPart: "```\n" + relevantLines.join("\n") + "\n```", }; }; exports.NpmLogInterpreter = NpmLogInterpreter; const LogPrefix = /^.*\[(info |error|warn |debug)\] /; const NpmFooterPrefix = /^npm ERR!/; const StackTraceLine = /^\W*at /; const BeginMochaFailingTests = /^\W*\d* failing$/; function recognizeNpmRunError(lines) { const reversedLines = lines.slice().reverse(); const lastBreakBeforeCommand = findTwoBlankLinesIndex(reversedLines); if (lastBreakBeforeCommand < 0) { return undefined; } return { relevantLines: lines.slice(-Math.min(lastBreakBeforeCommand, 20)) }; } function recognizeMochaTest(lines) { const begin = lines.findIndex(s => BeginMochaFailingTests.test(s)); if (begin < 0) { logger_1.logger.debug("No mocha test detected"); return undefined; } logger_1.logger.debug("Mocha test detected, beginning at %d: %s", begin, lines[begin]); const fromBeginning = lines.slice(begin); const end = findTwoBlankLinesIndex(fromBeginning) || fromBeginning.length; const fromFailingCountToTwoBlankLines = fromBeginning.slice(0, end); return { message: "Tests: " + lines[begin].trim(), relevantLines: fromFailingCountToTwoBlankLines.filter(s => !StackTraceLine.test(s)), }; } function stripLogPrefix(line) { return line.replace(LogPrefix, ""); } function removeNpmFooter(lines) { const npmErr = "npm ERR! This is probably not a problem with npm. There is likely additional logging output above."; if (lines.includes(npmErr)) { logger_1.logger.info("Filtering npm error footer"); return lines.filter(s => !NpmFooterPrefix.test(s)); } return lines; } function findTwoBlankLinesIndex(lines) { return lines.findIndex((s, i) => s === "" && lines[i + 1] === ""); } function lastOccurrenceOf(re, lines) { const reversedLines = lines.slice().reverse(); // is there a better way tto make a copy? reverse() is in-place. >:-( return reversedLines.find(s => re.test(s)); } function removeBlanksFromEnd(lines) { let w = lines.length - 1; while (lines[w].trim() === "") { w--; } return lines.slice(0, w + 1); } //# sourceMappingURL=npmLogInterpreter.js.map