Skip to content

Commit 28b7f63

Browse files
committed
lib: add suggestions on invalid subsystems
When an invalid subsystem is encountered, attempt to make a suggestion based on the nearest match (if any) from the valid subsystems.
1 parent 38d97b9 commit 28b7f63

File tree

5 files changed

+61
-3
lines changed

5 files changed

+61
-3
lines changed

lib/format-pretty.js

+7-2
Original file line numberDiff line numberDiff line change
@@ -74,13 +74,18 @@ function formatMessage(msg) {
7474
const pad = utils.rightPad(`${l}:${col}`, MAX_LINE_COL_LEN)
7575
const line = chalk.grey(pad)
7676
const id = formatId(msg.id)
77-
const m = msg.message
7877
const icon = msg.level === 'fail'
7978
? utils.X
8079
: msg.level === 'warn'
8180
? utils.WARN
8281
: utils.CHECK
83-
return ` ${icon} ${line} ${utils.rightPad(m, 40)} ${id}`
82+
const msg_lines = msg.message.split('\n')
83+
let formatted =
84+
[ ` ${icon} ${line} ${utils.rightPad(msg_lines[0], 40)} ${id}` ]
85+
for (const msg_line of msg_lines.slice(1)) {
86+
formatted.push(`${' '.repeat(17)}${msg_line}`)
87+
}
88+
return formatted.join('\n')
8489
}
8590

8691
function formatId(id) {

lib/rules/subsystem.js

+8-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
'use strict'
22

3+
const FuzzySet = require('fuzzyset.js')
4+
35
const id = 'subsystem'
46

57
const validSubsystems = [
@@ -111,11 +113,16 @@ module.exports = {
111113
for (const sub of parsed.subsystems) {
112114
if (!~subs.indexOf(sub)) {
113115
failed = true
116+
let suggestion = ''
117+
const suggestions = new FuzzySet(subs).get(sub)
118+
if (suggestions) {
119+
suggestion = `\nDid you mean "${suggestions[0][1]}"?`
120+
}
114121
// invalid subsystem
115122
const column = parsed.title.indexOf(sub)
116123
context.report({
117124
id: id
118-
, message: `Invalid subsystem: "${sub}"`
125+
, message: `Invalid subsystem: "${sub}"${suggestion}`
119126
, string: parsed.title
120127
, line: 0
121128
, column: column

package-lock.json

+5
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
},
1111
"dependencies": {
1212
"chalk": "~1.1.1",
13+
"fuzzyset.js": "^0.0.8",
1314
"gitlint-parser-node": "^1.1.0",
1415
"help": "^2.1.3",
1516
"nopt": "^3.0.6"

test/rules/subsystem.js

+40
Original file line numberDiff line numberDiff line change
@@ -88,5 +88,45 @@ test('rule: subsystem', (t) => {
8888

8989
Rule.validate(context, {options: {subsystems: Rule.defaults.subsystems}})
9090
})
91+
92+
const suggestionTests = [
93+
[ 'docs', 'doc' ]
94+
, [ 'error', 'errors' ]
95+
, [ 'napi', 'n-api' ]
96+
, [ 'perfhooks', 'perf_hooks' ]
97+
, [ 'worker_threads', 'worker' ]
98+
, [ 'V8', 'v8' ]
99+
]
100+
for (const [sub, suggestion] of suggestionTests) {
101+
t.test(`suggestion "${sub}" -> "${suggestion}"`, (tt) => {
102+
tt.plan(7)
103+
const title = `${sub}: come on`
104+
const v = new Validator()
105+
const context = new Commit({
106+
sha: 'e7c077c610afa371430180fbd447bfef60ebc5ea'
107+
, author: {
108+
name: 'Evan Lucas'
109+
, email: '[email protected]'
110+
, date: '2016-04-12T19:42:23Z'
111+
}
112+
, message: title
113+
}, v)
114+
115+
context.report = (opts) => {
116+
tt.pass('called report')
117+
tt.equal(opts.id, 'subsystem', 'id')
118+
tt.equal(opts.message
119+
, `Invalid subsystem: "${sub}"\nDid you mean "${suggestion}"?`
120+
, 'message')
121+
tt.equal(opts.string, title, 'string')
122+
tt.equal(opts.line, 0, 'line')
123+
tt.equal(opts.column, 0, 'column')
124+
tt.equal(opts.level, 'fail', 'level')
125+
tt.end()
126+
}
127+
128+
Rule.validate(context, {options: {subsystems: Rule.defaults.subsystems}})
129+
})
130+
}
91131
t.end()
92132
})

0 commit comments

Comments
 (0)