remlint 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +328 -0
  3. data/config/default.yml +374 -0
  4. data/docs/remlint-rules.md +390 -0
  5. data/docs/remlint.md +238 -0
  6. data/exe/remlint +8 -0
  7. data/lib/remlint/cli.rb +300 -0
  8. data/lib/remlint/command.rb +229 -0
  9. data/lib/remlint/config.rb +255 -0
  10. data/lib/remlint/date_literal.rb +283 -0
  11. data/lib/remlint/document.rb +161 -0
  12. data/lib/remlint/expr_lexer.rb +197 -0
  13. data/lib/remlint/extractors.rb +210 -0
  14. data/lib/remlint/formatter.rb +96 -0
  15. data/lib/remlint/invocation.rb +145 -0
  16. data/lib/remlint/logical_line.rb +194 -0
  17. data/lib/remlint/offense.rb +117 -0
  18. data/lib/remlint/rule.rb +216 -0
  19. data/lib/remlint/rules/addomit_without_scanfrom.rb +189 -0
  20. data/lib/remlint/rules/advance_warning_body.rb +176 -0
  21. data/lib/remlint/rules/banner_placement.rb +126 -0
  22. data/lib/remlint/rules/calendar_text_limited.rb +125 -0
  23. data/lib/remlint/rules/callback_signature.rb +221 -0
  24. data/lib/remlint/rules/clause_needs_full_date.rb +176 -0
  25. data/lib/remlint/rules/clause_requires_at.rb +178 -0
  26. data/lib/remlint/rules/clause_value_range.rb +257 -0
  27. data/lib/remlint/rules/color_component_range.rb +295 -0
  28. data/lib/remlint/rules/coordinate_not_string.rb +175 -0
  29. data/lib/remlint/rules/dangling_continuation.rb +134 -0
  30. data/lib/remlint/rules/date_out_of_range.rb +180 -0
  31. data/lib/remlint/rules/debug_command.rb +189 -0
  32. data/lib/remlint/rules/easterdate_from_today.rb +160 -0
  33. data/lib/remlint/rules/function_arity.rb +385 -0
  34. data/lib/remlint/rules/function_redefinition.rb +159 -0
  35. data/lib/remlint/rules/generated_file_edited.rb +125 -0
  36. data/lib/remlint/rules/hebrew_date.rb +245 -0
  37. data/lib/remlint/rules/iftrig_with_satisfy.rb +101 -0
  38. data/lib/remlint/rules/include_path.rb +155 -0
  39. data/lib/remlint/rules/info_clause.rb +186 -0
  40. data/lib/remlint/rules/info_substitution_without_header.rb +169 -0
  41. data/lib/remlint/rules/invocation_mismatch.rb +223 -0
  42. data/lib/remlint/rules/keyword_case.rb +172 -0
  43. data/lib/remlint/rules/license_header.rb +101 -0
  44. data/lib/remlint/rules/line_length.rb +101 -0
  45. data/lib/remlint/rules/literal_type_mismatch.rb +324 -0
  46. data/lib/remlint/rules/localization_pack.rb +144 -0
  47. data/lib/remlint/rules/moon_phase_argument.rb +162 -0
  48. data/lib/remlint/rules/omit_aware_delta.rb +168 -0
  49. data/lib/remlint/rules/push_vars_missing_name.rb +158 -0
  50. data/lib/remlint/rules/repeat_trigger.rb +188 -0
  51. data/lib/remlint/rules/satisfy_constraint.rb +230 -0
  52. data/lib/remlint/rules/shell_maxlen.rb +170 -0
  53. data/lib/remlint/rules/shell_use_while_run_disabled.rb +172 -0
  54. data/lib/remlint/rules/string_escape.rb +158 -0
  55. data/lib/remlint/rules/syntax.rb +229 -0
  56. data/lib/remlint/rules/system_variable_assignment.rb +197 -0
  57. data/lib/remlint/rules/tag_syntax.rb +145 -0
  58. data/lib/remlint/rules/text_after_eof_marker.rb +134 -0
  59. data/lib/remlint/rules/time_zone_name.rb +212 -0
  60. data/lib/remlint/rules/tk_tag_namespace.rb +121 -0
  61. data/lib/remlint/rules/todo_complete_through.rb +122 -0
  62. data/lib/remlint/rules/trailing_whitespace.rb +116 -0
  63. data/lib/remlint/rules/translate_command.rb +203 -0
  64. data/lib/remlint/rules/unbalanced_blocks.rb +305 -0
  65. data/lib/remlint/rules/unbalanced_delimiters.rb +251 -0
  66. data/lib/remlint/rules/unknown_special_type.rb +155 -0
  67. data/lib/remlint/rules/unknown_substitution_sequence.rb +255 -0
  68. data/lib/remlint/rules/unknown_system_variable.rb +145 -0
  69. data/lib/remlint/rules/unquoted_shell_substitution.rb +266 -0
  70. data/lib/remlint/rules/until_before_from.rb +204 -0
  71. data/lib/remlint/rules/world_writable_script.rb +128 -0
  72. data/lib/remlint/rules.rb +60 -0
  73. data/lib/remlint/runner.rb +274 -0
  74. data/lib/remlint/source.rb +36 -0
  75. data/lib/remlint/tables.rb +395 -0
  76. data/lib/remlint/trigger.rb +359 -0
  77. data/lib/remlint/version.rb +5 -0
  78. data/lib/remlint/vocabulary.rb +236 -0
  79. data/lib/remlint.rb +35 -0
  80. data/tasks/generate_tables.rb +175 -0
  81. metadata +170 -0
@@ -0,0 +1,374 @@
1
+ # RemLint's shipped defaults. A project's own .remlint.yml is merged over this
2
+ # key by key, so setting one option on one rule leaves everything else alone.
3
+ #
4
+ # Every rule understands `Enabled` and `Severity`; the rules with further
5
+ # options list them below. Run `remlint --show-rules` to see what is on.
6
+ #
7
+ # The default split: a rule reports something Remind itself would call an
8
+ # error, or it is off. Style preferences are opt-in, because a linter whose
9
+ # first run is a wall of cosmetic noise is a linter that gets switched off.
10
+
11
+ # Paths never linted, as shell globs against the path as given.
12
+ Exclude: []
13
+
14
+ # ---------------------------------------------------------------------------
15
+ # On by default: things Remind rejects, or that break its output.
16
+ # ---------------------------------------------------------------------------
17
+
18
+ # Whitespace at the end of a line. remind.vim highlights this as an Error --
19
+ # "This will match trailing whitespaces that seem to break rem2ps".
20
+ TrailingWhitespace:
21
+ Enabled: true
22
+ Severity: error
23
+
24
+ # A backslash that looks like a line continuation and is not, because it has a
25
+ # space after it, or because the file ends before the continuation does.
26
+ DanglingContinuation:
27
+ Enabled: true
28
+ Severity: error
29
+
30
+ # IF/IFTRIG/ENDIF, ELSE, and the PUSH/POP context stacks that do not pair up.
31
+ UnbalancedBlocks:
32
+ Enabled: true
33
+ Severity: error
34
+
35
+ # Brackets and parentheses that never close, or that close each other. Remind's
36
+ # own E_MISS_END and E_MISS_RIGHT_PAREN, reported without running the file.
37
+ UnbalancedDelimiters:
38
+ Enabled: true
39
+ Severity: error
40
+
41
+ # Calls with the wrong number of arguments, checked against Remind's function
42
+ # table and against the FSET definitions in the file itself.
43
+ FunctionArity:
44
+ Enabled: true
45
+ Severity: error
46
+
47
+ # A $SysVar that is not one of Remind's. Its namespace is closed, so a name
48
+ # that is not in the table is E_NOSUCH_VAR rather than an empty variable.
49
+ UnknownSystemVariable:
50
+ Enabled: true
51
+ Severity: error
52
+ # Extra $-prefixed names to accept, for a file that is fed variables from
53
+ # outside -- `remind -i$Latitude=...` and the like.
54
+ AllowedNames: []
55
+
56
+ # SET or UNSET on a read-only system variable, or a literal value outside the
57
+ # range Remind's table declares for it.
58
+ SystemVariableAssignment:
59
+ Enabled: true
60
+ Severity: error
61
+
62
+ # Colour components outside 0-255, in SPECIAL COLOR, SPECIAL SHADE and
63
+ # ansicolor(). Remind errors on these; rem2ps silently clamps them.
64
+ ColorComponentRange:
65
+ Enabled: true
66
+ Severity: error
67
+
68
+ # Reminder text pasted into a RUN or INCLUDECMD body outside shell quotes.
69
+ # The body goes through the substitution filter and the result is handed to
70
+ # /bin/sh, so a substitution is a hole in a shell command and what lands in it
71
+ # is data. An apostrophe is the polite failure.
72
+ UnquotedShellSubstitution:
73
+ Enabled: true
74
+ Severity: error
75
+
76
+ # DURATION or TZ on a reminder with no AT clause. A duration needs a start
77
+ # time; a bare date has no instant to convert between zones.
78
+ ClauseRequiresAt:
79
+ Enabled: true
80
+ Severity: error
81
+
82
+ # SATISFY inside an IFTRIG. IFTRIG takes every clause REM does except that
83
+ # one, which is easy to miss when a working REM is copied into an IFTRIG.
84
+ IftrigWithSatisfy:
85
+ Enabled: true
86
+ Severity: error
87
+
88
+ # A % sequence Remind does not substitute, or an argument form left unclosed.
89
+ # Every letter and digit is a real sequence, so this is mostly about
90
+ # punctuation -- but the failure is silent: Remind drops the % and prints the
91
+ # character.
92
+ UnknownSubstitutionSequence:
93
+ Enabled: true
94
+ Severity: warning
95
+
96
+ # A %<Header> reference with no INFO clause of that name on the same command.
97
+ # It expands to nothing, so the reminder reads like a truncation bug.
98
+ InfoSubstitutionWithoutHeader:
99
+ Enabled: true
100
+ Severity: warning
101
+
102
+ # Commands below a line reading exactly __EOF__, which Remind never reads.
103
+ # The marker is a debugging convenience; the failure is leaving it in.
104
+ TextAfterEofMarker:
105
+ Enabled: true
106
+ Severity: warning
107
+
108
+ # An UNTIL or THROUGH date earlier than the FROM or SCANFROM it belongs with.
109
+ # Remind warns about this one itself, at parse time; the linter says it in the
110
+ # editor and in CI instead of only on stderr when someone runs the file.
111
+ UntilBeforeFrom:
112
+ Enabled: true
113
+ Severity: error
114
+
115
+ # $Latitude or $Longitude set to a bare number. Remind has no floating-point
116
+ # type, so the coordinate has to arrive as a STRING; the failure is a
117
+ # confidently wrong sunrise time rather than an error.
118
+ CoordinateNotString:
119
+ Enabled: true
120
+ Severity: error
121
+
122
+ # A function calling shell(), defined between RUN OFF and RUN ON. The
123
+ # permission binds at definition, so the function fails even when it is called
124
+ # later with RUN back on -- and the error names the call site, which is the one
125
+ # place the mistake is not.
126
+ ShellUseWhileRunDisabled:
127
+ Enabled: true
128
+ Severity: error
129
+
130
+ # A comparison between literals of different types. Remind makes == a constant
131
+ # 0 and != a constant 1 across types, silently; ordering raises Type mismatch.
132
+ LiteralTypeMismatch:
133
+ Enabled: true
134
+ Severity: error
135
+
136
+ # An AT, DURATION, PRIORITY or MAX-OVERDUE value outside its range. Remind
137
+ # rejects each, but only on the day the line is reached.
138
+ ClauseValueRange:
139
+ Enabled: true
140
+ Severity: error
141
+
142
+ # A date outside 1990-01-01 to 5990-12-31, or with an impossible component.
143
+ # BASE + YR_RANGE make that range the type rather than a policy.
144
+ DateOutOfRange:
145
+ Enabled: true
146
+ Severity: error
147
+
148
+ # FROM, UNTIL, THROUGH or COMPLETE-THROUGH given a partial date. GetFullDate
149
+ # needs all three components; a TODO with an unusable COMPLETE-THROUGH starts
150
+ # its whole calculation at 1990-01-01.
151
+ ClauseNeedsFullDate:
152
+ Enabled: true
153
+ Severity: error
154
+
155
+ # A *n repeat with no start date to count from, or with a weekday that only
156
+ # picks the start date and is then ignored by the recurrence.
157
+ RepeatTrigger:
158
+ Enabled: true
159
+ Severity: warning
160
+
161
+ # An INFO clause that is malformed or repeats another's header. Headers are
162
+ # not case-sensitive, so Url: and URL: on one command collide.
163
+ InfoClause:
164
+ Enabled: true
165
+ Severity: warning
166
+
167
+ # A TAG containing a comma or whitespace. Tags reach back-ends as a
168
+ # comma-separated list, so a comma inside one splits it in two.
169
+ TagSyntax:
170
+ Enabled: true
171
+ Severity: warning
172
+
173
+ # A second BANNER, which silently replaces the first, or one written below the
174
+ # reminders it appears to apply to.
175
+ BannerPlacement:
176
+ Enabled: true
177
+ Severity: warning
178
+
179
+ # A SPECIAL type no shipped back-end parses. Remind passes any SPECIAL
180
+ # through and a back-end must ignore what it cannot read, so a typo produces
181
+ # no output and no error.
182
+ UnknownSpecialType:
183
+ Enabled: true
184
+ Severity: warning
185
+ # Extra types to accept, for a project with its own back-end.
186
+ AllowedTypes: []
187
+
188
+ # A backslash escape Remind does not define, which drops the backslash
189
+ # silently, or the prohibited \x00.
190
+ StringEscape:
191
+ Enabled: true
192
+ Severity: warning
193
+
194
+ # A DEBUG flag Remind does not define, or one switched on and never off --
195
+ # which turns every later run, including the cron one, into a trace log.
196
+ DebugCommand:
197
+ Enabled: true
198
+ Severity: warning
199
+
200
+ # shell() given a maximum length of zero, which returns the empty string
201
+ # whatever the command printed.
202
+ ShellMaxlen:
203
+ Enabled: true
204
+ Severity: warning
205
+
206
+ # A function redefined without the FSET - form that says the redefinition is
207
+ # deliberate. Remind warns; this says where the `-` goes.
208
+ FunctionRedefinition:
209
+ Enabled: true
210
+ Severity: warning
211
+
212
+ # A variable SET inside a PUSH-VARS block the PUSH-VARS never named, so the
213
+ # assignment survives the POP -- the one thing the block was there to stop.
214
+ PushVarsMissingName:
215
+ Enabled: true
216
+ Severity: warning
217
+
218
+ # A Remind callback defined with the wrong arity. Remind checks the shape and
219
+ # walks away, so the callback is simply never called.
220
+ CallbackSignature:
221
+ Enabled: true
222
+ Severity: warning
223
+
224
+ # INCLUDE with a relative path, which resolves against the working directory
225
+ # rather than the file's, or SYSINCLUDE with an absolute one.
226
+ IncludePath:
227
+ Enabled: true
228
+ Severity: warning
229
+
230
+ # easterdate(today()) in a trigger with an offset. On the day itself the
231
+ # function has already jumped a year ahead, so the reminder never fires.
232
+ EasterdateFromToday:
233
+ Enabled: true
234
+ Severity: warning
235
+
236
+ # A TZ name the zone database does not have, or one differing only in case.
237
+ # Reads /usr/share/zoneinfo; reports nothing where there is none to read.
238
+ TimeZoneName:
239
+ Enabled: true
240
+ Severity: warning
241
+ # Where to look, if not TZDIR or /usr/share/zoneinfo.
242
+ Directory: ~
243
+
244
+ # A reminder file anyone can write to. Remind refuses a world-writable script
245
+ # outright; the mode is invisible in every editor.
246
+ WorldWritableScript:
247
+ Enabled: true
248
+ Severity: error
249
+
250
+ # A TODO with MAX-OVERDUE and no COMPLETE-THROUGH. The calculation then starts
251
+ # at Remind's epoch, the task is decades overdue, and MAX-OVERDUE suppresses
252
+ # it -- so the reminder never appears at all.
253
+ TodoCompleteThrough:
254
+ Enabled: true
255
+ Severity: warning
256
+
257
+ # ADDOMIT with no SCANFROM, which adds next year's date once the day itself
258
+ # has passed -- so reminders skipping around the holiday are wrong from the
259
+ # day after it. Remind 06.01.03+ warns; this says it without running.
260
+ AddomitWithoutScanfrom:
261
+ Enabled: true
262
+ Severity: warning
263
+ # Ask for a minimum SCANFROM window as well. Zero accepts any. Chapter 4
264
+ # works through 28 days and include/holidays/us.rem uses that, but
265
+ # examples/defs.rem uses -7 throughout -- a smaller guarantee, not a bug.
266
+ MinimumWindow: 0
267
+
268
+ # A TRANSLATE that is none of Remind's five forms, or whose translated string
269
+ # does not carry the same % escapes in the same order as the original --
270
+ # which Remind rejects, leaving the message in English.
271
+ TranslateCommand:
272
+ Enabled: true
273
+ Severity: warning
274
+
275
+ # A Hebrew month Remind does not know, or a day past that month's length. The
276
+ # lengths were established by asking Remind across seven years, because
277
+ # Heshvan and Kislev vary with the year.
278
+ HebrewDate:
279
+ Enabled: true
280
+ Severity: error
281
+
282
+ # A moon phase or solstice selector outside the four values it accepts.
283
+ MoonPhaseArgument:
284
+ Enabled: true
285
+ Severity: error
286
+
287
+ # A hand-written TAG in TkRemind's TKTAGn namespace, which makes the GUI edit
288
+ # the wrong reminder with no diagnostic at all.
289
+ TkTagNamespace:
290
+ Enabled: true
291
+ Severity: warning
292
+
293
+ # Things a file does that its declared `# remlint:invocation` will not
294
+ # deliver: an unreadable -g sort spec, INFO under plain -p, TODO in a
295
+ # calendar. Silent for a file that declares no invocation.
296
+ InvocationMismatch:
297
+ Enabled: true
298
+ Severity: warning
299
+
300
+ # A language pack that never translates LANGID, so every script branching on
301
+ # `_("LANGID")` takes the English path. A pack is recognised by its day and
302
+ # month names; a file translating a handful of strings is not one.
303
+ LocalizationPack:
304
+ Enabled: true
305
+ Severity: info
306
+
307
+ # Hand-written commands in a file a tool owns and rewrites. Says nothing
308
+ # until GeneratedFiles lists something -- the linter cannot guess a layout.
309
+ GeneratedFileEdited:
310
+ Enabled: true
311
+ Severity: warning
312
+ GeneratedFiles: []
313
+
314
+ # ---------------------------------------------------------------------------
315
+ # Off by default: house style, and the one rule that executes the file.
316
+ # ---------------------------------------------------------------------------
317
+
318
+ # A SATISFY constraint the trigger could name directly, one no date can
319
+ # satisfy, or a year bound that wants to be an UNTIL. The book measures the
320
+ # first: 13.2M expression evaluations become 482K, and 2.30s becomes 0.58s.
321
+ SatisfyConstraint:
322
+ Enabled: false
323
+ Severity: info
324
+
325
+ # A reminder with a delta or an AT whose body never says when the event is.
326
+ # Pairs with CalendarTextLimited: this one asks for %b, that one fences it.
327
+ AdvanceWarningBody:
328
+ Enabled: false
329
+ Severity: info
330
+
331
+ # A relative-date substitution with no %" ... %" limit, so it follows the
332
+ # reminder into a calendar box where it is wrong.
333
+ CalendarTextLimited:
334
+ Enabled: false
335
+ Severity: info
336
+
337
+ # A single-sign delta in a file that omits nothing, where it is exactly the
338
+ # doubled form -- so either the sign or an OMIT is missing.
339
+ OmitAwareDelta:
340
+ Enabled: false
341
+ Severity: info
342
+
343
+ # Command keywords in a case other than the file's own. Off because
344
+ # examples/alignment.rem deliberately mixes MSG and msg to show they are the
345
+ # same thing. EnforcedStyle: upper, lower, or consistent (the file's majority).
346
+ KeywordCase:
347
+ Enabled: false
348
+ Severity: info
349
+ EnforcedStyle: upper
350
+
351
+ # Physical lines past Max characters. Measured before continuations are joined,
352
+ # so a command that was split to stay inside the margin is not penalised for it.
353
+ LineLength:
354
+ Enabled: false
355
+ Severity: info
356
+ Max: 100
357
+
358
+ # A licence identifier near the top of the file. Off because it is a project
359
+ # policy, not a Remind fact -- but it is a policy Remind's own examples keep.
360
+ LicenseHeader:
361
+ Enabled: false
362
+ Severity: info
363
+ Pattern: 'SPDX-License-Identifier:\s*\S+'
364
+ WithinLines: 10
365
+
366
+ # Remind's own diagnostics, from running the file through Remind.
367
+ #
368
+ # OFF, AND DELIBERATELY SO. Remind has no parse-only mode, so this runs the
369
+ # file. `-r` is passed to disable RUN directives, but INCLUDE still reads and
370
+ # INCLUDECMD still executes. Turn it on for files you trust.
371
+ Syntax:
372
+ Enabled: false
373
+ Severity: error
374
+ Command: remind