-
Notifications
You must be signed in to change notification settings - Fork 132
/
Copy pathdirective.ts
93 lines (81 loc) · 1.99 KB
/
directive.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
const DIRECTIVE_TYPES = ['enable', 'disable', 'source', 'source-path', 'shell'] as const
type DirectiveType = (typeof DIRECTIVE_TYPES)[number]
type Directive =
| {
type: 'enable'
rules: string[]
}
| {
type: 'disable'
rules: string[]
}
| {
type: 'source'
path: string
}
| {
type: 'source-path'
path: string
}
| {
type: 'shell'
shell: string
}
const DIRECTIVE_REG_EXP = /^(#\s*shellcheck\s+)([^#]*)/
export function parseShellCheckDirective(line: string): Directive[] {
const match = line.match(DIRECTIVE_REG_EXP)
if (!match) {
return []
}
const commands = match[2]
.split(' ')
.map((command) => command.trim())
.filter((command) => command !== '')
const directives: Directive[] = []
for (const command of commands) {
const [typeKey, directiveValue] = command.split('=')
const type = DIRECTIVE_TYPES.includes(typeKey as any)
? (typeKey as DirectiveType)
: null
if (!type || !directiveValue) {
continue
}
if (type === 'source-path' || type === 'source') {
directives.push({
type,
path: directiveValue,
})
} else if (type === 'shell') {
directives.push({
type,
shell: directiveValue,
})
continue
} else if (type === 'enable' || type === 'disable') {
const rules = []
for (const arg of directiveValue.split(',')) {
const ruleRangeMatch = arg.match(/^SC(\d*)-SC(\d*)$/)
if (ruleRangeMatch) {
for (
let i = parseInt(ruleRangeMatch[1], 10);
i <= parseInt(ruleRangeMatch[2], 10);
i++
) {
rules.push(`SC${i}`)
}
} else {
arg
.split(',')
.map((arg) => arg.trim())
.filter((arg) => arg !== '')
.forEach((arg) => rules.push(arg))
}
}
directives.push({
type,
rules,
})
}
}
return directives
}