-
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.
feat(commitlint-config): add junit formatter
Old package was deprecated so we are adding a new one forked into the repo
- Loading branch information
Showing
3 changed files
with
175 additions
and
0 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
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,159 @@ | ||
// @ts-check | ||
/** | ||
* Forked from archived repo - https://github.com/byCedric/Commitlint-Formats/blob/develop/packages/junit/src/junit.js | ||
*/ | ||
|
||
/** | ||
* Indent the message with an indentation level. | ||
* This will add tabs based on this level. | ||
* | ||
* @param {number} level | ||
* @param {string} line | ||
* @return {string} | ||
*/ | ||
function indent(level, line) { | ||
return `${' '.repeat(level)}${line}`; | ||
} | ||
|
||
/** | ||
* Escape a string to make it xml safe. | ||
* | ||
* @param {string | number} text | ||
* @return {string} | ||
*/ | ||
function escape(text) { | ||
const characters = { | ||
'<': '<', | ||
'>': '>', | ||
'&': '&', | ||
"'": ''', | ||
'"': '"', | ||
}; | ||
|
||
return String(text).replace(/[<>&'"]/g, (char) => characters[char]); | ||
} | ||
|
||
/** | ||
* @typedef {Object} CreateElementOptions | ||
* @property {number} [indent] | ||
* @property {boolean} [selfClosing] | ||
* @property {boolean} [noNewline] | ||
*/ | ||
|
||
/** | ||
* Create a new XML element containing various properties. | ||
* It can be configured to automatically add a newline, indentation and make it self closing. | ||
* | ||
* @param {string} tag | ||
* @param {CreateElementOptions} options | ||
* @param {Object} attributes | ||
* @return {string} | ||
*/ | ||
function createElement(tag, options, attributes) { | ||
const element = `<${tag}`; | ||
const closing = options.selfClosing ? ' />' : '>'; | ||
const ending = options.noNewline ? '' : '\n'; | ||
const properties = Object.keys(attributes) | ||
.map((key) => `${key}="${escape(attributes[key])}"`) | ||
.join(' '); | ||
|
||
return indent( | ||
options.indent || 0, | ||
`${element} ${properties}${closing}${ending}`, | ||
); | ||
} | ||
|
||
/** | ||
* Format the commitlint report as a valid JUnit XML report. | ||
* | ||
* @param {import('@commitlint/types').FormattableReport} report | ||
* @return {string} | ||
*/ | ||
function formatJunit(report = {}) { | ||
let output = ''; | ||
|
||
output += indent(0, '<?xml version="1.0" encoding="utf-8"?>\n'); | ||
output += indent(0, '<testsuites>\n'); | ||
|
||
const { results = [] } = report; | ||
|
||
const { errorCount, warningCount, testsCount } = results.reduce( | ||
(carry, result) => | ||
result.input | ||
? carry | ||
: { | ||
errorCount: carry.errorCount + (result.errors?.length || 0), | ||
warningCount: carry.warningCount + (result.warnings?.length || 0), | ||
testsCount: | ||
carry.testsCount + | ||
(result.errors?.length || 0) + | ||
(result.warnings?.length || 0), | ||
}, | ||
{ errorCount: 0, warningCount: 0, testsCount: 0 }, | ||
); | ||
|
||
output += createElement( | ||
'testsuite', | ||
{ indent: 1 }, | ||
{ | ||
name: 'commitlint', | ||
errors: 0, | ||
failures: errorCount + warningCount, | ||
tests: testsCount, | ||
}, | ||
); | ||
|
||
results.forEach((result) => { | ||
if (!result.input) return; | ||
const issues = [].concat(result.errors || [], result.warnings || []); | ||
|
||
output += createElement( | ||
'testsuite', | ||
{ indent: 2 }, | ||
{ | ||
name: result.input.split('\n')[0], | ||
errors: 0, | ||
failures: issues.length, | ||
tests: issues.length || 1, | ||
}, | ||
); | ||
|
||
if (issues.length > 0) { | ||
issues.forEach((issue) => { | ||
const type = issue.level === 2 ? 'error' : 'warning'; | ||
|
||
output += createElement( | ||
'testcase', | ||
{ indent: 3 }, | ||
{ name: issue.name }, | ||
); | ||
output += createElement( | ||
'failure', | ||
{ indent: 4, noNewline: true }, | ||
{ type }, | ||
); | ||
output += '<![CDATA['; | ||
output += `${issue.message} (${issue.name})\n`; | ||
output += ']]>'; | ||
output += '</failure>\n'; | ||
output += indent(3, '</testcase>\n'); | ||
}); | ||
|
||
output += indent(2, '</testsuite>\n'); | ||
} else { | ||
output += createElement( | ||
'testcase', | ||
{ indent: 3, selfClosing: true }, | ||
{ name: 'valid' }, | ||
); | ||
output += indent(2, '</testsuite>\n'); | ||
} | ||
}); | ||
|
||
output += indent(1, '</testsuite>\n'); | ||
output += indent(0, '</testsuites>\n'); | ||
|
||
return output; | ||
} | ||
|
||
module.exports = formatJunit; |
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 |
---|---|---|
|
@@ -7,8 +7,16 @@ | |
"type": "git", | ||
"url": "[email protected]:tablecheck/frontend.git" | ||
}, | ||
"files": [ | ||
"index.js", | ||
"formatters" | ||
], | ||
"version": "1.2.0", | ||
"main": "index.js", | ||
"exports": { | ||
".": "./index.js", | ||
"./formatters/junit": "./formatters/junit.js" | ||
}, | ||
"dependencies": { | ||
"@commitlint/config-conventional": "^17" | ||
}, | ||
|