1use crate::Severity;
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
4pub enum Category {
5 Correctness,
6 Style,
7 Performance,
8 Portability,
9 Security,
10}
11
12impl Category {
13 pub const fn prefix(self) -> &'static str {
14 match self {
15 Self::Correctness => "C",
16 Self::Style => "S",
17 Self::Performance => "P",
18 Self::Portability => "X",
19 Self::Security => "K",
20 }
21 }
22
23 pub fn from_prefix(prefix: &str) -> Option<Self> {
24 match prefix {
25 "C" => Some(Self::Correctness),
26 "S" => Some(Self::Style),
27 "P" => Some(Self::Performance),
28 "X" => Some(Self::Portability),
29 "K" => Some(Self::Security),
30 _ => None,
31 }
32 }
33}
34
35macro_rules! declare_rules {
36 (@sub $name:ident) => {
37 ()
38 };
39 (@count $($name:ident),+ $(,)?) => {
40 <[()]>::len(&[$(declare_rules!(@sub $name)),+])
41 };
42 ($(
43 ($code:literal, $category:expr, $severity:expr, $name:ident),
44 )+) => {
45 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
46 #[repr(u16)]
47 pub enum Rule {
48 $($name,)*
49 }
50
51 pub const ALL_RULES: [Rule; declare_rules!(@count $($name),+)] = [
52 $(Rule::$name,)*
53 ];
54
55 impl Rule {
56 pub const COUNT: usize = ALL_RULES.len();
57
58 pub fn iter() -> impl ExactSizeIterator<Item = Self> + DoubleEndedIterator + Clone {
59 ALL_RULES.into_iter()
60 }
61
62 pub const fn code(self) -> &'static str {
63 match self {
64 $(Self::$name => $code,)*
65 }
66 }
67
68 pub const fn category(self) -> Category {
69 match self {
70 $(Self::$name => $category,)*
71 }
72 }
73
74 pub const fn default_severity(self) -> Severity {
75 match self {
76 $(Self::$name => $severity,)*
77 }
78 }
79 }
80
81 fn canonical_code_to_rule(code: &str) -> Option<Rule> {
82 match code {
83 $($code => Some(Rule::$name),)*
84 _ => None,
85 }
86 }
87 };
88}
89
90declare_rules! {
91 ("C001", Category::Correctness, Severity::Warning, UnusedAssignment),
92 ("C002", Category::Correctness, Severity::Warning, DynamicSourcePath),
93 ("C003", Category::Correctness, Severity::Warning, UntrackedSourceFile),
94 ("C004", Category::Correctness, Severity::Warning, UncheckedDirectoryChange),
95 ("C005", Category::Correctness, Severity::Warning, SingleQuotedLiteral),
96 ("C006", Category::Correctness, Severity::Error, UndefinedVariable),
97 ("C007", Category::Correctness, Severity::Warning, FindOutputToXargs),
98 ("C008", Category::Correctness, Severity::Warning, TrapStringExpansion),
99 ("C009", Category::Correctness, Severity::Warning, QuotedBashRegex),
100 ("C010", Category::Correctness, Severity::Warning, ChainedTestBranches),
101 ("C011", Category::Correctness, Severity::Warning, LineOrientedInput),
102 ("C012", Category::Correctness, Severity::Warning, LeadingGlobArgument),
103 ("C013", Category::Correctness, Severity::Warning, FindOutputLoop),
104 ("C014", Category::Correctness, Severity::Error, LocalTopLevel),
105 ("C015", Category::Correctness, Severity::Warning, SudoRedirectionOrder),
106 ("C016", Category::Correctness, Severity::Error, StrayClosingKeyword),
107 ("C017", Category::Correctness, Severity::Warning, ConstantComparisonTest),
108 ("C018", Category::Correctness, Severity::Error, LoopControlOutsideLoop),
109 ("C019", Category::Correctness, Severity::Warning, LiteralUnaryStringTest),
110 ("C020", Category::Correctness, Severity::Warning, TruthyLiteralTest),
111 ("C021", Category::Correctness, Severity::Warning, ConstantCaseSubject),
112 ("C022", Category::Correctness, Severity::Error, EmptyTest),
113 ("C023", Category::Correctness, Severity::Error, LeadingZeroArithmetic),
114 ("C024", Category::Correctness, Severity::Warning, AssignmentSpacing),
115 ("C030", Category::Correctness, Severity::Error, MissingBracketSpace),
116 ("C031", Category::Correctness, Severity::Error, MissingSpaceBeforeBracketClose),
117 ("C032", Category::Correctness, Severity::Error, JammedTestBracket),
118 ("C033", Category::Correctness, Severity::Error, IndentedHeredocClose),
119 ("C025", Category::Correctness, Severity::Warning, PositionalTenBraces),
120 ("C027", Category::Correctness, Severity::Warning, BareDoneWord),
121 ("C034", Category::Correctness, Severity::Error, UnterminatedIf),
122 ("C035", Category::Correctness, Severity::Error, MissingFi),
123 ("C036", Category::Correctness, Severity::Error, BrokenTestEnd),
124 ("C037", Category::Correctness, Severity::Error, BrokenTestParse),
125 ("C038", Category::Correctness, Severity::Error, ElseIf),
126 ("C039", Category::Correctness, Severity::Warning, OpenDoubleQuote),
127 ("C040", Category::Correctness, Severity::Error, LinebreakInTest),
128 ("C041", Category::Correctness, Severity::Error, CStyleComment),
129 ("C042", Category::Correctness, Severity::Warning, CPrototypeFragment),
130 ("C043", Category::Correctness, Severity::Warning, BadRedirectionFdOrder),
131 ("C044", Category::Correctness, Severity::Warning, BareGlobCommandPath),
132 ("C045", Category::Correctness, Severity::Warning, DiffMarkerLine),
133 ("C046", Category::Correctness, Severity::Warning, PipeToKill),
134 ("C047", Category::Correctness, Severity::Error, InvalidExitStatus),
135 ("C048", Category::Correctness, Severity::Warning, CasePatternVar),
136 ("C049", Category::Correctness, Severity::Warning, TautologyChain),
137 ("C050", Category::Correctness, Severity::Warning, ArithmeticRedirectionTarget),
138 ("C051", Category::Correctness, Severity::Error, DuplicateRedirect),
139 ("C052", Category::Correctness, Severity::Error, AssignSpecialZero),
140 ("C053", Category::Correctness, Severity::Warning, SpaceyAssign),
141 ("C054", Category::Correctness, Severity::Warning, BareSlashMarker),
142 ("C055", Category::Correctness, Severity::Warning, PatternWithVariable),
143 ("C056", Category::Correctness, Severity::Warning, StatusCaptureAfterBranchTest),
144 ("C057", Category::Correctness, Severity::Warning, SubstWithRedirect),
145 ("C058", Category::Correctness, Severity::Warning, SubstWithRedirectErr),
146 ("C059", Category::Correctness, Severity::Warning, RedirectToCommandName),
147 ("C060", Category::Correctness, Severity::Warning, NonAbsoluteShebang),
148 ("C061", Category::Correctness, Severity::Warning, TemplateBraceInCommand),
149 ("C062", Category::Correctness, Severity::Warning, NestedParameterExpansion),
150 ("C063", Category::Correctness, Severity::Warning, OverwrittenFunction),
151 ("C064", Category::Correctness, Severity::Warning, IfMissingThen),
152 ("C065", Category::Correctness, Severity::Warning, ElseWithoutThen),
153 ("C066", Category::Correctness, Severity::Warning, MissingSemicolonBeforeBrace),
154 ("C067", Category::Correctness, Severity::Warning, EmptyFunctionBody),
155 ("C068", Category::Correctness, Severity::Warning, BareClosingBrace),
156 ("C069", Category::Correctness, Severity::Warning, BackslashBeforeClosingBacktick),
157 ("C070", Category::Correctness, Severity::Warning, PositionalParamAsOperator),
158 ("C071", Category::Correctness, Severity::Warning, DoubleParenGrouping),
159 ("C072", Category::Correctness, Severity::Warning, UnicodeQuoteInString),
160 ("C073", Category::Correctness, Severity::Warning, IndentedShebang),
161 ("C074", Category::Correctness, Severity::Warning, SpaceAfterHashBang),
162 ("C075", Category::Correctness, Severity::Warning, ShebangNotOnFirstLine),
163 (
164 "C076",
165 Category::Correctness,
166 Severity::Warning,
167 CommentedContinuationLine
168 ),
169 ("C077", Category::Correctness, Severity::Warning, SubshellInArithmetic),
170 ("C078", Category::Correctness, Severity::Warning, UnquotedGlobsInFind),
171 ("C080", Category::Correctness, Severity::Warning, GlobInGrepPattern),
172 ("C081", Category::Correctness, Severity::Warning, GlobInStringComparison),
173 ("C083", Category::Correctness, Severity::Warning, GlobInFindSubstitution),
174 ("C084", Category::Correctness, Severity::Warning, UnquotedGrepRegex),
175 (
176 "C085",
177 Category::Correctness,
178 Severity::Warning,
179 StderrBeforeStdoutRedirect
180 ),
181 (
182 "C094",
183 Category::Correctness,
184 Severity::Warning,
185 RedirectClobbersInput
186 ),
187 (
188 "C082",
189 Category::Correctness,
190 Severity::Warning,
191 EscapedNegationInTest
192 ),
193 (
194 "C086",
195 Category::Correctness,
196 Severity::Warning,
197 GreaterThanInTest
198 ),
199 (
200 "C087",
201 Category::Correctness,
202 Severity::Warning,
203 StringComparisonForVersion
204 ),
205 (
206 "C088",
207 Category::Correctness,
208 Severity::Warning,
209 MixedAndOrInCondition
210 ),
211 (
212 "C089",
213 Category::Correctness,
214 Severity::Warning,
215 QuotedCommandInTest
216 ),
217 (
218 "C090",
219 Category::Correctness,
220 Severity::Warning,
221 GlobInTestComparison
222 ),
223 (
224 "C091",
225 Category::Correctness,
226 Severity::Warning,
227 TildeInStringComparison
228 ),
229 ("C092", Category::Correctness, Severity::Warning, IfDollarCommand),
230 (
231 "C093",
232 Category::Correctness,
233 Severity::Warning,
234 BacktickInCommandPosition
235 ),
236 (
237 "C095",
238 Category::Correctness,
239 Severity::Warning,
240 AssignmentLooksLikeComparison
241 ),
242 ("C096", Category::Correctness, Severity::Warning, SuspiciousBracketGlob),
243 (
244 "C097",
245 Category::Correctness,
246 Severity::Error,
247 FunctionCalledWithoutArgs
248 ),
249 (
250 "C098",
251 Category::Correctness,
252 Severity::Warning,
253 SetFlagsWithoutDashes
254 ),
255 (
256 "C099",
257 Category::Correctness,
258 Severity::Warning,
259 QuotedArraySlice
260 ),
261 (
262 "C100",
263 Category::Correctness,
264 Severity::Warning,
265 QuotedBashSource
266 ),
267 (
268 "C101",
269 Category::Correctness,
270 Severity::Warning,
271 IfsSetToLiteralBackslashN
272 ),
273 (
274 "C102",
275 Category::Correctness,
276 Severity::Warning,
277 GlobInTestDirectory
278 ),
279 (
280 "C103",
281 Category::Correctness,
282 Severity::Warning,
283 FindOrWithoutGrouping
284 ),
285 (
286 "C104",
287 Category::Correctness,
288 Severity::Warning,
289 NonShellSyntaxInScript
290 ),
291 (
292 "C105",
293 Category::Correctness,
294 Severity::Warning,
295 ExportWithPositionalParams
296 ),
297 (
298 "C106",
299 Category::Correctness,
300 Severity::Warning,
301 AppendToArrayAsString
302 ),
303 (
304 "C107",
305 Category::Correctness,
306 Severity::Warning,
307 DollarQuestionAfterCommand
308 ),
309 (
310 "C108",
311 Category::Correctness,
312 Severity::Warning,
313 UnsetAssociativeArrayElement
314 ),
315 (
316 "C109",
317 Category::Correctness,
318 Severity::Warning,
319 MapfileProcessSubstitution
320 ),
321 (
322 "C111",
323 Category::Correctness,
324 Severity::Warning,
325 AtSignInStringCompare
326 ),
327 (
328 "C112",
329 Category::Correctness,
330 Severity::Warning,
331 ArraySliceInComparison
332 ),
333 (
334 "C114",
335 Category::Correctness,
336 Severity::Warning,
337 GlobWithExpansionInLoop
338 ),
339 (
340 "C116",
341 Category::Correctness,
342 Severity::Warning,
343 AssignmentToNumericVariable
344 ),
345 (
346 "C117",
347 Category::Correctness,
348 Severity::Warning,
349 PlusPrefixInAssignment
350 ),
351 (
352 "C118",
353 Category::Correctness,
354 Severity::Warning,
355 MalformedArithmeticInCondition
356 ),
357 (
358 "C119",
359 Category::Correctness,
360 Severity::Warning,
361 RedirectBeforePipe
362 ),
363 (
364 "C120",
365 Category::Correctness,
366 Severity::Warning,
367 ExprSubstrInTest
368 ),
369 (
370 "C121",
371 Category::Correctness,
372 Severity::Warning,
373 StringComparedWithEq
374 ),
375 (
376 "C122",
377 Category::Correctness,
378 Severity::Warning,
379 AFlagInDoubleBracket
380 ),
381 (
382 "C123",
383 Category::Correctness,
384 Severity::Error,
385 FunctionReferencesUnsetParam
386 ),
387 ("C124", Category::Correctness, Severity::Warning, UnreachableAfterExit),
388 ("C127", Category::Correctness, Severity::Warning, UnusedHeredoc),
389 (
390 "C125",
391 Category::Correctness,
392 Severity::Warning,
393 UncheckedDirectoryChangeInFunction
394 ),
395 (
396 "C126",
397 Category::Correctness,
398 Severity::Error,
399 ContinueOutsideLoopInFunction
400 ),
401 (
402 "C128",
403 Category::Correctness,
404 Severity::Warning,
405 CaseGlobReachability
406 ),
407 (
408 "C129",
409 Category::Correctness,
410 Severity::Warning,
411 CaseDefaultBeforeGlob
412 ),
413 (
414 "C130",
415 Category::Correctness,
416 Severity::Warning,
417 AppendWithEscapedQuotes
418 ),
419 (
420 "C131",
421 Category::Correctness,
422 Severity::Warning,
423 VariableAsCommandName
424 ),
425 (
426 "C132",
427 Category::Correctness,
428 Severity::Warning,
429 EnvPrefixExpansionOnly
430 ),
431 (
432 "C133",
433 Category::Correctness,
434 Severity::Warning,
435 ArrayToStringConversion
436 ),
437 (
438 "C134",
439 Category::Correctness,
440 Severity::Warning,
441 GetoptsOptionNotInCase
442 ),
443 (
444 "C135",
445 Category::Correctness,
446 Severity::Warning,
447 CaseArmNotInGetopts
448 ),
449 (
450 "C136",
451 Category::Correctness,
452 Severity::Warning,
453 LocalCrossReference
454 ),
455 (
456 "C137",
457 Category::Correctness,
458 Severity::Warning,
459 UnicodeSingleQuoteInSingleQuotes
460 ),
461 ("C138", Category::Correctness, Severity::Warning, HeredocMissingEnd),
462 ("C139", Category::Correctness, Severity::Warning, SpacedAssignment),
463 ("C140", Category::Correctness, Severity::Warning, BadVarName),
464 ("C141", Category::Correctness, Severity::Error, LoopWithoutEnd),
465 (
466 "C142",
467 Category::Correctness,
468 Severity::Error,
469 MissingDoneInForLoop
470 ),
471 ("C143", Category::Correctness, Severity::Error, DanglingElse),
472 (
473 "C144",
474 Category::Correctness,
475 Severity::Warning,
476 HeredocCloserNotAlone
477 ),
478 ("C145", Category::Correctness, Severity::Warning, MisquotedHeredocClose),
479 ("C146", Category::Correctness, Severity::Error, UntilMissingDo),
480 ("C148", Category::Correctness, Severity::Warning, BrokenAssocKey),
481 (
482 "C150",
483 Category::Correctness,
484 Severity::Warning,
485 SubshellLocalAssignment
486 ),
487 ("C151", Category::Correctness, Severity::Warning, CommaArrayElements),
488 ("C155", Category::Correctness, Severity::Warning, SubshellSideEffect),
489 (
490 "C156",
491 Category::Correctness,
492 Severity::Warning,
493 PossibleVariableMisspelling
494 ),
495 ("C157", Category::Correctness, Severity::Error, IfBracketGlued),
496 (
497 "C158",
498 Category::Correctness,
499 Severity::Warning,
500 ImplicitGlobalInFunction
501 ),
502 ("C159", Category::Correctness, Severity::Warning, MutableGlobal),
503 (
504 "C160",
505 Category::Correctness,
506 Severity::Warning,
507 UnanchoredSourcePath
508 ),
509 (
510 "C161",
511 Category::Correctness,
512 Severity::Error,
513 FunctionCalledBeforeDefined
514 ),
515 ("P001", Category::Performance, Severity::Warning, ExprArithmetic),
516 ("P002", Category::Performance, Severity::Warning, GrepCountPipeline),
517 ("P003", Category::Performance, Severity::Warning, SingleTestSubshell),
518 ("P004", Category::Performance, Severity::Warning, SubshellTestGroup),
519 ("X001", Category::Portability, Severity::Warning, DoubleBracketInSh),
520 ("X002", Category::Portability, Severity::Warning, TestEqualityOperator),
521 ("X003", Category::Portability, Severity::Warning, LocalVariableInSh),
522 ("X004", Category::Portability, Severity::Warning, FunctionKeyword),
523 ("X005", Category::Portability, Severity::Warning, BashCaseFallthrough),
524 ("X006", Category::Portability, Severity::Warning, ProcessSubstitution),
525 ("X007", Category::Portability, Severity::Warning, AnsiCQuoting),
526 ("X010", Category::Portability, Severity::Warning, BraceExpansion),
527 ("X011", Category::Portability, Severity::Warning, HereString),
528 ("X008", Category::Portability, Severity::Warning, StandaloneArithmetic),
529 ("X009", Category::Portability, Severity::Warning, SelectLoop),
530 ("X014", Category::Portability, Severity::Warning, Coproc),
531 ("X012", Category::Portability, Severity::Warning, AmpersandRedirection),
532 ("X013", Category::Portability, Severity::Warning, ArrayAssignment),
533 ("X015", Category::Portability, Severity::Warning, LetCommand),
534 ("X016", Category::Portability, Severity::Warning, DeclareCommand),
535 ("X017", Category::Portability, Severity::Warning, TrapErr),
536 ("X018", Category::Portability, Severity::Warning, IndirectExpansion),
537 ("X019", Category::Portability, Severity::Warning, ArrayReference),
538 ("X020", Category::Portability, Severity::Warning, BraceFdRedirection),
539 ("X021", Category::Portability, Severity::Warning, PipefailOption),
540 ("X022", Category::Portability, Severity::Warning, WaitOption),
541 ("X023", Category::Portability, Severity::Warning, SubstringExpansion),
542 ("X024", Category::Portability, Severity::Warning, CaseModificationExpansion),
543 ("X025", Category::Portability, Severity::Warning, ReplacementExpansion),
544 ("X026", Category::Portability, Severity::Warning, BashFileSlurp),
545 ("X027", Category::Portability, Severity::Warning, EchoFlags),
546 ("X028", Category::Portability, Severity::Warning, TrLowerRange),
547 ("X029", Category::Portability, Severity::Warning, TrUpperRange),
548 ("X030", Category::Portability, Severity::Warning, EchoBackslashEscapes),
549 ("X031", Category::Portability, Severity::Warning, SourceBuiltinInSh),
550 ("X032", Category::Portability, Severity::Warning, PrintfQFormatInSh),
551 ("X033", Category::Portability, Severity::Warning, IfElifBashTest),
552 ("X035", Category::Portability, Severity::Warning, FunctionParamsInSh),
553 ("X037", Category::Portability, Severity::Warning, ExtglobCase),
554 ("X048", Category::Portability, Severity::Warning, ExtglobInCasePattern),
555 ("X054", Category::Portability, Severity::Warning, ExtglobInSh),
556 ("X065", Category::Portability, Severity::Warning, CaretNegationInBracket),
557 ("X036", Category::Portability, Severity::Warning, ZshRedirPipe),
558 ("X038", Category::Portability, Severity::Warning, ZshBraceIf),
559 ("X039", Category::Portability, Severity::Warning, ZshAlwaysBlock),
560 ("X040", Category::Portability, Severity::Warning, ArraySubscriptTest),
561 ("X041", Category::Portability, Severity::Warning, ArraySubscriptCondition),
562 ("X042", Category::Portability, Severity::Warning, SourcedWithArgs),
563 ("X043", Category::Portability, Severity::Warning, ZshFlagExpansion),
564 ("X044", Category::Portability, Severity::Warning, NestedZshSubstitution),
565 ("X045", Category::Portability, Severity::Warning, PlusEqualsAppend),
566 ("X051", Category::Portability, Severity::Warning, ZshNestedExpansion),
567 ("X047", Category::Portability, Severity::Warning, MultiVarForLoop),
568 ("X049", Category::Portability, Severity::Warning, ZshPromptBracket),
569 ("X050", Category::Portability, Severity::Warning, CshSyntaxInSh),
570 ("X053", Category::Portability, Severity::Warning, ZshAssignmentToZero),
571 ("X056", Category::Portability, Severity::Warning, CStyleForInSh),
572 ("X055", Category::Portability, Severity::Warning, DollarStringInSh),
573 ("X057", Category::Portability, Severity::Warning, LegacyArithmeticInSh),
574 ("X062", Category::Portability, Severity::Warning, CStyleForArithmeticInSh),
575 ("X071", Category::Portability, Severity::Warning, ArrayKeysInSh),
576 ("X081", Category::Portability, Severity::Warning, StarGlobRemovalInSh),
577 ("X076", Category::Portability, Severity::Warning, ZshParameterFlag),
578 ("X077", Category::Portability, Severity::Warning, NestedDefaultExpansion),
579 ("X078", Category::Portability, Severity::Warning, ZshArraySubscriptInCase),
580 ("X079", Category::Portability, Severity::Warning, ZshParameterIndexFlag),
581 ("X046", Category::Portability, Severity::Warning, ExtglobInTest),
582 ("X052", Category::Portability, Severity::Warning, FunctionKeywordInSh),
583 ("X058", Category::Portability, Severity::Warning, LexicalComparisonInDoubleBracket),
584 ("X059", Category::Portability, Severity::Warning, RegexMatchInSh),
585 ("X060", Category::Portability, Severity::Warning, VTestInSh),
586 ("X061", Category::Portability, Severity::Warning, ATestInSh),
587 ("X063", Category::Portability, Severity::Warning, AmpersandRedirectInSh),
588 ("X066", Category::Portability, Severity::Warning, PipeStderrInSh),
589 ("X067", Category::Portability, Severity::Warning, HyphenatedFunctionName),
590 ("X068", Category::Portability, Severity::Warning, ErrexitTrapInSh),
591 ("X069", Category::Portability, Severity::Warning, SignalNameInTrap),
592 ("X070", Category::Portability, Severity::Warning, BasePrefixInArithmetic),
593 ("X072", Category::Portability, Severity::Warning, UnsetPatternInSh),
594 ("X073", Category::Portability, Severity::Warning, OptionTestInSh),
595 ("X074", Category::Portability, Severity::Warning, StickyBitTestInSh),
596 ("X075", Category::Portability, Severity::Warning, OwnershipTestInSh),
597 ("X080", Category::Portability, Severity::Warning, SourceInsideFunctionInSh),
598 ("K001", Category::Security, Severity::Warning, RmGlobOnVariablePath),
599 ("K002", Category::Security, Severity::Warning, SshLocalExpansion),
600 ("K003", Category::Security, Severity::Warning, EvalOnArray),
601 ("K004", Category::Security, Severity::Warning, FindExecDirWithShell),
602 ("K006", Category::Security, Severity::Warning, RmRootishTarget),
603 (
604 "K007",
605 Category::Security,
606 Severity::Warning,
607 ChmodWorldWritableSensitivePath
608 ),
609 ("K008", Category::Security, Severity::Warning, ForkBombPattern),
610 ("S001", Category::Style, Severity::Warning, UnquotedExpansion),
611 ("S002", Category::Style, Severity::Warning, ReadWithoutRaw),
612 ("S003", Category::Style, Severity::Warning, LoopFromCommandOutput),
613 ("S004", Category::Style, Severity::Warning, UnquotedCommandSubstitution),
614 ("S005", Category::Style, Severity::Warning, LegacyBackticks),
615 ("S006", Category::Style, Severity::Warning, LegacyArithmeticExpansion),
616 ("S007", Category::Style, Severity::Warning, PrintfFormatVariable),
617 ("S008", Category::Style, Severity::Warning, UnquotedArrayExpansion),
618 ("S009", Category::Style, Severity::Warning, EchoedCommandSubstitution),
619 ("S010", Category::Style, Severity::Warning, ExportCommandSubstitution),
620 ("S011", Category::Style, Severity::Warning, CompoundTestOperator),
621 ("S012", Category::Style, Severity::Warning, PsGrepPipeline),
622 ("S013", Category::Style, Severity::Warning, LsGrepPipeline),
623 ("S014", Category::Style, Severity::Warning, UnquotedDollarStar),
624 ("S015", Category::Style, Severity::Warning, QuotedDollarStarLoop),
625 ("S017", Category::Style, Severity::Warning, UnquotedArraySplit),
626 ("S018", Category::Style, Severity::Warning, CommandOutputArraySplit),
627 ("S021", Category::Style, Severity::Warning, PositionalArgsInString),
628 ("S020", Category::Style, Severity::Warning, SingleIterationLoop),
629 ("S032", Category::Style, Severity::Warning, BareCommandNameAssignment),
630 ("S036", Category::Style, Severity::Warning, BareRead),
631 ("S037", Category::Style, Severity::Warning, RedundantSpacesInEcho),
632 ("S038", Category::Style, Severity::Warning, RedundantReturnStatus),
633 ("S044", Category::Style, Severity::Warning, EchoToSedSubstitution),
634 ("S050", Category::Style, Severity::Hint, UnquotedWordBetweenQuotes),
635 ("S051", Category::Style, Severity::Warning, UnquotedTrClass),
636 ("S052", Category::Style, Severity::Warning, UnquotedVariableInTest),
637 ("S054", Category::Style, Severity::Warning, SuWithoutFlag),
638 (
639 "S055",
640 Category::Style,
641 Severity::Warning,
642 GlobAssignedToVariable
643 ),
644 ("S056", Category::Style, Severity::Warning, CommandSubstitutionInAlias),
645 ("S057", Category::Style, Severity::Warning, FunctionInAlias),
646 ("S058", Category::Style, Severity::Warning, UnquotedPathInMkdir),
647 ("S059", Category::Style, Severity::Warning, DeprecatedTempfileCommand),
648 ("S060", Category::Style, Severity::Warning, EgrepDeprecated),
649 ("S061", Category::Style, Severity::Warning, FgrepDeprecated),
650 ("S062", Category::Style, Severity::Warning, DefaultValueInColonAssign),
651 ("S064", Category::Style, Severity::Warning, XargsWithInlineReplace),
652 ("S065", Category::Style, Severity::Warning, XPrefixInTest),
653 ("S067", Category::Style, Severity::Warning, LeadingGlobInGrepPattern),
654 ("S068", Category::Style, Severity::Warning, TrapSignalNumbers),
655 ("S069", Category::Style, Severity::Hint, GetoptsInvalidFlagHandler),
656 ("S070", Category::Style, Severity::Warning, DoubleQuoteNesting),
657 ("S071", Category::Style, Severity::Warning, EnvPrefixCommandOnly),
658 ("S076", Category::Style, Severity::Warning, MixedQuoteWord),
659 (
660 "S077",
661 Category::Style,
662 Severity::Warning,
663 BraceVariableBeforeBracket
664 ),
665 ("S049", Category::Style, Severity::Warning, UnquotedTrRange),
666 ("S046", Category::Style, Severity::Warning, LsPipedToXargs),
667 ("S047", Category::Style, Severity::Warning, LsInSubstitution),
668 (
669 "S016",
670 Category::Style,
671 Severity::Warning,
672 EchoInsideCommandSubstitution
673 ),
674 ("S019", Category::Style, Severity::Warning, GrepOutputInTest),
675 ("S022", Category::Style, Severity::Hint, AvoidLetBuiltin),
676 ("S033", Category::Style, Severity::Warning, EchoHereDoc),
677 ("S034", Category::Style, Severity::Warning, ArrayIndexArithmetic),
678 ("S035", Category::Style, Severity::Warning, ArithmeticScoreLine),
679 ("S045", Category::Style, Severity::Warning, DollarInArithmetic),
680 ("S023", Category::Style, Severity::Warning, EscapedUnderscore),
681 ("S024", Category::Style, Severity::Warning, SingleQuoteBackslash),
682 ("S025", Category::Style, Severity::Warning, LiteralBackslash),
683 ("SH-173", Category::Style, Severity::Warning, BackslashBeforeCommand),
684 ("S028", Category::Style, Severity::Warning, SuspectClosingQuote),
685 ("S029", Category::Style, Severity::Warning, LiteralBraces),
686 ("S030", Category::Style, Severity::Warning, HeredocEndSpace),
687 ("S031", Category::Style, Severity::Warning, TrailingDirective),
688 (
689 "S039",
690 Category::Style,
691 Severity::Warning,
692 LiteralBackslashInSingleQuotes
693 ),
694 ("S040", Category::Style, Severity::Warning, LiteralControlEscape),
695 (
696 "S041",
697 Category::Style,
698 Severity::Warning,
699 FunctionBodyWithoutBraces
700 ),
701 (
702 "S066",
703 Category::Style,
704 Severity::Warning,
705 LocalDeclareCombined
706 ),
707 ("S042", Category::Style, Severity::Warning, IfsEqualsAmbiguity),
708 ("S043", Category::Style, Severity::Warning, MissingShebangLine),
709 ("S053", Category::Style, Severity::Warning, DuplicateShebangFlag),
710 ("S072", Category::Style, Severity::Warning, LinebreakBeforeAnd),
711 ("S073", Category::Style, Severity::Warning, SpacedTabstripClose),
712 ("S074", Category::Style, Severity::Warning, AmpersandSemicolon),
713 ("S075", Category::Style, Severity::Warning, CombineAppends),
714 ("S078", Category::Style, Severity::Warning, ShebangShellPolicy),
715 ("S079", Category::Style, Severity::Warning, ShebangFormPolicy),
716 ("S080", Category::Style, Severity::Warning, ScriptSizeThreshold),
717 ("S081", Category::Style, Severity::Warning, MissingFileDescription),
718 ("S082", Category::Style, Severity::Warning, TodoFormat),
719 ("S083", Category::Style, Severity::Warning, MissingFunctionDoc),
720 ("S084", Category::Style, Severity::Warning, FunctionDocContent),
721 ("S085", Category::Style, Severity::Warning, MissingMainEntrypoint),
722}
723
724pub fn code_to_rule(code: &str) -> Option<Rule> {
725 canonical_code_to_rule(code).or(match code {
726 "SH-001" => Some(Rule::UnquotedExpansion),
727 "SH-002" => Some(Rule::ReadWithoutRaw),
728 "SH-003" => Some(Rule::UnusedAssignment),
729 "SH-004" => Some(Rule::LoopFromCommandOutput),
730 "SH-005" => Some(Rule::UnquotedCommandSubstitution),
731 "SH-008" => Some(Rule::LocalVariableInSh),
732 "SH-009" => Some(Rule::FunctionKeyword),
733 "SH-010" => Some(Rule::BashCaseFallthrough),
734 "SH-011" => Some(Rule::ProcessSubstitution),
735 "SH-012" => Some(Rule::AnsiCQuoting),
736 "SH-015" => Some(Rule::BraceExpansion),
737 "SH-016" => Some(Rule::HereString),
738 "SH-018" => Some(Rule::ArrayAssignment),
739 "SH-023" => Some(Rule::IndirectExpansion),
740 "SH-024" => Some(Rule::ArrayReference),
741 "SH-031" => Some(Rule::SubstringExpansion),
742 "SH-032" => Some(Rule::CaseModificationExpansion),
743 "SH-033" => Some(Rule::ReplacementExpansion),
744 "SH-053" => Some(Rule::BashFileSlurp),
745 "SH-013" => Some(Rule::StandaloneArithmetic),
746 "SH-014" => Some(Rule::SelectLoop),
747 "SH-019" => Some(Rule::Coproc),
748 "SH-079" => Some(Rule::AvoidLetBuiltin),
749 "SH-020" => Some(Rule::LetCommand),
750 "SH-021" => Some(Rule::DeclareCommand),
751 "SH-289" => Some(Rule::LocalDeclareCombined),
752 "SH-029" => Some(Rule::PipefailOption),
753 "SH-030" => Some(Rule::WaitOption),
754 "SH-022" => Some(Rule::TrapErr),
755 "SH-080" => Some(Rule::SourceBuiltinInSh),
756 "SH-081" => Some(Rule::PrintfQFormatInSh),
757 "SH-054" => Some(Rule::EchoFlags),
758 "SH-058" => Some(Rule::TrLowerRange),
759 "SH-059" => Some(Rule::TrUpperRange),
760 "SH-061" => Some(Rule::EchoBackslashEscapes),
761 "SH-226" => Some(Rule::FunctionKeywordInSh),
762 "SH-274" => Some(Rule::HyphenatedFunctionName),
763 "SH-234" => Some(Rule::IfsSetToLiteralBackslashN),
764 "SH-236" => Some(Rule::GlobInTestDirectory),
765 "SH-284" => Some(Rule::MalformedArithmeticInCondition),
766 "SH-287" => Some(Rule::ExprSubstrInTest),
767 "SH-288" => Some(Rule::StringComparedWithEq),
768 "SH-290" => Some(Rule::AFlagInDoubleBracket),
769 "SH-279" => Some(Rule::UnsetPatternInSh),
770 "SH-291" => Some(Rule::NestedDefaultExpansion),
771 "SH-304" => Some(Rule::SourceInsideFunctionInSh),
772 "SH-275" => Some(Rule::ErrexitTrapInSh),
773 "SH-276" => Some(Rule::SignalNameInTrap),
774 "SH-297" => Some(Rule::TrapSignalNumbers),
775 "SH-277" => Some(Rule::BasePrefixInArithmetic),
776 "SH-034" => Some(Rule::LegacyBackticks),
777 "SH-035" => Some(Rule::LegacyArithmeticExpansion),
778 "SH-078" => Some(Rule::LeadingZeroArithmetic),
779 "SH-157" => Some(Rule::ArrayIndexArithmetic),
780 "SH-161" => Some(Rule::ArithmeticScoreLine),
781 "SH-197" => Some(Rule::DollarInArithmetic),
782 "SH-198" => Some(Rule::LsPipedToXargs),
783 "SH-203" => Some(Rule::UnquotedTrRange),
784 "SH-082" => Some(Rule::EscapedUnderscore),
785 "SH-208" => Some(Rule::UnquotedTrClass),
786 "SH-212" => Some(Rule::UnquotedVariableInTest),
787 "SH-087" => Some(Rule::SingleQuoteBackslash),
788 "SH-172" => Some(Rule::LiteralBackslashInSingleQuotes),
789 "SH-185" => Some(Rule::IfsEqualsAmbiguity),
790 "SH-088" => Some(Rule::LiteralBackslash),
791 "SH-258" => Some(Rule::AssignmentToNumericVariable),
792 "SH-259" => Some(Rule::PlusPrefixInAssignment),
793 "SH-307" => Some(Rule::AppendWithEscapedQuotes),
794 "SH-025" => Some(Rule::DynamicSourcePath),
795 "SH-026" => Some(Rule::UntrackedSourceFile),
796 "SH-027" => Some(Rule::UncheckedDirectoryChange),
797 "SH-228" => Some(Rule::FunctionCalledWithoutArgs),
798 "SH-292" => Some(Rule::FunctionReferencesUnsetParam),
799 "SH-295" => Some(Rule::UncheckedDirectoryChangeInFunction),
800 "SH-296" => Some(Rule::ContinueOutsideLoopInFunction),
801 "SH-308" => Some(Rule::VariableAsCommandName),
802 "SH-311" => Some(Rule::ArrayToStringConversion),
803 "SH-337" => Some(Rule::BrokenAssocKey),
804 "SH-347" => Some(Rule::SubshellSideEffect),
805 "SH-340" => Some(Rule::CommaArrayElements),
806 "SH-351" => Some(Rule::PossibleVariableMisspelling),
807 "SH-036" => Some(Rule::SingleQuotedLiteral),
808 "SH-037" => Some(Rule::PrintfFormatVariable),
809 "SH-038" => Some(Rule::UnquotedArrayExpansion),
810 "SH-039" => Some(Rule::UndefinedVariable),
811 "SH-040" => Some(Rule::EchoedCommandSubstitution),
812 "SH-051" => Some(Rule::CompoundTestOperator),
813 "SH-170" => Some(Rule::RedundantReturnStatus),
814 "SH-168" => Some(Rule::RedundantSpacesInEcho),
815 "SH-196" => Some(Rule::EchoToSedSubstitution),
816 "SH-205" => Some(Rule::UnquotedWordBetweenQuotes),
817 "SH-066" => Some(Rule::EchoInsideCommandSubstitution),
818 "SH-199" => Some(Rule::LsInSubstitution),
819 "SH-163" => Some(Rule::BareRead),
820 "SH-245" => Some(Rule::DeprecatedTempfileCommand),
821 "SH-247" => Some(Rule::EgrepDeprecated),
822 "SH-248" => Some(Rule::FgrepDeprecated),
823 "SH-255" => Some(Rule::XargsWithInlineReplace),
824 "SH-256" => Some(Rule::XPrefixInTest),
825 "SH-306" => Some(Rule::DoubleQuoteNesting),
826 "SH-309" => Some(Rule::EnvPrefixCommandOnly),
827 "SH-350" => Some(Rule::MixedQuoteWord),
828 "SH-354" => Some(Rule::BraceVariableBeforeBracket),
829 "SH-071" => Some(Rule::GrepOutputInTest),
830 "SH-076" => Some(Rule::SingleIterationLoop),
831 "SH-128" => Some(Rule::BareCommandNameAssignment),
832 "SH-041" => Some(Rule::FindOutputToXargs),
833 "SH-042" => Some(Rule::TrapStringExpansion),
834 "SH-043" => Some(Rule::QuotedBashRegex),
835 "SH-044" => Some(Rule::RmGlobOnVariablePath),
836 "SH-047" => Some(Rule::SshLocalExpansion),
837 "SH-151" => Some(Rule::EvalOnArray),
838 "SH-324" => Some(Rule::RmRootishTarget),
839 "SH-325" => Some(Rule::ChmodWorldWritableSensitivePath),
840 "SH-326" => Some(Rule::ForkBombPattern),
841 "SH-045" => Some(Rule::ChainedTestBranches),
842 "C079" => Some(Rule::ChainedTestBranches),
843 "SH-201" => Some(Rule::ChainedTestBranches),
844 "SH-046" => Some(Rule::LineOrientedInput),
845 "SH-048" => Some(Rule::LeadingGlobArgument),
846 "SH-049" => Some(Rule::FindOutputLoop),
847 "SH-050" => Some(Rule::ExportCommandSubstitution),
848 "SH-135" => Some(Rule::EchoHereDoc),
849 "SH-052" => Some(Rule::LocalTopLevel),
850 "SH-060" => Some(Rule::SudoRedirectionOrder),
851 "SH-065" => Some(Rule::StrayClosingKeyword),
852 "SH-146" => Some(Rule::AssignSpecialZero),
853 "SH-147" => Some(Rule::SpaceyAssign),
854 "SH-069" => Some(Rule::ConstantComparisonTest),
855 "SH-070" => Some(Rule::LoopControlOutsideLoop),
856 "SH-072" => Some(Rule::LiteralUnaryStringTest),
857 "SH-073" => Some(Rule::TruthyLiteralTest),
858 "SH-074" => Some(Rule::ConstantCaseSubject),
859 "SH-075" => Some(Rule::EmptyTest),
860 "SH-084" => Some(Rule::AssignmentSpacing),
861 "SH-098" => Some(Rule::MissingBracketSpace),
862 "SH-102" => Some(Rule::JammedTestBracket),
863 "SH-104" => Some(Rule::IndentedHeredocClose),
864 "SH-133" => Some(Rule::DiffMarkerLine),
865 "SH-134" => Some(Rule::PipeToKill),
866 "SH-086" => Some(Rule::PositionalTenBraces),
867 "SH-091" => Some(Rule::BareDoneWord),
868 "SH-100" => Some(Rule::MissingSpaceBeforeBracketClose),
869 "SH-105" => Some(Rule::UnterminatedIf),
870 "SH-106" => Some(Rule::MissingFi),
871 "SH-107" => Some(Rule::FunctionParamsInSh),
872 "SH-109" => Some(Rule::BrokenTestEnd),
873 "SH-110" => Some(Rule::BrokenTestParse),
874 "SH-111" => Some(Rule::ExtglobCase),
875 "SH-182" => Some(Rule::ExtglobInCasePattern),
876 "SH-261" => Some(Rule::ExtglobInSh),
877 "SH-272" => Some(Rule::CaretNegationInBracket),
878 "SH-207" => Some(Rule::EscapedNegationInTest),
879 "SH-213" => Some(Rule::GreaterThanInTest),
880 "SH-214" => Some(Rule::StringComparisonForVersion),
881 "SH-215" => Some(Rule::MixedAndOrInCondition),
882 "SH-216" => Some(Rule::QuotedCommandInTest),
883 "SH-217" => Some(Rule::GlobInTestComparison),
884 "SH-219" => Some(Rule::TildeInStringComparison),
885 "SH-220" => Some(Rule::IfDollarCommand),
886 "SH-221" => Some(Rule::BacktickInCommandPosition),
887 "SH-112" => Some(Rule::ElseIf),
888 "SH-113" => Some(Rule::OpenDoubleQuote),
889 "SH-114" => Some(Rule::SuspectClosingQuote),
890 "SH-115" => Some(Rule::LinebreakInTest),
891 "SH-116" => Some(Rule::LiteralBraces),
892 "SH-119" => Some(Rule::HeredocEndSpace),
893 "SH-120" => Some(Rule::TrailingDirective),
894 "SH-329" => Some(Rule::LinebreakBeforeAnd),
895 "SH-330" => Some(Rule::SpacedTabstripClose),
896 "SH-335" => Some(Rule::AmpersandSemicolon),
897 "SH-349" => Some(Rule::CombineAppends),
898 "SH-339" => Some(Rule::SubshellLocalAssignment),
899 "SH-121" => Some(Rule::CStyleComment),
900 "SH-123" => Some(Rule::CPrototypeFragment),
901 "SH-129" => Some(Rule::BadRedirectionFdOrder),
902 "SH-130" => Some(Rule::BareGlobCommandPath),
903 "SH-141" => Some(Rule::InvalidExitStatus),
904 "SH-142" => Some(Rule::CasePatternVar),
905 "SH-143" => Some(Rule::TautologyChain),
906 "SH-144" => Some(Rule::ArithmeticRedirectionTarget),
907 "SH-145" => Some(Rule::DuplicateRedirect),
908 "SH-148" => Some(Rule::BareSlashMarker),
909 "SH-152" => Some(Rule::PatternWithVariable),
910 "SH-155" => Some(Rule::StatusCaptureAfterBranchTest),
911 "SH-017" => Some(Rule::AmpersandRedirection),
912 "SH-028" => Some(Rule::BraceFdRedirection),
913 "SH-270" => Some(Rule::AmpersandRedirectInSh),
914 "SH-273" => Some(Rule::PipeStderrInSh),
915 "SH-159" => Some(Rule::SubstWithRedirect),
916 "SH-160" => Some(Rule::SubstWithRedirectErr),
917 "SH-165" => Some(Rule::RedirectToCommandName),
918 "SH-285" => Some(Rule::RedirectBeforePipe),
919 "SH-166" => Some(Rule::NonAbsoluteShebang),
920 "SH-167" => Some(Rule::TemplateBraceInCommand),
921 "SH-169" => Some(Rule::NestedParameterExpansion),
922 "SH-171" => Some(Rule::OverwrittenFunction),
923 "SH-175" => Some(Rule::IfMissingThen),
924 "SH-176" => Some(Rule::ElseWithoutThen),
925 "SH-177" => Some(Rule::MissingSemicolonBeforeBrace),
926 "SH-178" => Some(Rule::EmptyFunctionBody),
927 "SH-179" => Some(Rule::BareClosingBrace),
928 "SH-186" => Some(Rule::BackslashBeforeClosingBacktick),
929 "SH-187" => Some(Rule::PositionalParamAsOperator),
930 "SH-211" => Some(Rule::StderrBeforeStdoutRedirect),
931 "SH-222" => Some(Rule::RedirectClobbersInput),
932 "SH-188" => Some(Rule::DoubleParenGrouping),
933 "SH-189" => Some(Rule::UnicodeQuoteInString),
934 "SH-190" => Some(Rule::MissingShebangLine),
935 "SH-191" => Some(Rule::IndentedShebang),
936 "SH-192" => Some(Rule::SpaceAfterHashBang),
937 "SH-193" => Some(Rule::ShebangNotOnFirstLine),
938 "SH-223" => Some(Rule::DuplicateShebangFlag),
939 "SH-224" => Some(Rule::AssignmentLooksLikeComparison),
940 "SH-225" => Some(Rule::SuspiciousBracketGlob),
941 "SH-227" => Some(Rule::SuWithoutFlag),
942 "SH-231" => Some(Rule::GlobAssignedToVariable),
943 "SH-194" => Some(Rule::CommentedContinuationLine),
944 "SH-195" => Some(Rule::SubshellInArithmetic),
945 "SH-200" => Some(Rule::UnquotedGlobsInFind),
946 "SH-204" => Some(Rule::GlobInGrepPattern),
947 "SH-206" => Some(Rule::GlobInStringComparison),
948 "SH-209" => Some(Rule::GlobInFindSubstitution),
949 "SH-210" => Some(Rule::UnquotedGrepRegex),
950 "SH-229" => Some(Rule::SetFlagsWithoutDashes),
951 "SH-230" => Some(Rule::QuotedArraySlice),
952 "SH-232" => Some(Rule::QuotedBashSource),
953 "SH-233" => Some(Rule::CommandSubstitutionInAlias),
954 "SH-235" => Some(Rule::FunctionInAlias),
955 "SH-237" => Some(Rule::FindOrWithoutGrouping),
956 "SH-238" => Some(Rule::NonShellSyntaxInScript),
957 "SH-239" => Some(Rule::ExportWithPositionalParams),
958 "SH-240" => Some(Rule::UnquotedPathInMkdir),
959 "SH-249" => Some(Rule::AtSignInStringCompare),
960 "SH-250" => Some(Rule::ArraySliceInComparison),
961 "SH-251" => Some(Rule::DefaultValueInColonAssign),
962 "SH-241" => Some(Rule::AppendToArrayAsString),
963 "SH-242" => Some(Rule::DollarQuestionAfterCommand),
964 "SH-243" => Some(Rule::UnsetAssociativeArrayElement),
965 "SH-244" => Some(Rule::MapfileProcessSubstitution),
966 "SH-254" => Some(Rule::GlobWithExpansionInLoop),
967 "SH-293" => Some(Rule::UnreachableAfterExit),
968 "SH-298" => Some(Rule::UnusedHeredoc),
969 "SH-300" => Some(Rule::GetoptsInvalidFlagHandler),
970 "SH-301" => Some(Rule::CaseGlobReachability),
971 "SH-302" => Some(Rule::CaseDefaultBeforeGlob),
972 "SH-312" => Some(Rule::GetoptsOptionNotInCase),
973 "SH-313" => Some(Rule::CaseArmNotInGetopts),
974 "SH-318" => Some(Rule::HeredocMissingEnd),
975 "SH-310" => Some(Rule::EnvPrefixExpansionOnly),
976 "SH-055" => Some(Rule::ExprArithmetic),
977 "SH-056" => Some(Rule::PsGrepPipeline),
978 "SH-057" => Some(Rule::LsGrepPipeline),
979 "SH-062" => Some(Rule::UnquotedDollarStar),
980 "SH-063" => Some(Rule::QuotedDollarStarLoop),
981 "SH-067" => Some(Rule::UnquotedArraySplit),
982 "SH-068" => Some(Rule::CommandOutputArraySplit),
983 "SH-294" => Some(Rule::LeadingGlobInGrepPattern),
984 "SH-077" => Some(Rule::PositionalArgsInString),
985 "SH-064" => Some(Rule::GrepCountPipeline),
986 "SH-137" => Some(Rule::SingleTestSubshell),
987 "SH-164" => Some(Rule::SubshellTestGroup),
988 "SH-006" => Some(Rule::DoubleBracketInSh),
989 "SH-007" => Some(Rule::TestEqualityOperator),
990 "SH-093" => Some(Rule::IfElifBashTest),
991 "SH-108" => Some(Rule::ZshRedirPipe),
992 "SH-124" => Some(Rule::ZshBraceIf),
993 "SH-125" => Some(Rule::ZshAlwaysBlock),
994 "SH-140" => Some(Rule::SourcedWithArgs),
995 "SH-153" => Some(Rule::ZshFlagExpansion),
996 "SH-154" => Some(Rule::NestedZshSubstitution),
997 "SH-158" => Some(Rule::PlusEqualsAppend),
998 "SH-180" => Some(Rule::MultiVarForLoop),
999 "SH-181" => Some(Rule::FunctionBodyWithoutBraces),
1000 "SH-183" => Some(Rule::ZshPromptBracket),
1001 "SH-184" => Some(Rule::CshSyntaxInSh),
1002 "SH-218" => Some(Rule::ZshNestedExpansion),
1003 "SH-260" => Some(Rule::ZshAssignmentToZero),
1004 "SH-262" => Some(Rule::DollarStringInSh),
1005 "SH-263" => Some(Rule::CStyleForInSh),
1006 "SH-264" => Some(Rule::LegacyArithmeticInSh),
1007 "SH-269" => Some(Rule::CStyleForArithmeticInSh),
1008 "SH-278" => Some(Rule::ArrayKeysInSh),
1009 "SH-305" => Some(Rule::StarGlobRemovalInSh),
1010 "SH-286" => Some(Rule::ZshParameterFlag),
1011 "SH-299" => Some(Rule::ZshArraySubscriptInCase),
1012 "SH-303" => Some(Rule::ZshParameterIndexFlag),
1013 "SH-126" => Some(Rule::ArraySubscriptTest),
1014 "SH-127" => Some(Rule::ArraySubscriptCondition),
1015 "SH-174" => Some(Rule::ExtglobInTest),
1016 "SH-265" => Some(Rule::LexicalComparisonInDoubleBracket),
1017 "SH-266" => Some(Rule::RegexMatchInSh),
1018 "SH-267" => Some(Rule::VTestInSh),
1019 "SH-268" => Some(Rule::ATestInSh),
1020 "SH-280" => Some(Rule::OptionTestInSh),
1021 "SH-281" => Some(Rule::StickyBitTestInSh),
1022 "SH-282" => Some(Rule::OwnershipTestInSh),
1023 "SH-283" => Some(Rule::FindExecDirWithShell),
1024 "SH-314" => Some(Rule::LocalCrossReference),
1025 "SH-315" => Some(Rule::UnicodeSingleQuoteInSingleQuotes),
1026 "SH-319" => Some(Rule::SpacedAssignment),
1027 "SH-320" => Some(Rule::BadVarName),
1028 "SH-321" => Some(Rule::LoopWithoutEnd),
1029 "SH-322" => Some(Rule::MissingDoneInForLoop),
1030 "SH-327" => Some(Rule::DanglingElse),
1031 "SH-332" => Some(Rule::HeredocCloserNotAlone),
1032 "SH-333" => Some(Rule::MisquotedHeredocClose),
1033 "SH-334" => Some(Rule::UntilMissingDo),
1034 "SH-353" => Some(Rule::IfBracketGlued),
1035 _ => None,
1036 })
1037}
1038
1039#[cfg(test)]
1040mod tests {
1041 use super::*;
1042 use std::collections::BTreeSet;
1043
1044 #[test]
1045 fn rule_codes_are_unique() {
1046 let codes = Rule::iter().map(Rule::code).collect::<BTreeSet<_>>();
1047 assert_eq!(codes.len(), Rule::COUNT);
1048 }
1049
1050 #[test]
1051 fn resolves_legacy_shuck_aliases() {
1052 assert_eq!(code_to_rule("SH-001"), Some(Rule::UnquotedExpansion));
1053 assert_eq!(code_to_rule("SH-002"), Some(Rule::ReadWithoutRaw));
1054 assert_eq!(code_to_rule("SH-003"), Some(Rule::UnusedAssignment));
1055 assert_eq!(code_to_rule("SH-004"), Some(Rule::LoopFromCommandOutput));
1056 assert_eq!(
1057 code_to_rule("SH-005"),
1058 Some(Rule::UnquotedCommandSubstitution)
1059 );
1060 assert_eq!(code_to_rule("SH-010"), Some(Rule::BashCaseFallthrough));
1061 assert_eq!(code_to_rule("SH-013"), Some(Rule::StandaloneArithmetic));
1062 assert_eq!(code_to_rule("SH-014"), Some(Rule::SelectLoop));
1063 assert_eq!(code_to_rule("SH-019"), Some(Rule::Coproc));
1064 assert_eq!(code_to_rule("SH-034"), Some(Rule::LegacyBackticks));
1065 assert_eq!(
1066 code_to_rule("SH-035"),
1067 Some(Rule::LegacyArithmeticExpansion)
1068 );
1069 assert_eq!(code_to_rule("SH-055"), Some(Rule::ExprArithmetic));
1070 assert_eq!(code_to_rule("SH-056"), Some(Rule::PsGrepPipeline));
1071 assert_eq!(code_to_rule("SH-057"), Some(Rule::LsGrepPipeline));
1072 assert_eq!(code_to_rule("SH-107"), Some(Rule::FunctionParamsInSh));
1073 assert_eq!(code_to_rule("S014"), Some(Rule::UnquotedDollarStar));
1074 assert_eq!(code_to_rule("SH-062"), Some(Rule::UnquotedDollarStar));
1075 assert_eq!(code_to_rule("S015"), Some(Rule::QuotedDollarStarLoop));
1076 assert_eq!(code_to_rule("SH-063"), Some(Rule::QuotedDollarStarLoop));
1077 assert_eq!(code_to_rule("S017"), Some(Rule::UnquotedArraySplit));
1078 assert_eq!(code_to_rule("SH-067"), Some(Rule::UnquotedArraySplit));
1079 assert_eq!(code_to_rule("S018"), Some(Rule::CommandOutputArraySplit));
1080 assert_eq!(code_to_rule("SH-068"), Some(Rule::CommandOutputArraySplit));
1081 assert_eq!(code_to_rule("S067"), Some(Rule::LeadingGlobInGrepPattern));
1082 assert_eq!(code_to_rule("SH-294"), Some(Rule::LeadingGlobInGrepPattern));
1083 assert_eq!(code_to_rule("S068"), Some(Rule::TrapSignalNumbers));
1084 assert_eq!(code_to_rule("SH-297"), Some(Rule::TrapSignalNumbers));
1085 assert_eq!(code_to_rule("S069"), Some(Rule::GetoptsInvalidFlagHandler));
1086 assert_eq!(
1087 code_to_rule("SH-300"),
1088 Some(Rule::GetoptsInvalidFlagHandler)
1089 );
1090 assert_eq!(code_to_rule("S071"), Some(Rule::EnvPrefixCommandOnly));
1091 assert_eq!(code_to_rule("SH-309"), Some(Rule::EnvPrefixCommandOnly));
1092 assert_eq!(code_to_rule("S076"), Some(Rule::MixedQuoteWord));
1093 assert_eq!(code_to_rule("SH-350"), Some(Rule::MixedQuoteWord));
1094 assert_eq!(code_to_rule("S077"), Some(Rule::BraceVariableBeforeBracket));
1095 assert_eq!(
1096 code_to_rule("SH-354"),
1097 Some(Rule::BraceVariableBeforeBracket)
1098 );
1099 assert_eq!(code_to_rule("S021"), Some(Rule::PositionalArgsInString));
1100 assert_eq!(code_to_rule("SH-077"), Some(Rule::PositionalArgsInString));
1101 assert_eq!(code_to_rule("S020"), Some(Rule::SingleIterationLoop));
1102 assert_eq!(code_to_rule("SH-076"), Some(Rule::SingleIterationLoop));
1103 assert_eq!(code_to_rule("S032"), Some(Rule::BareCommandNameAssignment));
1104 assert_eq!(
1105 code_to_rule("SH-128"),
1106 Some(Rule::BareCommandNameAssignment)
1107 );
1108 assert_eq!(code_to_rule("SH-146"), Some(Rule::AssignSpecialZero));
1109 assert_eq!(code_to_rule("SH-147"), Some(Rule::SpaceyAssign));
1110 assert_eq!(code_to_rule("SH-064"), Some(Rule::GrepCountPipeline));
1111 assert_eq!(code_to_rule("SH-137"), Some(Rule::SingleTestSubshell));
1112 assert_eq!(code_to_rule("SH-164"), Some(Rule::SubshellTestGroup));
1113 assert_eq!(code_to_rule("S023"), Some(Rule::EscapedUnderscore));
1114 assert_eq!(code_to_rule("SH-082"), Some(Rule::EscapedUnderscore));
1115 assert_eq!(code_to_rule("S034"), Some(Rule::ArrayIndexArithmetic));
1116 assert_eq!(code_to_rule("SH-157"), Some(Rule::ArrayIndexArithmetic));
1117 assert_eq!(code_to_rule("S035"), Some(Rule::ArithmeticScoreLine));
1118 assert_eq!(code_to_rule("SH-161"), Some(Rule::ArithmeticScoreLine));
1119 assert_eq!(
1120 code_to_rule("SH-228"),
1121 Some(Rule::FunctionCalledWithoutArgs)
1122 );
1123 assert_eq!(
1124 code_to_rule("SH-292"),
1125 Some(Rule::FunctionReferencesUnsetParam)
1126 );
1127 assert_eq!(code_to_rule("S045"), Some(Rule::DollarInArithmetic));
1128 assert_eq!(code_to_rule("SH-197"), Some(Rule::DollarInArithmetic));
1129 assert_eq!(code_to_rule("S046"), Some(Rule::LsPipedToXargs));
1130 assert_eq!(code_to_rule("SH-198"), Some(Rule::LsPipedToXargs));
1131 assert_eq!(code_to_rule("S047"), Some(Rule::LsInSubstitution));
1132 assert_eq!(code_to_rule("SH-199"), Some(Rule::LsInSubstitution));
1133 assert_eq!(code_to_rule("S055"), Some(Rule::GlobAssignedToVariable));
1134 assert_eq!(code_to_rule("SH-231"), Some(Rule::GlobAssignedToVariable));
1135 assert_eq!(code_to_rule("SH-203"), Some(Rule::UnquotedTrRange));
1136 assert_eq!(code_to_rule("S024"), Some(Rule::SingleQuoteBackslash));
1137 assert_eq!(code_to_rule("SH-087"), Some(Rule::SingleQuoteBackslash));
1138 assert_eq!(code_to_rule("S052"), Some(Rule::UnquotedVariableInTest));
1139 assert_eq!(code_to_rule("SH-208"), Some(Rule::UnquotedTrClass));
1140 assert_eq!(code_to_rule("SH-212"), Some(Rule::UnquotedVariableInTest));
1141 assert_eq!(code_to_rule("S058"), Some(Rule::UnquotedPathInMkdir));
1142 assert_eq!(code_to_rule("S062"), Some(Rule::DefaultValueInColonAssign));
1143 assert_eq!(code_to_rule("S064"), Some(Rule::XargsWithInlineReplace));
1144 assert_eq!(code_to_rule("S011"), Some(Rule::CompoundTestOperator));
1145 assert_eq!(code_to_rule("S065"), Some(Rule::XPrefixInTest));
1146 assert_eq!(code_to_rule("SH-051"), Some(Rule::CompoundTestOperator));
1147 assert_eq!(
1148 code_to_rule("SH-251"),
1149 Some(Rule::DefaultValueInColonAssign)
1150 );
1151 assert_eq!(code_to_rule("SH-025"), Some(Rule::DynamicSourcePath));
1152 assert_eq!(code_to_rule("SH-256"), Some(Rule::XPrefixInTest));
1153 assert_eq!(
1154 code_to_rule("S039"),
1155 Some(Rule::LiteralBackslashInSingleQuotes)
1156 );
1157 assert_eq!(code_to_rule("S038"), Some(Rule::RedundantReturnStatus));
1158 assert_eq!(code_to_rule("SH-170"), Some(Rule::RedundantReturnStatus));
1159 assert_eq!(
1160 code_to_rule("SH-172"),
1161 Some(Rule::LiteralBackslashInSingleQuotes)
1162 );
1163 assert_eq!(code_to_rule("S026"), None);
1164 assert_eq!(code_to_rule("SH-092"), None);
1165 assert_eq!(code_to_rule("S040"), Some(Rule::LiteralControlEscape));
1166 assert_eq!(code_to_rule("SH-173"), Some(Rule::BackslashBeforeCommand));
1167 assert_eq!(code_to_rule("S041"), Some(Rule::FunctionBodyWithoutBraces));
1168 assert_eq!(
1169 code_to_rule("SH-181"),
1170 Some(Rule::FunctionBodyWithoutBraces)
1171 );
1172 assert_eq!(code_to_rule("S066"), Some(Rule::LocalDeclareCombined));
1173 assert_eq!(code_to_rule("SH-289"), Some(Rule::LocalDeclareCombined));
1174 assert_eq!(code_to_rule("SH-026"), Some(Rule::UntrackedSourceFile));
1175 assert_eq!(code_to_rule("SH-036"), Some(Rule::SingleQuotedLiteral));
1176 assert_eq!(code_to_rule("SH-037"), Some(Rule::PrintfFormatVariable));
1177 assert_eq!(code_to_rule("SH-038"), Some(Rule::UnquotedArrayExpansion));
1178 assert_eq!(code_to_rule("SH-039"), Some(Rule::UndefinedVariable));
1179 assert_eq!(
1180 code_to_rule("SH-040"),
1181 Some(Rule::EchoedCommandSubstitution)
1182 );
1183 assert_eq!(
1184 code_to_rule("SH-066"),
1185 Some(Rule::EchoInsideCommandSubstitution)
1186 );
1187 assert_eq!(code_to_rule("SH-168"), Some(Rule::RedundantSpacesInEcho));
1188 assert_eq!(code_to_rule("SH-196"), Some(Rule::EchoToSedSubstitution));
1189 assert_eq!(code_to_rule("SH-163"), Some(Rule::BareRead));
1190 assert_eq!(code_to_rule("SH-071"), Some(Rule::GrepOutputInTest));
1191 assert_eq!(code_to_rule("SH-041"), Some(Rule::FindOutputToXargs));
1192 assert_eq!(code_to_rule("SH-042"), Some(Rule::TrapStringExpansion));
1193 assert_eq!(code_to_rule("SH-043"), Some(Rule::QuotedBashRegex));
1194 assert_eq!(code_to_rule("SH-044"), Some(Rule::RmGlobOnVariablePath));
1195 assert_eq!(code_to_rule("SH-047"), Some(Rule::SshLocalExpansion));
1196 assert_eq!(code_to_rule("SH-324"), Some(Rule::RmRootishTarget));
1197 assert_eq!(
1198 code_to_rule("SH-325"),
1199 Some(Rule::ChmodWorldWritableSensitivePath)
1200 );
1201 assert_eq!(code_to_rule("SH-326"), Some(Rule::ForkBombPattern));
1202 assert_eq!(code_to_rule("SH-045"), Some(Rule::ChainedTestBranches));
1203 assert_eq!(code_to_rule("C079"), Some(Rule::ChainedTestBranches));
1204 assert_eq!(code_to_rule("SH-201"), Some(Rule::ChainedTestBranches));
1205 assert_eq!(code_to_rule("SH-046"), Some(Rule::LineOrientedInput));
1206 assert_eq!(code_to_rule("SH-049"), Some(Rule::FindOutputLoop));
1207 assert_eq!(
1208 code_to_rule("SH-050"),
1209 Some(Rule::ExportCommandSubstitution)
1210 );
1211 assert_eq!(code_to_rule("S033"), Some(Rule::EchoHereDoc));
1212 assert_eq!(code_to_rule("SH-135"), Some(Rule::EchoHereDoc));
1213 assert_eq!(code_to_rule("SH-052"), Some(Rule::LocalTopLevel));
1214 assert_eq!(code_to_rule("SH-060"), Some(Rule::SudoRedirectionOrder));
1215 assert_eq!(code_to_rule("SH-081"), Some(Rule::PrintfQFormatInSh));
1216 assert_eq!(code_to_rule("SH-275"), Some(Rule::ErrexitTrapInSh));
1217 assert_eq!(code_to_rule("SH-276"), Some(Rule::SignalNameInTrap));
1218 assert_eq!(code_to_rule("SH-277"), Some(Rule::BasePrefixInArithmetic));
1219 assert_eq!(code_to_rule("SH-069"), Some(Rule::ConstantComparisonTest));
1220 assert_eq!(code_to_rule("SH-070"), Some(Rule::LoopControlOutsideLoop));
1221 assert_eq!(code_to_rule("SH-072"), Some(Rule::LiteralUnaryStringTest));
1222 assert_eq!(code_to_rule("SH-073"), Some(Rule::TruthyLiteralTest));
1223 assert_eq!(code_to_rule("SH-074"), Some(Rule::ConstantCaseSubject));
1224 assert_eq!(code_to_rule("SH-075"), Some(Rule::EmptyTest));
1225 assert_eq!(code_to_rule("C023"), Some(Rule::LeadingZeroArithmetic));
1226 assert_eq!(code_to_rule("SH-078"), Some(Rule::LeadingZeroArithmetic));
1227 assert_eq!(code_to_rule("C024"), Some(Rule::AssignmentSpacing));
1228 assert_eq!(code_to_rule("SH-084"), Some(Rule::AssignmentSpacing));
1229 assert_eq!(code_to_rule("C030"), Some(Rule::MissingBracketSpace));
1230 assert_eq!(code_to_rule("SH-098"), Some(Rule::MissingBracketSpace));
1231 assert_eq!(
1232 code_to_rule("C031"),
1233 Some(Rule::MissingSpaceBeforeBracketClose)
1234 );
1235 assert_eq!(
1236 code_to_rule("SH-100"),
1237 Some(Rule::MissingSpaceBeforeBracketClose)
1238 );
1239 assert_eq!(code_to_rule("C032"), Some(Rule::JammedTestBracket));
1240 assert_eq!(code_to_rule("SH-102"), Some(Rule::JammedTestBracket));
1241 assert_eq!(code_to_rule("C033"), Some(Rule::IndentedHeredocClose));
1242 assert_eq!(code_to_rule("SH-104"), Some(Rule::IndentedHeredocClose));
1243 assert_eq!(code_to_rule("SH-134"), Some(Rule::PipeToKill));
1244 assert_eq!(code_to_rule("SH-086"), Some(Rule::PositionalTenBraces));
1245 assert_eq!(code_to_rule("C027"), Some(Rule::BareDoneWord));
1246 assert_eq!(code_to_rule("SH-091"), Some(Rule::BareDoneWord));
1247 assert_eq!(code_to_rule("C034"), Some(Rule::UnterminatedIf));
1248 assert_eq!(code_to_rule("SH-105"), Some(Rule::UnterminatedIf));
1249 assert_eq!(code_to_rule("C035"), Some(Rule::MissingFi));
1250 assert_eq!(code_to_rule("SH-106"), Some(Rule::MissingFi));
1251 assert_eq!(code_to_rule("C036"), Some(Rule::BrokenTestEnd));
1252 assert_eq!(code_to_rule("SH-109"), Some(Rule::BrokenTestEnd));
1253 assert_eq!(code_to_rule("C037"), Some(Rule::BrokenTestParse));
1254 assert_eq!(code_to_rule("SH-110"), Some(Rule::BrokenTestParse));
1255 assert_eq!(code_to_rule("SH-111"), Some(Rule::ExtglobCase));
1256 assert_eq!(code_to_rule("SH-182"), Some(Rule::ExtglobInCasePattern));
1257 assert_eq!(code_to_rule("SH-261"), Some(Rule::ExtglobInSh));
1258 assert_eq!(code_to_rule("SH-272"), Some(Rule::CaretNegationInBracket));
1259 assert_eq!(code_to_rule("C038"), Some(Rule::ElseIf));
1260 assert_eq!(code_to_rule("SH-112"), Some(Rule::ElseIf));
1261 assert_eq!(code_to_rule("C039"), Some(Rule::OpenDoubleQuote));
1262 assert_eq!(code_to_rule("SH-113"), Some(Rule::OpenDoubleQuote));
1263 assert_eq!(code_to_rule("S028"), Some(Rule::SuspectClosingQuote));
1264 assert_eq!(code_to_rule("SH-114"), Some(Rule::SuspectClosingQuote));
1265 assert_eq!(
1266 code_to_rule("SH-245"),
1267 Some(Rule::DeprecatedTempfileCommand)
1268 );
1269 assert_eq!(code_to_rule("SH-247"), Some(Rule::EgrepDeprecated));
1270 assert_eq!(code_to_rule("SH-248"), Some(Rule::FgrepDeprecated));
1271 assert_eq!(code_to_rule("SH-255"), Some(Rule::XargsWithInlineReplace));
1272 assert_eq!(code_to_rule("S029"), Some(Rule::LiteralBraces));
1273 assert_eq!(code_to_rule("SH-116"), Some(Rule::LiteralBraces));
1274 assert_eq!(code_to_rule("S030"), Some(Rule::HeredocEndSpace));
1275 assert_eq!(code_to_rule("SH-119"), Some(Rule::HeredocEndSpace));
1276 assert_eq!(code_to_rule("S031"), Some(Rule::TrailingDirective));
1277 assert_eq!(code_to_rule("SH-120"), Some(Rule::TrailingDirective));
1278 assert_eq!(code_to_rule("S072"), Some(Rule::LinebreakBeforeAnd));
1279 assert_eq!(code_to_rule("SH-329"), Some(Rule::LinebreakBeforeAnd));
1280 assert_eq!(code_to_rule("S073"), Some(Rule::SpacedTabstripClose));
1281 assert_eq!(code_to_rule("SH-330"), Some(Rule::SpacedTabstripClose));
1282 assert_eq!(code_to_rule("S074"), Some(Rule::AmpersandSemicolon));
1283 assert_eq!(code_to_rule("SH-335"), Some(Rule::AmpersandSemicolon));
1284 assert_eq!(code_to_rule("S075"), Some(Rule::CombineAppends));
1285 assert_eq!(code_to_rule("SH-349"), Some(Rule::CombineAppends));
1286 assert_eq!(code_to_rule("S085"), Some(Rule::MissingMainEntrypoint));
1287 assert_eq!(code_to_rule("C040"), Some(Rule::LinebreakInTest));
1288 assert_eq!(code_to_rule("SH-115"), Some(Rule::LinebreakInTest));
1289 assert_eq!(code_to_rule("C041"), Some(Rule::CStyleComment));
1290 assert_eq!(code_to_rule("SH-121"), Some(Rule::CStyleComment));
1291 assert_eq!(code_to_rule("C042"), Some(Rule::CPrototypeFragment));
1292 assert_eq!(code_to_rule("SH-123"), Some(Rule::CPrototypeFragment));
1293 assert_eq!(code_to_rule("C043"), Some(Rule::BadRedirectionFdOrder));
1294 assert_eq!(code_to_rule("SH-129"), Some(Rule::BadRedirectionFdOrder));
1295 assert_eq!(code_to_rule("C044"), Some(Rule::BareGlobCommandPath));
1296 assert_eq!(code_to_rule("SH-130"), Some(Rule::BareGlobCommandPath));
1297 assert_eq!(code_to_rule("C045"), Some(Rule::DiffMarkerLine));
1298 assert_eq!(code_to_rule("SH-133"), Some(Rule::DiffMarkerLine));
1299 assert_eq!(code_to_rule("C085"), Some(Rule::StderrBeforeStdoutRedirect));
1300 assert_eq!(code_to_rule("C094"), Some(Rule::RedirectClobbersInput));
1301 assert_eq!(
1302 code_to_rule("SH-211"),
1303 Some(Rule::StderrBeforeStdoutRedirect)
1304 );
1305 assert_eq!(code_to_rule("SH-222"), Some(Rule::RedirectClobbersInput));
1306 assert_eq!(code_to_rule("SH-141"), Some(Rule::InvalidExitStatus));
1307 assert_eq!(code_to_rule("SH-142"), Some(Rule::CasePatternVar));
1308 assert_eq!(code_to_rule("SH-143"), Some(Rule::TautologyChain));
1309 assert_eq!(
1310 code_to_rule("SH-144"),
1311 Some(Rule::ArithmeticRedirectionTarget)
1312 );
1313 assert_eq!(code_to_rule("SH-145"), Some(Rule::DuplicateRedirect));
1314 assert_eq!(code_to_rule("SH-148"), Some(Rule::BareSlashMarker));
1315 assert_eq!(code_to_rule("SH-151"), Some(Rule::EvalOnArray));
1316 assert_eq!(code_to_rule("SH-152"), Some(Rule::PatternWithVariable));
1317 assert_eq!(
1318 code_to_rule("SH-155"),
1319 Some(Rule::StatusCaptureAfterBranchTest)
1320 );
1321 assert_eq!(code_to_rule("SH-159"), Some(Rule::SubstWithRedirect));
1322 assert_eq!(code_to_rule("SH-160"), Some(Rule::SubstWithRedirectErr));
1323 assert_eq!(code_to_rule("SH-165"), Some(Rule::RedirectToCommandName));
1324 assert_eq!(code_to_rule("SH-166"), Some(Rule::NonAbsoluteShebang));
1325 assert_eq!(code_to_rule("SH-167"), Some(Rule::TemplateBraceInCommand));
1326 assert_eq!(code_to_rule("SH-169"), Some(Rule::NestedParameterExpansion));
1327 assert_eq!(code_to_rule("SH-171"), Some(Rule::OverwrittenFunction));
1328 assert_eq!(code_to_rule("SH-175"), Some(Rule::IfMissingThen));
1329 assert_eq!(code_to_rule("SH-176"), Some(Rule::ElseWithoutThen));
1330 assert_eq!(
1331 code_to_rule("SH-177"),
1332 Some(Rule::MissingSemicolonBeforeBrace)
1333 );
1334 assert_eq!(code_to_rule("SH-178"), Some(Rule::EmptyFunctionBody));
1335 assert_eq!(code_to_rule("SH-179"), Some(Rule::BareClosingBrace));
1336 assert_eq!(
1337 code_to_rule("SH-186"),
1338 Some(Rule::BackslashBeforeClosingBacktick)
1339 );
1340 assert_eq!(
1341 code_to_rule("SH-187"),
1342 Some(Rule::PositionalParamAsOperator)
1343 );
1344 assert_eq!(code_to_rule("SH-188"), Some(Rule::DoubleParenGrouping));
1345 assert_eq!(code_to_rule("SH-189"), Some(Rule::UnicodeQuoteInString));
1346 assert_eq!(code_to_rule("SH-190"), Some(Rule::MissingShebangLine));
1347 assert_eq!(code_to_rule("SH-191"), Some(Rule::IndentedShebang));
1348 assert_eq!(code_to_rule("SH-192"), Some(Rule::SpaceAfterHashBang));
1349 assert_eq!(code_to_rule("SH-193"), Some(Rule::ShebangNotOnFirstLine));
1350 assert_eq!(code_to_rule("SH-223"), Some(Rule::DuplicateShebangFlag));
1351 assert_eq!(code_to_rule("SH-079"), Some(Rule::AvoidLetBuiltin));
1352 assert_eq!(
1353 code_to_rule("SH-224"),
1354 Some(Rule::AssignmentLooksLikeComparison)
1355 );
1356 assert_eq!(code_to_rule("C096"), Some(Rule::SuspiciousBracketGlob));
1357 assert_eq!(code_to_rule("SH-225"), Some(Rule::SuspiciousBracketGlob));
1358 assert_eq!(code_to_rule("SH-227"), Some(Rule::SuWithoutFlag));
1359 assert_eq!(code_to_rule("SH-240"), Some(Rule::UnquotedPathInMkdir));
1360 assert_eq!(code_to_rule("SH-195"), Some(Rule::SubshellInArithmetic));
1361 assert_eq!(code_to_rule("C078"), Some(Rule::UnquotedGlobsInFind));
1362 assert_eq!(code_to_rule("SH-200"), Some(Rule::UnquotedGlobsInFind));
1363 assert_eq!(code_to_rule("C080"), Some(Rule::GlobInGrepPattern));
1364 assert_eq!(code_to_rule("SH-204"), Some(Rule::GlobInGrepPattern));
1365 assert_eq!(code_to_rule("C081"), Some(Rule::GlobInStringComparison));
1366 assert_eq!(code_to_rule("SH-206"), Some(Rule::GlobInStringComparison));
1367 assert_eq!(code_to_rule("C083"), Some(Rule::GlobInFindSubstitution));
1368 assert_eq!(code_to_rule("SH-209"), Some(Rule::GlobInFindSubstitution));
1369 assert_eq!(code_to_rule("C084"), Some(Rule::UnquotedGrepRegex));
1370 assert_eq!(code_to_rule("SH-210"), Some(Rule::UnquotedGrepRegex));
1371 assert_eq!(code_to_rule("C006"), Some(Rule::UndefinedVariable));
1372 assert_eq!(code_to_rule("SH-039"), Some(Rule::UndefinedVariable));
1373 assert_eq!(code_to_rule("C076"), Some(Rule::CommentedContinuationLine));
1374 assert_eq!(
1375 code_to_rule("SH-194"),
1376 Some(Rule::CommentedContinuationLine)
1377 );
1378 assert_eq!(code_to_rule("C098"), Some(Rule::SetFlagsWithoutDashes));
1379 assert_eq!(code_to_rule("SH-229"), Some(Rule::SetFlagsWithoutDashes));
1380 assert_eq!(code_to_rule("C099"), Some(Rule::QuotedArraySlice));
1381 assert_eq!(code_to_rule("SH-230"), Some(Rule::QuotedArraySlice));
1382 assert_eq!(code_to_rule("C100"), Some(Rule::QuotedBashSource));
1383 assert_eq!(code_to_rule("SH-232"), Some(Rule::QuotedBashSource));
1384 assert_eq!(
1385 code_to_rule("SH-233"),
1386 Some(Rule::CommandSubstitutionInAlias)
1387 );
1388 assert_eq!(code_to_rule("SH-235"), Some(Rule::FunctionInAlias));
1389 assert_eq!(code_to_rule("C103"), Some(Rule::FindOrWithoutGrouping));
1390 assert_eq!(code_to_rule("SH-237"), Some(Rule::FindOrWithoutGrouping));
1391 assert_eq!(code_to_rule("C104"), Some(Rule::NonShellSyntaxInScript));
1392 assert_eq!(code_to_rule("SH-238"), Some(Rule::NonShellSyntaxInScript));
1393 assert_eq!(code_to_rule("C105"), Some(Rule::ExportWithPositionalParams));
1394 assert_eq!(
1395 code_to_rule("SH-239"),
1396 Some(Rule::ExportWithPositionalParams)
1397 );
1398 assert_eq!(code_to_rule("C111"), Some(Rule::AtSignInStringCompare));
1399 assert_eq!(code_to_rule("SH-249"), Some(Rule::AtSignInStringCompare));
1400 assert_eq!(code_to_rule("C112"), Some(Rule::ArraySliceInComparison));
1401 assert_eq!(code_to_rule("SH-250"), Some(Rule::ArraySliceInComparison));
1402 assert_eq!(
1403 code_to_rule("C118"),
1404 Some(Rule::MalformedArithmeticInCondition)
1405 );
1406 assert_eq!(
1407 code_to_rule("SH-284"),
1408 Some(Rule::MalformedArithmeticInCondition)
1409 );
1410 assert_eq!(code_to_rule("C120"), Some(Rule::ExprSubstrInTest));
1411 assert_eq!(code_to_rule("SH-287"), Some(Rule::ExprSubstrInTest));
1412 assert_eq!(code_to_rule("C121"), Some(Rule::StringComparedWithEq));
1413 assert_eq!(code_to_rule("SH-288"), Some(Rule::StringComparedWithEq));
1414 assert_eq!(code_to_rule("C122"), Some(Rule::AFlagInDoubleBracket));
1415 assert_eq!(code_to_rule("SH-290"), Some(Rule::AFlagInDoubleBracket));
1416 assert_eq!(code_to_rule("C106"), Some(Rule::AppendToArrayAsString));
1417 assert_eq!(code_to_rule("SH-241"), Some(Rule::AppendToArrayAsString));
1418 assert_eq!(code_to_rule("C107"), Some(Rule::DollarQuestionAfterCommand));
1419 assert_eq!(
1420 code_to_rule("SH-242"),
1421 Some(Rule::DollarQuestionAfterCommand)
1422 );
1423 assert_eq!(
1424 code_to_rule("C108"),
1425 Some(Rule::UnsetAssociativeArrayElement)
1426 );
1427 assert_eq!(
1428 code_to_rule("SH-243"),
1429 Some(Rule::UnsetAssociativeArrayElement)
1430 );
1431 assert_eq!(code_to_rule("C109"), Some(Rule::MapfileProcessSubstitution));
1432 assert_eq!(
1433 code_to_rule("SH-244"),
1434 Some(Rule::MapfileProcessSubstitution)
1435 );
1436 assert_eq!(code_to_rule("C114"), Some(Rule::GlobWithExpansionInLoop));
1437 assert_eq!(code_to_rule("SH-254"), Some(Rule::GlobWithExpansionInLoop));
1438 assert_eq!(code_to_rule("C124"), Some(Rule::UnreachableAfterExit));
1439 assert_eq!(code_to_rule("SH-293"), Some(Rule::UnreachableAfterExit));
1440 assert_eq!(code_to_rule("C127"), Some(Rule::UnusedHeredoc));
1441 assert_eq!(code_to_rule("SH-298"), Some(Rule::UnusedHeredoc));
1442 assert_eq!(code_to_rule("C128"), Some(Rule::CaseGlobReachability));
1443 assert_eq!(code_to_rule("SH-301"), Some(Rule::CaseGlobReachability));
1444 assert_eq!(code_to_rule("C129"), Some(Rule::CaseDefaultBeforeGlob));
1445 assert_eq!(code_to_rule("SH-302"), Some(Rule::CaseDefaultBeforeGlob));
1446 assert_eq!(code_to_rule("C134"), Some(Rule::GetoptsOptionNotInCase));
1447 assert_eq!(code_to_rule("SH-312"), Some(Rule::GetoptsOptionNotInCase));
1448 assert_eq!(code_to_rule("C135"), Some(Rule::CaseArmNotInGetopts));
1449 assert_eq!(code_to_rule("SH-313"), Some(Rule::CaseArmNotInGetopts));
1450 assert_eq!(code_to_rule("C138"), Some(Rule::HeredocMissingEnd));
1451 assert_eq!(code_to_rule("SH-318"), Some(Rule::HeredocMissingEnd));
1452 assert_eq!(
1453 code_to_rule("C125"),
1454 Some(Rule::UncheckedDirectoryChangeInFunction)
1455 );
1456 assert_eq!(
1457 code_to_rule("SH-295"),
1458 Some(Rule::UncheckedDirectoryChangeInFunction)
1459 );
1460 assert_eq!(
1461 code_to_rule("C126"),
1462 Some(Rule::ContinueOutsideLoopInFunction)
1463 );
1464 assert_eq!(
1465 code_to_rule("SH-296"),
1466 Some(Rule::ContinueOutsideLoopInFunction)
1467 );
1468 assert_eq!(code_to_rule("C131"), Some(Rule::VariableAsCommandName));
1469 assert_eq!(code_to_rule("SH-308"), Some(Rule::VariableAsCommandName));
1470 assert_eq!(code_to_rule("C132"), Some(Rule::EnvPrefixExpansionOnly));
1471 assert_eq!(code_to_rule("SH-310"), Some(Rule::EnvPrefixExpansionOnly));
1472 assert_eq!(code_to_rule("C133"), Some(Rule::ArrayToStringConversion));
1473 assert_eq!(code_to_rule("SH-311"), Some(Rule::ArrayToStringConversion));
1474 assert_eq!(code_to_rule("C148"), Some(Rule::BrokenAssocKey));
1475 assert_eq!(code_to_rule("SH-337"), Some(Rule::BrokenAssocKey));
1476 assert_eq!(code_to_rule("SH-347"), Some(Rule::SubshellSideEffect));
1477 assert_eq!(code_to_rule("C150"), Some(Rule::SubshellLocalAssignment));
1478 assert_eq!(code_to_rule("SH-339"), Some(Rule::SubshellLocalAssignment));
1479 assert_eq!(code_to_rule("C151"), Some(Rule::CommaArrayElements));
1480 assert_eq!(code_to_rule("SH-340"), Some(Rule::CommaArrayElements));
1481 assert_eq!(
1482 code_to_rule("SH-351"),
1483 Some(Rule::PossibleVariableMisspelling)
1484 );
1485 assert_eq!(code_to_rule("SH-283"), Some(Rule::FindExecDirWithShell));
1486 assert_eq!(
1487 code_to_rule("C137"),
1488 Some(Rule::UnicodeSingleQuoteInSingleQuotes)
1489 );
1490 assert_eq!(
1491 code_to_rule("SH-315"),
1492 Some(Rule::UnicodeSingleQuoteInSingleQuotes)
1493 );
1494 assert_eq!(code_to_rule("C141"), Some(Rule::LoopWithoutEnd));
1495 assert_eq!(code_to_rule("SH-321"), Some(Rule::LoopWithoutEnd));
1496 assert_eq!(code_to_rule("C142"), Some(Rule::MissingDoneInForLoop));
1497 assert_eq!(code_to_rule("SH-322"), Some(Rule::MissingDoneInForLoop));
1498 assert_eq!(code_to_rule("C143"), Some(Rule::DanglingElse));
1499 assert_eq!(code_to_rule("SH-327"), Some(Rule::DanglingElse));
1500 assert_eq!(code_to_rule("C144"), Some(Rule::HeredocCloserNotAlone));
1501 assert_eq!(code_to_rule("SH-332"), Some(Rule::HeredocCloserNotAlone));
1502 assert_eq!(code_to_rule("C145"), Some(Rule::MisquotedHeredocClose));
1503 assert_eq!(code_to_rule("SH-333"), Some(Rule::MisquotedHeredocClose));
1504 assert_eq!(code_to_rule("C146"), Some(Rule::UntilMissingDo));
1505 assert_eq!(code_to_rule("SH-334"), Some(Rule::UntilMissingDo));
1506 assert_eq!(code_to_rule("C157"), Some(Rule::IfBracketGlued));
1507 assert_eq!(code_to_rule("SH-353"), Some(Rule::IfBracketGlued));
1508 assert_eq!(code_to_rule("X005"), Some(Rule::BashCaseFallthrough));
1509 assert_eq!(code_to_rule("X008"), Some(Rule::StandaloneArithmetic));
1510 assert_eq!(code_to_rule("X009"), Some(Rule::SelectLoop));
1511 assert_eq!(code_to_rule("X014"), Some(Rule::Coproc));
1512 assert_eq!(code_to_rule("X036"), Some(Rule::ZshRedirPipe));
1513 assert_eq!(code_to_rule("SH-108"), Some(Rule::ZshRedirPipe));
1514 assert_eq!(code_to_rule("X038"), Some(Rule::ZshBraceIf));
1515 assert_eq!(code_to_rule("SH-124"), Some(Rule::ZshBraceIf));
1516 assert_eq!(code_to_rule("X039"), Some(Rule::ZshAlwaysBlock));
1517 assert_eq!(code_to_rule("SH-125"), Some(Rule::ZshAlwaysBlock));
1518 assert_eq!(code_to_rule("X042"), Some(Rule::SourcedWithArgs));
1519 assert_eq!(code_to_rule("SH-140"), Some(Rule::SourcedWithArgs));
1520 assert_eq!(code_to_rule("X043"), Some(Rule::ZshFlagExpansion));
1521 assert_eq!(code_to_rule("SH-153"), Some(Rule::ZshFlagExpansion));
1522 assert_eq!(code_to_rule("X044"), Some(Rule::NestedZshSubstitution));
1523 assert_eq!(code_to_rule("SH-154"), Some(Rule::NestedZshSubstitution));
1524 assert_eq!(code_to_rule("X045"), Some(Rule::PlusEqualsAppend));
1525 assert_eq!(code_to_rule("SH-158"), Some(Rule::PlusEqualsAppend));
1526 assert_eq!(code_to_rule("X047"), Some(Rule::MultiVarForLoop));
1527 assert_eq!(code_to_rule("SH-180"), Some(Rule::MultiVarForLoop));
1528 assert_eq!(code_to_rule("X049"), Some(Rule::ZshPromptBracket));
1529 assert_eq!(code_to_rule("SH-183"), Some(Rule::ZshPromptBracket));
1530 assert_eq!(code_to_rule("X050"), Some(Rule::CshSyntaxInSh));
1531 assert_eq!(code_to_rule("SH-184"), Some(Rule::CshSyntaxInSh));
1532 assert_eq!(code_to_rule("X051"), Some(Rule::ZshNestedExpansion));
1533 assert_eq!(code_to_rule("SH-218"), Some(Rule::ZshNestedExpansion));
1534 assert_eq!(code_to_rule("X053"), Some(Rule::ZshAssignmentToZero));
1535 assert_eq!(code_to_rule("SH-260"), Some(Rule::ZshAssignmentToZero));
1536 assert_eq!(code_to_rule("X055"), Some(Rule::DollarStringInSh));
1537 assert_eq!(code_to_rule("SH-262"), Some(Rule::DollarStringInSh));
1538 assert_eq!(code_to_rule("X056"), Some(Rule::CStyleForInSh));
1539 assert_eq!(code_to_rule("SH-263"), Some(Rule::CStyleForInSh));
1540 assert_eq!(code_to_rule("X057"), Some(Rule::LegacyArithmeticInSh));
1541 assert_eq!(code_to_rule("SH-264"), Some(Rule::LegacyArithmeticInSh));
1542 assert_eq!(code_to_rule("X062"), Some(Rule::CStyleForArithmeticInSh));
1543 assert_eq!(code_to_rule("SH-269"), Some(Rule::CStyleForArithmeticInSh));
1544 assert_eq!(code_to_rule("X071"), Some(Rule::ArrayKeysInSh));
1545 assert_eq!(code_to_rule("SH-278"), Some(Rule::ArrayKeysInSh));
1546 assert_eq!(code_to_rule("X081"), Some(Rule::StarGlobRemovalInSh));
1547 assert_eq!(code_to_rule("SH-305"), Some(Rule::StarGlobRemovalInSh));
1548 assert_eq!(code_to_rule("X076"), Some(Rule::ZshParameterFlag));
1549 assert_eq!(code_to_rule("SH-286"), Some(Rule::ZshParameterFlag));
1550 assert_eq!(code_to_rule("X077"), Some(Rule::NestedDefaultExpansion));
1551 assert_eq!(code_to_rule("SH-291"), Some(Rule::NestedDefaultExpansion));
1552 assert_eq!(code_to_rule("X078"), Some(Rule::ZshArraySubscriptInCase));
1553 assert_eq!(code_to_rule("SH-299"), Some(Rule::ZshArraySubscriptInCase));
1554 assert_eq!(code_to_rule("X079"), Some(Rule::ZshParameterIndexFlag));
1555 assert_eq!(code_to_rule("SH-303"), Some(Rule::ZshParameterIndexFlag));
1556 assert_eq!(code_to_rule("X013"), Some(Rule::ArrayAssignment));
1557 assert_eq!(code_to_rule("SH-018"), Some(Rule::ArrayAssignment));
1558 assert_eq!(code_to_rule("X018"), Some(Rule::IndirectExpansion));
1559 assert_eq!(code_to_rule("SH-023"), Some(Rule::IndirectExpansion));
1560 assert_eq!(code_to_rule("X019"), Some(Rule::ArrayReference));
1561 assert_eq!(code_to_rule("SH-024"), Some(Rule::ArrayReference));
1562 assert_eq!(code_to_rule("X023"), Some(Rule::SubstringExpansion));
1563 assert_eq!(code_to_rule("SH-031"), Some(Rule::SubstringExpansion));
1564 assert_eq!(code_to_rule("X024"), Some(Rule::CaseModificationExpansion));
1565 assert_eq!(
1566 code_to_rule("SH-032"),
1567 Some(Rule::CaseModificationExpansion)
1568 );
1569 assert_eq!(code_to_rule("X025"), Some(Rule::ReplacementExpansion));
1570 assert_eq!(code_to_rule("SH-033"), Some(Rule::ReplacementExpansion));
1571 assert_eq!(code_to_rule("X026"), Some(Rule::BashFileSlurp));
1572 assert_eq!(code_to_rule("SH-053"), Some(Rule::BashFileSlurp));
1573 assert_eq!(code_to_rule("X027"), Some(Rule::EchoFlags));
1574 assert_eq!(code_to_rule("SH-054"), Some(Rule::EchoFlags));
1575 assert_eq!(code_to_rule("X028"), Some(Rule::TrLowerRange));
1576 assert_eq!(code_to_rule("SH-058"), Some(Rule::TrLowerRange));
1577 assert_eq!(code_to_rule("X029"), Some(Rule::TrUpperRange));
1578 assert_eq!(code_to_rule("SH-059"), Some(Rule::TrUpperRange));
1579 assert_eq!(code_to_rule("X030"), Some(Rule::EchoBackslashEscapes));
1580 assert_eq!(code_to_rule("SH-061"), Some(Rule::EchoBackslashEscapes));
1581 }
1582}