gurkencheck 0.0.6 → 0.0.9

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 (120) hide show
  1. package/README.md +134 -3
  2. package/dist/config-parser.d.ts.map +1 -1
  3. package/dist/config-parser.js +7 -1
  4. package/dist/config-parser.js.map +1 -1
  5. package/dist/diagnostics.d.ts +34 -0
  6. package/dist/diagnostics.d.ts.map +1 -0
  7. package/dist/diagnostics.js +53 -0
  8. package/dist/diagnostics.js.map +1 -0
  9. package/dist/exit-codes.d.ts +10 -0
  10. package/dist/exit-codes.d.ts.map +1 -0
  11. package/dist/exit-codes.js +10 -0
  12. package/dist/exit-codes.js.map +1 -0
  13. package/dist/feature-finder.d.ts +38 -0
  14. package/dist/feature-finder.d.ts.map +1 -1
  15. package/dist/feature-finder.js +86 -8
  16. package/dist/feature-finder.js.map +1 -1
  17. package/dist/formatters/index.d.ts +44 -4
  18. package/dist/formatters/index.d.ts.map +1 -1
  19. package/dist/formatters/index.js +52 -15
  20. package/dist/formatters/index.js.map +1 -1
  21. package/dist/formatters/stylish.d.ts +3 -0
  22. package/dist/formatters/stylish.d.ts.map +1 -1
  23. package/dist/formatters/stylish.js +32 -1
  24. package/dist/formatters/stylish.js.map +1 -1
  25. package/dist/formatters/tap.d.ts +14 -0
  26. package/dist/formatters/tap.d.ts.map +1 -1
  27. package/dist/formatters/tap.js +22 -7
  28. package/dist/formatters/tap.js.map +1 -1
  29. package/dist/gherkin/parse.d.ts +42 -1
  30. package/dist/gherkin/parse.d.ts.map +1 -1
  31. package/dist/gherkin/parse.js +68 -3
  32. package/dist/gherkin/parse.js.map +1 -1
  33. package/dist/index.d.ts +27 -9
  34. package/dist/index.d.ts.map +1 -1
  35. package/dist/index.js +15 -5
  36. package/dist/index.js.map +1 -1
  37. package/dist/linter.d.ts +31 -3
  38. package/dist/linter.d.ts.map +1 -1
  39. package/dist/linter.js +82 -15
  40. package/dist/linter.js.map +1 -1
  41. package/dist/logger.d.ts +2 -0
  42. package/dist/logger.d.ts.map +1 -1
  43. package/dist/logger.js +4 -0
  44. package/dist/logger.js.map +1 -1
  45. package/dist/main.d.ts +9 -1
  46. package/dist/main.d.ts.map +1 -1
  47. package/dist/main.js +158 -31
  48. package/dist/main.js.map +1 -1
  49. package/dist/rules/no-dupe-feature-names.d.ts.map +1 -1
  50. package/dist/rules/no-dupe-feature-names.js +26 -13
  51. package/dist/rules/no-dupe-feature-names.js.map +1 -1
  52. package/dist/rules/no-dupe-file-names.d.ts.map +1 -1
  53. package/dist/rules/no-dupe-file-names.js +32 -17
  54. package/dist/rules/no-dupe-file-names.js.map +1 -1
  55. package/dist/rules/no-dupe-scenario-names.d.ts.map +1 -1
  56. package/dist/rules/no-dupe-scenario-names.js +34 -22
  57. package/dist/rules/no-dupe-scenario-names.js.map +1 -1
  58. package/dist/rules.d.ts +41 -3
  59. package/dist/rules.d.ts.map +1 -1
  60. package/dist/rules.js +112 -4
  61. package/dist/rules.js.map +1 -1
  62. package/dist/stats/collect.d.ts +31 -0
  63. package/dist/stats/collect.d.ts.map +1 -0
  64. package/dist/stats/collect.js +249 -0
  65. package/dist/stats/collect.js.map +1 -0
  66. package/dist/stats/command.d.ts +4 -0
  67. package/dist/stats/command.d.ts.map +1 -0
  68. package/dist/stats/command.js +113 -0
  69. package/dist/stats/command.js.map +1 -0
  70. package/dist/stats/format/index.d.ts +25 -0
  71. package/dist/stats/format/index.d.ts.map +1 -0
  72. package/dist/stats/format/index.js +25 -0
  73. package/dist/stats/format/index.js.map +1 -0
  74. package/dist/stats/format/json.d.ts +10 -0
  75. package/dist/stats/format/json.d.ts.map +1 -0
  76. package/dist/stats/format/json.js +5 -0
  77. package/dist/stats/format/json.js.map +1 -0
  78. package/dist/stats/format/markdown.d.ts +8 -0
  79. package/dist/stats/format/markdown.d.ts.map +1 -0
  80. package/dist/stats/format/markdown.js +123 -0
  81. package/dist/stats/format/markdown.js.map +1 -0
  82. package/dist/stats/format/shared.d.ts +34 -0
  83. package/dist/stats/format/shared.d.ts.map +1 -0
  84. package/dist/stats/format/shared.js +37 -0
  85. package/dist/stats/format/shared.js.map +1 -0
  86. package/dist/stats/format/text.d.ts +5 -0
  87. package/dist/stats/format/text.d.ts.map +1 -0
  88. package/dist/stats/format/text.js +175 -0
  89. package/dist/stats/format/text.js.map +1 -0
  90. package/dist/stats/index.d.ts +21 -0
  91. package/dist/stats/index.d.ts.map +1 -0
  92. package/dist/stats/index.js +17 -0
  93. package/dist/stats/index.js.map +1 -0
  94. package/dist/stats/normalise.d.ts +38 -0
  95. package/dist/stats/normalise.d.ts.map +1 -0
  96. package/dist/stats/normalise.js +65 -0
  97. package/dist/stats/normalise.js.map +1 -0
  98. package/dist/stats/similar.d.ts +61 -0
  99. package/dist/stats/similar.d.ts.map +1 -0
  100. package/dist/stats/similar.js +173 -0
  101. package/dist/stats/similar.js.map +1 -0
  102. package/dist/stats/types.d.ts +159 -0
  103. package/dist/stats/types.d.ts.map +1 -0
  104. package/dist/stats/types.js +10 -0
  105. package/dist/stats/types.js.map +1 -0
  106. package/dist/types.d.ts +47 -3
  107. package/dist/types.d.ts.map +1 -1
  108. package/dist/util/glob.d.ts +18 -0
  109. package/dist/util/glob.d.ts.map +1 -1
  110. package/dist/util/glob.js +126 -22
  111. package/dist/util/glob.js.map +1 -1
  112. package/dist/util/stream.d.ts +31 -0
  113. package/dist/util/stream.d.ts.map +1 -0
  114. package/dist/util/stream.js +67 -0
  115. package/dist/util/stream.js.map +1 -0
  116. package/dist/watch.d.ts +36 -0
  117. package/dist/watch.d.ts.map +1 -0
  118. package/dist/watch.js +203 -0
  119. package/dist/watch.js.map +1 -0
  120. package/package.json +1 -1
package/README.md CHANGED
@@ -73,14 +73,19 @@ gurkencheck [options] <feature-files>
73
73
  -i, --ignore <globs> comma separated globs to skip, overriding .gurkencheckignore
74
74
  -r, --rulesdir <dir> directory of custom rules; may be given more than once
75
75
  -l, --language <code> dialect for files with no "# language:" header
76
+ -w, --watch keep running, checking again whenever a file changes
76
77
  -h, --help show this message
77
78
  -v, --version show the version number
79
+
80
+ Commands:
81
+ stats [paths] report on the shape of your feature files,
82
+ rather than on what is wrong with them
78
83
  ```
79
84
 
80
85
  ## Rules
81
86
 
82
- There are 33 rules you switch on, covering naming, tags, indentation, structure and size,
83
- plus four that are always on because Gherkin itself refuses to read a file that breaks
87
+ There are 36 rules you switch on, covering naming, tags, indentation, structure and size,
88
+ plus five that are always on because Gherkin itself refuses to read a file that breaks
84
89
  them. Each one is documented at
85
90
  **[sebs.github.io/gurkencheck](https://sebs.github.io/gurkencheck/)** with a
86
91
  good and a bad example.
@@ -99,6 +104,132 @@ or a state plus that rule's own settings:
99
104
 
100
105
  Mistyped rule names and settings are reported before any file is read.
101
106
 
107
+ ## Statistics
108
+
109
+ `gurkencheck stats` describes a suite instead of judging it: what is in the files, how
110
+ much of the step vocabulary is shared, and where it has drifted apart.
111
+
112
+ ```sh
113
+ npx gurkencheck stats features
114
+ ```
115
+
116
+ ```
117
+ 124 files, 124 features, 811 test cases
118
+
119
+ Inventory
120
+ Features 124
121
+ Rules 18
122
+ Backgrounds 61
123
+ Scenarios 402
124
+ Scenario Outlines 57
125
+ Examples tables 61 409 rows
126
+ Steps 2314 as written
127
+ ...
128
+
129
+ Scenarios
130
+ Test cases 811 one per Scenario, one per Examples row
131
+ Steps per scenario min 1 median 5 p90 11 max 27 mean 5.5
132
+
133
+ Longest
134
+ 27 Checkout with every payment method features/checkout.feature:88
135
+ ...
136
+
137
+ Steps
138
+ Written 2314 Background steps included
139
+ Distinct 871 38% of all steps - lower is more reuse
140
+ Written once 512 59% of distinct steps
141
+ ...
142
+
143
+ Nearly the same (14 groups)
144
+ 9 i am logged in features/login.feature:4
145
+ 2 i'm logged in features/profile.feature:9
146
+ ```
147
+
148
+ Once it has run it exits `0`, whatever the numbers say; it exits `2` only when it could not
149
+ run at all, such as a format that does not exist or a `--top` that is not a whole number.
150
+ Statistics are for reading, not for failing a build — that is what the rules are for.
151
+
152
+ ```
153
+ gurkencheck stats [options] <feature-files>
154
+
155
+ -f, --format <format> output format: text, json, md (default: text)
156
+ -i, --ignore <globs> comma separated globs to skip
157
+ -l, --language <code> dialect for files with no "# language:" header
158
+ --top <n> how many entries each list shows (default: 10)
159
+ -h, --help show this message
160
+ ```
161
+
162
+ ### What the numbers mean
163
+
164
+ **Test cases** counts one per Scenario and one per row of every Examples table, because a
165
+ Scenario Outline with twelve rows is twelve tests. It is usually well above the number
166
+ people carry in their heads, and it is the one that predicts how long a run takes.
167
+
168
+ **Distinct steps** is the number to watch. Two steps count as one when they differ only in
169
+ what a step definition would capture anyway, so these are all the same step:
170
+
171
+ ```gherkin
172
+ Given I have 3 items in my cart
173
+ Given I have 17 items in my cart
174
+ Given I have 3 items in my cart.
175
+ ```
176
+
177
+ Numbers, `"quoted strings"` and `<placeholders>` are each replaced by a marker; case,
178
+ spacing and a trailing full stop or exclamation mark are ignored; and the keyword is left
179
+ out, so a `Given`
180
+ and an `And` of the same text are one step. Single quotes are left alone — `the user's
181
+ cart is 'empty'` has three of them, and pairing them up would eat half the sentence.
182
+
183
+ A low share of distinct steps means the team shares a vocabulary. A high one means
184
+ everybody invents their own phrasing, and the step definitions rot.
185
+
186
+ **Nearly the same** groups steps a few single-character edits apart: `I am logged in`
187
+ against `I'm logged in`, or a `<placeholder>` against a value written in its place. Those
188
+ are one behaviour costing two step definitions. The budget is at most three edits, and no
189
+ more than about a seventh of the longer of the two, so a short step is allowed only one;
190
+ steps under eight characters are left out altogether. That is deliberately tight — further
191
+ apart than that and a step is a different sentence rather than the same one spelled two
192
+ ways.
193
+
194
+ **Written once** lists the steps used exactly once. Some are genuine; most are a phrasing
195
+ somebody invented because they could not find the one that already existed.
196
+
197
+ **Untagged scenarios** counts the scenarios carrying no tag of their own, none on their
198
+ Examples tables, and none inherited from their Feature or Rule, and so reachable by no tag
199
+ expression.
200
+
201
+ Files the parser refuses are listed at the end rather than counted, because half a broken
202
+ file would quietly make every number wrong.
203
+
204
+ ### Keeping a record
205
+
206
+ `--format json` writes the whole dataset, with none of the lists cut short, indented so
207
+ that two runs can be diffed:
208
+
209
+ ```sh
210
+ npx gurkencheck stats features --format json > stats.json
211
+ ```
212
+
213
+ `--format md` writes the same report as Markdown tables, for pasting into a pull request.
214
+
215
+ ## Watching for changes
216
+
217
+ `--watch` checks once, then again whenever a feature file or your configuration
218
+ changes, until you stop it with Ctrl-C.
219
+
220
+ ```sh
221
+ npx gurkencheck --watch features
222
+ ```
223
+
224
+ Every pass is a whole run rather than an update of the last one. Rules that look
225
+ across files — two files sharing a name, a scenario name used twice — have to see
226
+ every file to know what they have found, so there is little to reuse between
227
+ passes, and keeping every parsed file in memory between keystrokes costs more
228
+ than reading them again.
229
+
230
+ Directories are watched rather than the files found at startup, so a feature file
231
+ created after it started is picked up too. `node_modules` and `.git` are skipped.
232
+
102
233
  ## Reporting to GitHub code scanning
103
234
 
104
235
  `--format sarif` writes a SARIF 2.1.0 log, which GitHub reads directly:
@@ -138,7 +269,7 @@ Write a comment in the feature file:
138
269
  | `gurkencheck-disable-file` | The whole file, wherever the comment appears |
139
270
 
140
271
  Name the rules you mean, separated by commas or spaces; a directive naming no rules covers
141
- all of them. Comments inside a doc string are text and are left alone. The four always-on
272
+ all of them. Comments inside a doc string are text and are left alone. The five always-on
142
273
  rules cannot be switched off this way — a file that breaks one of them cannot be read at
143
274
  all, so hiding the message would leave nothing in its place.
144
275
 
@@ -1 +1 @@
1
- {"version":3,"file":"config-parser.d.ts","sourceRoot":"","sources":["../src/config-parser.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAC,aAAa,EAAE,YAAY,EAAC,MAAM,YAAY,CAAC;AAG5D,gFAAgF;AAChF,eAAO,MAAM,wBAAwB,mBAAmB,CAAC;AAQzD,oEAAoE;AACpE,MAAM,MAAM,mBAAmB,GAC3B;IAAC,EAAE,EAAE,IAAI,CAAC;IAAC,aAAa,EAAE,aAAa,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAC,GAC3E;IAAC,EAAE,EAAE,KAAK,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAC,CAAC;AA6HpD;;;;GAIG;AACH,wBAAsB,iBAAiB,CACrC,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,KAAK,EAAE,YAAY,GAClB,OAAO,CAAC,mBAAmB,CAAC,CAqD9B"}
1
+ {"version":3,"file":"config-parser.d.ts","sourceRoot":"","sources":["../src/config-parser.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAC,aAAa,EAAE,YAAY,EAAC,MAAM,YAAY,CAAC;AAG5D,gFAAgF;AAChF,eAAO,MAAM,wBAAwB,mBAAmB,CAAC;AAQzD,oEAAoE;AACpE,MAAM,MAAM,mBAAmB,GAC3B;IAAC,EAAE,EAAE,IAAI,CAAC;IAAC,aAAa,EAAE,aAAa,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAC,GAC3E;IAAC,EAAE,EAAE,KAAK,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAC,CAAC;AAoIpD;;;;GAIG;AACH,wBAAsB,iBAAiB,CACrC,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,KAAK,EAAE,YAAY,GAClB,OAAO,CAAC,mBAAmB,CAAC,CAqD9B"}
@@ -88,7 +88,13 @@ async function loadExtended(specifier, fromFile) {
88
88
  if (resolved.endsWith('.json')) {
89
89
  return { configuration: parseFile(resolved), source: resolved };
90
90
  }
91
- const module = (await import(__rewriteRelativeImportExtension(pathToFileURL(resolved).href)));
91
+ let module;
92
+ try {
93
+ module = (await import(__rewriteRelativeImportExtension(pathToFileURL(resolved).href)));
94
+ }
95
+ catch (thrown) {
96
+ throw new ConfigurationError(`Could not load "${specifier}", extended from "${fromFile}": ${thrown instanceof Error ? thrown.message : String(thrown)}`);
97
+ }
92
98
  const exported = module['default'] ?? module;
93
99
  if (!isConfigurationObject(exported)) {
94
100
  throw new ConfigurationError(`"${specifier}" does not export a configuration object.`);
@@ -1 +1 @@
1
- {"version":3,"file":"config-parser.js","sourceRoot":"","sources":["../src/config-parser.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config-parser.js","sourceRoot":"","sources":["../src/config-parser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * How a diagnostic is meant to read.
3
+ *
4
+ * `detail` is a line belonging with the error above it, which is why it is
5
+ * here rather than being left to the caller to indent.
6
+ */
7
+ export type DiagnosticLevel = 'error' | 'detail' | 'notice';
8
+ export interface Diagnostic {
9
+ level: DiagnosticLevel;
10
+ message: string;
11
+ /** Lines listed under the message, such as what is wrong with a config. */
12
+ details?: readonly string[];
13
+ }
14
+ /** Where diagnostics go. */
15
+ export interface Diagnostics {
16
+ report(diagnostic: Diagnostic): void;
17
+ }
18
+ /** Says nothing at all. What the library does unless it is told otherwise. */
19
+ export declare const SILENT: Diagnostics;
20
+ export interface CollectedDiagnostics extends Diagnostics {
21
+ /** Everything reported so far, in order. */
22
+ readonly reported: readonly Diagnostic[];
23
+ }
24
+ /** Keeps what it is told, for a test or for something showing it later. */
25
+ export declare function collectDiagnostics(): CollectedDiagnostics;
26
+ /**
27
+ * Writes to stderr, the way the command line always has.
28
+ *
29
+ * Findings go to stdout so they can be redirected or piped; anything about
30
+ * the run itself goes to stderr, so piping the one does not swallow the
31
+ * other.
32
+ */
33
+ export declare const TO_STDERR: Diagnostics;
34
+ //# sourceMappingURL=diagnostics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnostics.d.ts","sourceRoot":"","sources":["../src/diagnostics.ts"],"names":[],"mappings":"AAgBA;;;;;GAKG;AACH,MAAM,MAAM,eAAe,GAAG,OAAO,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAE5D,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,eAAe,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,2EAA2E;IAC3E,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC7B;AAED,4BAA4B;AAC5B,MAAM,WAAW,WAAW;IAC1B,MAAM,CAAC,UAAU,EAAE,UAAU,GAAG,IAAI,CAAC;CACtC;AAED,8EAA8E;AAC9E,eAAO,MAAM,MAAM,EAAE,WAEpB,CAAC;AAEF,MAAM,WAAW,oBAAqB,SAAQ,WAAW;IACvD,4CAA4C;IAC5C,QAAQ,CAAC,QAAQ,EAAE,SAAS,UAAU,EAAE,CAAC;CAC1C;AAED,2EAA2E;AAC3E,wBAAgB,kBAAkB,IAAI,oBAAoB,CAQzD;AAED;;;;;;GAMG;AACH,eAAO,MAAM,SAAS,EAAE,WAavB,CAAC"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Saying something to whoever is running gurkencheck, without deciding where
3
+ * it goes.
4
+ *
5
+ * The README promises that nothing in the library writes to the console. That
6
+ * was true only by convention - no library entry point happened to call the
7
+ * logger - and not quite true even then, since `runStats` is exported and
8
+ * wrote straight to stderr. Reporting through here instead makes it hold by
9
+ * construction: the library says what happened, and the command line is what
10
+ * decides that goes to stderr in red.
11
+ *
12
+ * This is for things said *about* a run. What a run produces - the findings,
13
+ * the statistics - is the formatter's business and goes to stdout.
14
+ */
15
+ import * as logger from './logger.js';
16
+ /** Says nothing at all. What the library does unless it is told otherwise. */
17
+ export const SILENT = {
18
+ report: () => undefined,
19
+ };
20
+ /** Keeps what it is told, for a test or for something showing it later. */
21
+ export function collectDiagnostics() {
22
+ const reported = [];
23
+ return {
24
+ reported,
25
+ report(diagnostic) {
26
+ reported.push(diagnostic);
27
+ },
28
+ };
29
+ }
30
+ /**
31
+ * Writes to stderr, the way the command line always has.
32
+ *
33
+ * Findings go to stdout so they can be redirected or piped; anything about
34
+ * the run itself goes to stderr, so piping the one does not swallow the
35
+ * other.
36
+ */
37
+ export const TO_STDERR = {
38
+ report({ level, message, details }) {
39
+ if (level === 'error') {
40
+ logger.boldError(message);
41
+ }
42
+ else if (level === 'detail') {
43
+ logger.error(message);
44
+ }
45
+ else {
46
+ logger.note(message);
47
+ }
48
+ for (const detail of details ?? []) {
49
+ logger.error(`- ${detail}`);
50
+ }
51
+ },
52
+ };
53
+ //# sourceMappingURL=diagnostics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnostics.js","sourceRoot":"","sources":["../src/diagnostics.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,MAAM,MAAM,aAAa,CAAC;AAsBtC,8EAA8E;AAC9E,MAAM,CAAC,MAAM,MAAM,GAAgB;IACjC,MAAM,EAAE,GAAG,EAAE,CAAC,SAAS;CACxB,CAAC;AAOF,2EAA2E;AAC3E,MAAM,UAAU,kBAAkB;IAChC,MAAM,QAAQ,GAAiB,EAAE,CAAC;IAClC,OAAO;QACL,QAAQ;QACR,MAAM,CAAC,UAAsB;YAC3B,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC5B,CAAC;KACF,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,SAAS,GAAgB;IACpC,MAAM,CAAC,EAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAa;QAC1C,IAAI,KAAK,KAAK,OAAO,EAAE,CAAC;YACtB,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QAC5B,CAAC;aAAM,IAAI,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC9B,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACxB,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACvB,CAAC;QACD,KAAK,MAAM,MAAM,IAAI,OAAO,IAAI,EAAE,EAAE,CAAC;YACnC,MAAM,CAAC,KAAK,CAAC,KAAK,MAAM,EAAE,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC;CACF,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * What the command line hands back to the shell.
3
+ */
4
+ /** Nothing to report. */
5
+ export declare const EXIT_OK = 0;
6
+ /** At least one finding serious enough to fail the run. Warnings alone do not. */
7
+ export declare const EXIT_LINT_ERRORS = 1;
8
+ /** The command could not run: bad arguments, missing or invalid config. */
9
+ export declare const EXIT_USAGE = 2;
10
+ //# sourceMappingURL=exit-codes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exit-codes.d.ts","sourceRoot":"","sources":["../src/exit-codes.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,yBAAyB;AACzB,eAAO,MAAM,OAAO,IAAI,CAAC;AAEzB,kFAAkF;AAClF,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAElC,2EAA2E;AAC3E,eAAO,MAAM,UAAU,IAAI,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * What the command line hands back to the shell.
3
+ */
4
+ /** Nothing to report. */
5
+ export const EXIT_OK = 0;
6
+ /** At least one finding serious enough to fail the run. Warnings alone do not. */
7
+ export const EXIT_LINT_ERRORS = 1;
8
+ /** The command could not run: bad arguments, missing or invalid config. */
9
+ export const EXIT_USAGE = 2;
10
+ //# sourceMappingURL=exit-codes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exit-codes.js","sourceRoot":"","sources":["../src/exit-codes.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,yBAAyB;AACzB,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,CAAC;AAEzB,kFAAkF;AAClF,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC;AAElC,2EAA2E;AAC3E,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,CAAC"}
@@ -8,6 +8,20 @@ export interface FeatureSearch {
8
8
  /** Arguments that were neither a feature file, a directory nor a glob. */
9
9
  invalidPatterns: string[];
10
10
  }
11
+ export interface FeatureFileStream {
12
+ /**
13
+ * Matching feature files, found as the walk reaches them, in the order
14
+ * `findFeatureFiles` returns them in.
15
+ */
16
+ files: AsyncGenerator<string>;
17
+ /**
18
+ * Arguments that were neither a feature file, a directory nor a glob.
19
+ *
20
+ * Known before anything is walked, so a caller can give up on a bad
21
+ * argument without having searched for the good ones.
22
+ */
23
+ invalidPatterns: string[];
24
+ }
11
25
  /** Reads the ignore file, one glob pattern per line, ignoring blank lines. */
12
26
  export declare function readIgnorePatterns(ignoreArgument: readonly string[] | undefined, ignoreFileName?: string): string[];
13
27
  /**
@@ -15,4 +29,28 @@ export declare function readIgnorePatterns(ignoreArgument: readonly string[] | u
15
29
  * working directory is searched recursively.
16
30
  */
17
31
  export declare function findFeatureFiles(patterns: readonly string[], ignoreArgument?: readonly string[]): FeatureSearch;
32
+ /**
33
+ * The same search, handing each file over as it is found.
34
+ *
35
+ * Walking a large tree to the end before anything else starts is time in
36
+ * which nothing is read, parsed or checked. Handing files over as they turn
37
+ * up lets the rest of the work begin on the first one.
38
+ *
39
+ * Only a run given more than one pattern remembers what it has already
40
+ * handed over: one walk cannot reach the same file twice, and remembering is
41
+ * what a stream is trying to avoid.
42
+ */
43
+ export declare function findFeatureFileStream(patterns: readonly string[], ignoreArgument?: readonly string[]): FeatureFileStream;
44
+ /**
45
+ * The directories a set of patterns could draw feature files from.
46
+ *
47
+ * What to watch, in other words. A directory rather than the files
48
+ * themselves, so that a file created after the run started is noticed too -
49
+ * watching only what was found would never hear about anything new.
50
+ *
51
+ * A directory inside another one in the list is dropped: a recursive watch on
52
+ * the parent already covers it, and two watches over one place would report
53
+ * every change twice.
54
+ */
55
+ export declare function featureRoots(patterns: readonly string[]): string[];
18
56
  //# sourceMappingURL=feature-finder.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"feature-finder.d.ts","sourceRoot":"","sources":["../src/feature-finder.ts"],"names":[],"mappings":"AASA,+DAA+D;AAC/D,eAAO,MAAM,wBAAwB,uBAAuB,CAAC;AAE7D,uDAAuD;AACvD,eAAO,MAAM,wBAAwB,UAAsB,CAAC;AAE5D,MAAM,WAAW,aAAa;IAC5B,iEAAiE;IACjE,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,0EAA0E;IAC1E,eAAe,EAAE,MAAM,EAAE,CAAC;CAC3B;AA0BD,8EAA8E;AAC9E,wBAAgB,kBAAkB,CAChC,cAAc,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,EAC7C,cAAc,GAAE,MAAiC,GAChD,MAAM,EAAE,CAYV;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,SAAS,MAAM,EAAE,EAC3B,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,GACjC,aAAa,CAiBf"}
1
+ {"version":3,"file":"feature-finder.d.ts","sourceRoot":"","sources":["../src/feature-finder.ts"],"names":[],"mappings":"AASA,+DAA+D;AAC/D,eAAO,MAAM,wBAAwB,uBAAuB,CAAC;AAE7D,uDAAuD;AACvD,eAAO,MAAM,wBAAwB,UAAsB,CAAC;AAE5D,MAAM,WAAW,aAAa;IAC5B,iEAAiE;IACjE,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,0EAA0E;IAC1E,eAAe,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,iBAAiB;IAChC;;;OAGG;IACH,KAAK,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IAC9B;;;;;OAKG;IACH,eAAe,EAAE,MAAM,EAAE,CAAC;CAC3B;AA0BD,8EAA8E;AAC9E,wBAAgB,kBAAkB,CAChC,cAAc,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,EAC7C,cAAc,GAAE,MAAiC,GAChD,MAAM,EAAE,CAoBV;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,SAAS,MAAM,EAAE,EAC3B,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,GACjC,aAAa,CAiBf;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,SAAS,MAAM,EAAE,EAC3B,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,GACjC,iBAAiB,CA+BnB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,EAAE,CAuBlE"}
@@ -5,7 +5,7 @@
5
5
  import fs from 'node:fs';
6
6
  import path from 'node:path';
7
7
  import { uniq } from './util/collections.js';
8
- import { globSync } from './util/glob.js';
8
+ import { globRoot, globStream, globSync } from './util/glob.js';
9
9
  /** The ignore file looked for when `--ignore` is not given. */
10
10
  export const DEFAULT_IGNORE_FILE_NAME = '.gurkencheckignore';
11
11
  /** Never worth linting, and expensive to walk into. */
@@ -39,14 +39,21 @@ export function readIgnorePatterns(ignoreArgument, ignoreFileName = DEFAULT_IGNO
39
39
  if (ignoreArgument !== undefined && ignoreArgument.length > 0) {
40
40
  return [...ignoreArgument];
41
41
  }
42
- if (fs.existsSync(ignoreFileName)) {
43
- return fs
44
- .readFileSync(ignoreFileName, 'utf8')
45
- .split(/\r\n|\r|\n/)
46
- .map((line) => line.trim())
47
- .filter((line) => line !== '' && !line.startsWith('#'));
42
+ let contents;
43
+ try {
44
+ contents = fs.readFileSync(ignoreFileName, 'utf8');
45
+ }
46
+ catch {
47
+ // No ignore file, or one that cannot be read: fall back to the defaults
48
+ // rather than stopping the run, so that node_modules stays skipped either
49
+ // way. Reading it outright rather than checking that it exists first also
50
+ // closes the gap between the two, in which it can be moved or removed.
51
+ return [...DEFAULT_IGNORED_PATTERNS];
48
52
  }
49
- return [...DEFAULT_IGNORED_PATTERNS];
53
+ return contents
54
+ .split(/\r\n|\r|\n/)
55
+ .map((line) => line.trim())
56
+ .filter((line) => line !== '' && !line.startsWith('#'));
50
57
  }
51
58
  /**
52
59
  * Finds the feature files named by the given patterns. With no patterns, the
@@ -67,4 +74,75 @@ export function findFeatureFiles(patterns, ignoreArgument) {
67
74
  }
68
75
  return { files: uniq(files), invalidPatterns };
69
76
  }
77
+ /**
78
+ * The same search, handing each file over as it is found.
79
+ *
80
+ * Walking a large tree to the end before anything else starts is time in
81
+ * which nothing is read, parsed or checked. Handing files over as they turn
82
+ * up lets the rest of the work begin on the first one.
83
+ *
84
+ * Only a run given more than one pattern remembers what it has already
85
+ * handed over: one walk cannot reach the same file twice, and remembering is
86
+ * what a stream is trying to avoid.
87
+ */
88
+ export function findFeatureFileStream(patterns, ignoreArgument) {
89
+ const searched = patterns.length > 0 ? patterns : ['.'];
90
+ const ignore = readIgnorePatterns(ignoreArgument);
91
+ const globs = [];
92
+ const invalidPatterns = [];
93
+ for (const pattern of searched) {
94
+ const featureGlob = toFeatureGlob(pattern);
95
+ if (featureGlob === undefined) {
96
+ invalidPatterns.push(pattern);
97
+ }
98
+ else {
99
+ globs.push(featureGlob);
100
+ }
101
+ }
102
+ async function* files() {
103
+ const seen = globs.length > 1 ? new Set() : undefined;
104
+ for (const featureGlob of globs) {
105
+ for await (const file of globStream(featureGlob, { ignore })) {
106
+ if (seen !== undefined) {
107
+ if (seen.has(file))
108
+ continue;
109
+ seen.add(file);
110
+ }
111
+ yield file;
112
+ }
113
+ }
114
+ }
115
+ return { files: files(), invalidPatterns };
116
+ }
117
+ /**
118
+ * The directories a set of patterns could draw feature files from.
119
+ *
120
+ * What to watch, in other words. A directory rather than the files
121
+ * themselves, so that a file created after the run started is noticed too -
122
+ * watching only what was found would never hear about anything new.
123
+ *
124
+ * A directory inside another one in the list is dropped: a recursive watch on
125
+ * the parent already covers it, and two watches over one place would report
126
+ * every change twice.
127
+ */
128
+ export function featureRoots(patterns) {
129
+ const searched = patterns.length > 0 ? patterns : ['.'];
130
+ const roots = new Set();
131
+ for (const pattern of searched) {
132
+ const featureGlob = toFeatureGlob(pattern);
133
+ if (featureGlob !== undefined) {
134
+ roots.add(globRoot(featureGlob));
135
+ }
136
+ }
137
+ // Shorter paths sort first, so a parent is always seen before its children.
138
+ const sorted = [...roots].sort();
139
+ const kept = [];
140
+ for (const root of sorted) {
141
+ const covered = kept.some((parent) => root === parent || root.startsWith(`${parent}${path.sep}`));
142
+ if (!covered) {
143
+ kept.push(root);
144
+ }
145
+ }
146
+ return kept;
147
+ }
70
148
  //# sourceMappingURL=feature-finder.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"feature-finder.js","sourceRoot":"","sources":["../src/feature-finder.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"feature-finder.js","sourceRoot":"","sources":["../src/feature-finder.ts"],"names":[],"mappings":"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"}
@@ -9,15 +9,55 @@ export type Formatter = (results: readonly FileResult[]) => void | string | Prom
9
9
  /** The formats accepted by `--format` without having to be loaded. */
10
10
  export declare const FORMATTERS: Record<string, Formatter>;
11
11
  export declare const DEFAULT_FORMAT = "stylish";
12
+ /**
13
+ * A formatter writing as the results arrive, rather than once they are all
14
+ * in.
15
+ *
16
+ * Text comes back written verbatim, line breaks included, so a formatter says
17
+ * exactly what goes on the stream. `start` and `end` are optional: a format
18
+ * with no preamble and no trailer needs neither.
19
+ */
20
+ export interface FormatterRun {
21
+ /** Written before the first result. */
22
+ start?(): string;
23
+ /** Written for one file, as soon as that file is done. */
24
+ file(result: FileResult): string;
25
+ /** Written after the last result. */
26
+ end?(): string;
27
+ }
28
+ /**
29
+ * Starts one run of a streaming formatter.
30
+ *
31
+ * A factory rather than an object, so counters and the like belong to a run
32
+ * and two at once cannot tread on each other.
33
+ */
34
+ export type StreamingFormatter = () => FormatterRun;
35
+ /**
36
+ * The formats that can be written as the run goes on.
37
+ *
38
+ * Not every format can. json, sarif and junit are each a single document with
39
+ * a root element and counts over the whole run, so there is nothing to write
40
+ * until the run is over; they stay as they are rather than being bent into a
41
+ * shape that does not suit them.
42
+ */
43
+ export declare const STREAMING_FORMATTERS: Record<string, StreamingFormatter>;
44
+ /** The streaming formatter for a format name, when that format has one. */
45
+ export declare function getStreamingFormatter(format: string | undefined): StreamingFormatter | undefined;
46
+ /**
47
+ * The streaming formatter for a name, a path or a package, when there is one.
48
+ *
49
+ * A formatter of your own joins in by exporting `startRun`, a function
50
+ * returning `{start?, file, end?}`. Without one it is used as it always was,
51
+ * with the whole run at once.
52
+ */
53
+ export declare function loadStreamingFormatter(format: string | undefined, cwd?: string): Promise<StreamingFormatter | undefined>;
12
54
  /** The formatter for a built-in format name, or `undefined` for anything else. */
13
55
  export declare function getFormatter(format: string | undefined): Formatter | undefined;
14
56
  /**
15
57
  * The formatter for a format name, a path, or a package.
16
58
  *
17
- * Anything that is not a built-in name is loaded as a module, resolved from
18
- * `cwd` so that a formatter installed in the project is found and a relative
19
- * path means what it looks like. The module may export the formatter as its
20
- * default export, as `printResults`, or be the function itself.
59
+ * The module may export the formatter as its default export, as
60
+ * `printResults`, or be the function itself.
21
61
  */
22
62
  export declare function loadFormatter(format: string | undefined, cwd?: string): Promise<Formatter>;
23
63
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/formatters/index.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,aAAa,CAAC;AAO5C;;;;;GAKG;AACH,MAAM,MAAM,SAAS,GAAG,CACtB,OAAO,EAAE,SAAS,UAAU,EAAE,KAC3B,IAAI,GAAG,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,MAAM,CAAC,CAAC;AAE5C,sEAAsE;AACtE,eAAO,MAAM,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAQhD,CAAC;AAEF,eAAO,MAAM,cAAc,YAAY,CAAC;AAExC,kFAAkF;AAClF,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,CAE9E;AAMD;;;;;;;GAOG;AACH,wBAAsB,aAAa,CACjC,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,GAAG,GAAE,MAAsB,GAC1B,OAAO,CAAC,SAAS,CAAC,CAwCpB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/formatters/index.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,aAAa,CAAC;AAO5C;;;;;GAKG;AACH,MAAM,MAAM,SAAS,GAAG,CACtB,OAAO,EAAE,SAAS,UAAU,EAAE,KAC3B,IAAI,GAAG,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,MAAM,CAAC,CAAC;AAE5C,sEAAsE;AACtE,eAAO,MAAM,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAQhD,CAAC;AAEF,eAAO,MAAM,cAAc,YAAY,CAAC;AAExC;;;;;;;GAOG;AACH,MAAM,WAAW,YAAY;IAC3B,uCAAuC;IACvC,KAAK,CAAC,IAAI,MAAM,CAAC;IACjB,0DAA0D;IAC1D,IAAI,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAAC;IACjC,qCAAqC;IACrC,GAAG,CAAC,IAAI,MAAM,CAAC;CAChB;AAED;;;;;GAKG;AACH,MAAM,MAAM,kBAAkB,GAAG,MAAM,YAAY,CAAC;AAEpD;;;;;;;GAOG;AACH,eAAO,MAAM,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAGnE,CAAC;AAEF,2EAA2E;AAC3E,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,MAAM,GAAG,SAAS,GACzB,kBAAkB,GAAG,SAAS,CAEhC;AAED;;;;;;GAMG;AACH,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,GAAG,GAAE,MAAsB,GAC1B,OAAO,CAAC,kBAAkB,GAAG,SAAS,CAAC,CASzC;AAED,kFAAkF;AAClF,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,CAE9E;AAwCD;;;;;GAKG;AACH,wBAAsB,aAAa,CACjC,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,GAAG,GAAE,MAAsB,GAC1B,OAAO,CAAC,SAAS,CAAC,CAiBpB"}