forked from protofire/solhint
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- copied the current version of eslint formatters into our codebase since they're no longer accesible from importing the `eslint` package (see discussions in protofire#380) for details - only imported those already supported, there are many other eslint formatters in the current eslint version (8.32.0) than there were in the one we were using previously (5.6.0) - table formatter was dropped by the latest version of eslint, so I fetched it from 5.6.0 instead - while building this commit I realized it was possible to remove a formatter entirely and all existing tests would pass, so I created an issue for discussing that - made eslint a dev dependency to reduce install size, since it's only used for linting this codebase. - added some dependencies of the eslint formatters. Used 'old' strip-ansi version 6.0.1 which seems to still be maintained instead of 7.0.1 since from version 7 onwards it's a pure ESM package
- Loading branch information
1 parent
4c4f127
commit 6beb38f
Showing
7 changed files
with
597 additions
and
51 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
/** | ||
* @fileoverview Stylish reporter | ||
* @author Sindre Sorhus | ||
*/ | ||
"use strict"; | ||
|
||
const chalk = require("chalk"), | ||
stripAnsi = require("strip-ansi"), | ||
table = require("text-table"); | ||
|
||
//------------------------------------------------------------------------------ | ||
// Helpers | ||
//------------------------------------------------------------------------------ | ||
|
||
/** | ||
* Given a word and a count, append an s if count is not one. | ||
* @param {string} word A word in its singular form. | ||
* @param {int} count A number controlling whether word should be pluralized. | ||
* @returns {string} The original word with an s on the end if count is not one. | ||
*/ | ||
function pluralize(word, count) { | ||
return (count === 1 ? word : `${word}s`); | ||
} | ||
|
||
//------------------------------------------------------------------------------ | ||
// Public Interface | ||
//------------------------------------------------------------------------------ | ||
|
||
module.exports = function(results) { | ||
|
||
let output = "\n", | ||
errorCount = 0, | ||
warningCount = 0, | ||
fixableErrorCount = 0, | ||
fixableWarningCount = 0, | ||
summaryColor = "yellow"; | ||
|
||
results.forEach(result => { | ||
const messages = result.messages; | ||
|
||
if (messages.length === 0) { | ||
return; | ||
} | ||
|
||
errorCount += result.errorCount; | ||
warningCount += result.warningCount; | ||
fixableErrorCount += result.fixableErrorCount; | ||
fixableWarningCount += result.fixableWarningCount; | ||
|
||
output += `${chalk.underline(result.filePath)}\n`; | ||
|
||
output += `${table( | ||
messages.map(message => { | ||
let messageType; | ||
if (message.fatal || message.severity === 2) { | ||
messageType = chalk.red("error"); | ||
summaryColor = "red"; | ||
} else { | ||
messageType = chalk.yellow("warning"); | ||
} | ||
return [ | ||
"", | ||
message.line || 0, | ||
message.column || 0, | ||
messageType, | ||
message.message.replace(/([^ ])\.$/u, "$1"), | ||
chalk.dim(message.ruleId || "") | ||
]; | ||
}), | ||
{ | ||
align: ["", "r", "l"], | ||
stringLength(str) { | ||
return stripAnsi(str).length; | ||
} | ||
} | ||
).split("\n").map(el => el.replace(/(\d+)\s+(\d+)/u, (m, p1, p2) => chalk.dim(`${p1}:${p2}`))).join("\n")}\n\n`; | ||
}); | ||
|
||
const total = errorCount + warningCount; | ||
|
||
if (total > 0) { | ||
output += chalk[summaryColor].bold([ | ||
"\u2716 ", total, pluralize(" problem", total), | ||
" (", errorCount, pluralize(" error", errorCount), ", ", | ||
warningCount, pluralize(" warning", warningCount), ")\n" | ||
].join("")); | ||
|
||
if (fixableErrorCount > 0 || fixableWarningCount > 0) { | ||
output += chalk[summaryColor].bold([ | ||
" ", fixableErrorCount, pluralize(" error", fixableErrorCount), " and ", | ||
fixableWarningCount, pluralize(" warning", fixableWarningCount), | ||
" potentially fixable with the `--fix` option.\n" | ||
].join("")); | ||
} | ||
} | ||
|
||
// Resets output color, for prevent change on top level | ||
return total > 0 ? chalk.reset(output) : ""; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,150 @@ | ||
/** | ||
* @fileoverview "table reporter. | ||
* @author Gajus Kuizinas <[email protected]> | ||
*/ | ||
"use strict"; | ||
|
||
//------------------------------------------------------------------------------ | ||
// Requirements | ||
//------------------------------------------------------------------------------ | ||
|
||
const chalk = require("chalk"), | ||
table = require("table").table, | ||
pluralize = require("pluralize"); | ||
|
||
//------------------------------------------------------------------------------ | ||
// Helpers | ||
//------------------------------------------------------------------------------ | ||
|
||
/** | ||
* Draws text table. | ||
* @param {Array<Object>} messages Error messages relating to a specific file. | ||
* @returns {string} A text table. | ||
*/ | ||
function drawTable(messages) { | ||
const rows = []; | ||
|
||
if (messages.length === 0) { | ||
return ""; | ||
} | ||
|
||
rows.push([ | ||
chalk.bold("Line"), | ||
chalk.bold("Column"), | ||
chalk.bold("Type"), | ||
chalk.bold("Message"), | ||
chalk.bold("Rule ID") | ||
]); | ||
|
||
messages.forEach(message => { | ||
let messageType; | ||
|
||
if (message.fatal || message.severity === 2) { | ||
messageType = chalk.red("error"); | ||
} else { | ||
messageType = chalk.yellow("warning"); | ||
} | ||
|
||
rows.push([ | ||
message.line || 0, | ||
message.column || 0, | ||
messageType, | ||
message.message, | ||
message.ruleId || "" | ||
]); | ||
}); | ||
|
||
return table(rows, { | ||
columns: { | ||
0: { | ||
width: 8, | ||
wrapWord: true | ||
}, | ||
1: { | ||
width: 8, | ||
wrapWord: true | ||
}, | ||
2: { | ||
width: 8, | ||
wrapWord: true | ||
}, | ||
3: { | ||
paddingRight: 5, | ||
width: 50, | ||
wrapWord: true | ||
}, | ||
4: { | ||
width: 20, | ||
wrapWord: true | ||
} | ||
}, | ||
drawHorizontalLine(index) { | ||
return index === 1; | ||
} | ||
}); | ||
} | ||
|
||
/** | ||
* Draws a report (multiple tables). | ||
* @param {Array} results Report results for every file. | ||
* @returns {string} A column of text tables. | ||
*/ | ||
function drawReport(results) { | ||
let files; | ||
|
||
files = results.map(result => { | ||
if (!result.messages.length) { | ||
return ""; | ||
} | ||
|
||
return `\n${result.filePath}\n\n${drawTable(result.messages)}`; | ||
}); | ||
|
||
files = files.filter(content => content.trim()); | ||
|
||
return files.join(""); | ||
} | ||
|
||
//------------------------------------------------------------------------------ | ||
// Public Interface | ||
//------------------------------------------------------------------------------ | ||
|
||
module.exports = function(report) { | ||
let result, | ||
errorCount, | ||
warningCount; | ||
|
||
result = ""; | ||
errorCount = 0; | ||
warningCount = 0; | ||
|
||
report.forEach(fileReport => { | ||
errorCount += fileReport.errorCount; | ||
warningCount += fileReport.warningCount; | ||
}); | ||
|
||
if (errorCount || warningCount) { | ||
result = drawReport(report); | ||
} | ||
|
||
result += `\n${table([ | ||
[ | ||
chalk.red(pluralize("Error", errorCount, true)) | ||
], | ||
[ | ||
chalk.yellow(pluralize("Warning", warningCount, true)) | ||
] | ||
], { | ||
columns: { | ||
0: { | ||
width: 110, | ||
wrapWord: true | ||
} | ||
}, | ||
drawHorizontalLine() { | ||
return true; | ||
} | ||
})}`; | ||
|
||
return result; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
/** | ||
* @fileoverview TAP reporter | ||
* @author Jonathan Kingston | ||
*/ | ||
"use strict"; | ||
|
||
const yaml = require("js-yaml"); | ||
|
||
//------------------------------------------------------------------------------ | ||
// Helper Functions | ||
//------------------------------------------------------------------------------ | ||
|
||
/** | ||
* Returns a canonical error level string based upon the error message passed in. | ||
* @param {Object} message Individual error message provided by eslint | ||
* @returns {string} Error level string | ||
*/ | ||
function getMessageType(message) { | ||
if (message.fatal || message.severity === 2) { | ||
return "error"; | ||
} | ||
return "warning"; | ||
} | ||
|
||
/** | ||
* Takes in a JavaScript object and outputs a TAP diagnostics string | ||
* @param {Object} diagnostic JavaScript object to be embedded as YAML into output. | ||
* @returns {string} diagnostics string with YAML embedded - TAP version 13 compliant | ||
*/ | ||
function outputDiagnostics(diagnostic) { | ||
const prefix = " "; | ||
let output = `${prefix}---\n`; | ||
|
||
output += prefix + yaml.dump(diagnostic).split("\n").join(`\n${prefix}`); | ||
output += "...\n"; | ||
return output; | ||
} | ||
|
||
//------------------------------------------------------------------------------ | ||
// Public Interface | ||
//------------------------------------------------------------------------------ | ||
|
||
module.exports = function(results) { | ||
let output = `TAP version 13\n1..${results.length}\n`; | ||
|
||
results.forEach((result, id) => { | ||
const messages = result.messages; | ||
let testResult = "ok"; | ||
let diagnostics = {}; | ||
|
||
if (messages.length > 0) { | ||
messages.forEach(message => { | ||
const severity = getMessageType(message); | ||
const diagnostic = { | ||
message: message.message, | ||
severity, | ||
data: { | ||
line: message.line || 0, | ||
column: message.column || 0, | ||
ruleId: message.ruleId || "" | ||
} | ||
}; | ||
|
||
// This ensures a warning message is not flagged as error | ||
if (severity === "error") { | ||
testResult = "not ok"; | ||
} | ||
|
||
/* | ||
* If we have multiple messages place them under a messages key | ||
* The first error will be logged as message key | ||
* This is to adhere to TAP 13 loosely defined specification of having a message key | ||
*/ | ||
if ("message" in diagnostics) { | ||
if (typeof diagnostics.messages === "undefined") { | ||
diagnostics.messages = []; | ||
} | ||
diagnostics.messages.push(diagnostic); | ||
} else { | ||
diagnostics = diagnostic; | ||
} | ||
}); | ||
} | ||
|
||
output += `${testResult} ${id + 1} - ${result.filePath}\n`; | ||
|
||
// If we have an error include diagnostics | ||
if (messages.length > 0) { | ||
output += outputDiagnostics(diagnostics); | ||
} | ||
|
||
}); | ||
|
||
return output; | ||
}; |
Oops, something went wrong.