@tony.ganchev/eslint-plugin-header 3.1.12 → 3.2.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.
package/README.md CHANGED
@@ -47,47 +47,53 @@ Both flat config and legacy, hierarchical config can be used.
47
47
 
48
48
  ## Usage
49
49
 
50
- This rule takes between 1 and 4 arguments after the rule validation severity.
51
-
52
- The configuration can take any of the following forms:
53
-
54
- - File-based Configuration
55
- - `[<severity>, "<file>"]` - read the header template from a file.
56
- - `[<severity>, "<file>", {<settings>}]` - read the header template from a
57
- file with additional settings.
58
- - Inline Configuration
59
- - `"<severity>", "<comment-type>", <header-contents>` - define the header
60
- contents inline.
61
- - `[<severity>, "<comment-type>", <header-contents>, {<settings>}]` - define
62
- the header contents inline and pass additional settings.
63
- - `[<severity>, "<comment-type>", <header-contents>, <n-empty-lines>]` -
64
- define the header contents inline and an expected number of empty lines
65
- after the header.
66
- - `[<severity>, "<comment-type>", <header-contents>, <n-empty-lines>,
67
- {<settings>}]` - define the header contents inline and an expected number of
68
- empty lines after the header and pass additional settings.
50
+ The plugin and its _header_ rule goes through evolution of its configuration in
51
+ the 3.2.x release. We introduced a new single object-based configuration format
52
+ that is easier to evolve in the future to add more capabilities.
53
+
54
+ The legacy configuration format inherited from
55
+ [eslint-plugin-header](https://github.com/Stuk/eslint-plugin-header) is still
56
+ supported and you can learn how to use it in a
57
+ [dedicated document](legacy-config.md). For information on how to switch from
58
+ the legacy configuration format to the new style, follow our
59
+ [migration guide](migrate-config.md). The current document from this point on
60
+ will cover only the new configuration format.
61
+
62
+ This _header_ rule takes a single object as configuration, after the severity
63
+ level. At the very least, the object should contain a `header` field describing
64
+ the expected header to match in the source files.
69
65
 
70
66
  ### File-based Configuration
71
67
 
72
- In this configuration mode, the first argument is a string pointing to a JS
73
- file containing the header contents. The rule would expect an exact match to be
74
- found in the source code.
68
+ In this configuration mode, the header template is read from a file.
75
69
 
76
- The second argument can be a settings object that will be covered later in this
77
- document.
70
+ _eslint.config.mjs_:
78
71
 
79
- ```json
80
- {
81
- "plugins": [
82
- "header"
83
- ],
84
- "rules": {
85
- "header/header": [2, "config/header.js"]
72
+ ```js
73
+ import header from "@tony.ganchev/eslint-plugin-header";
74
+ import { defineConfig } from "eslint/config";
75
+
76
+ export default defineConfig([
77
+ {
78
+ files: ["**/*.js"],
79
+ plugins: {
80
+ "@tony.ganchev": header
81
+ },
82
+ rules: {
83
+ "@tony.ganchev/header": [
84
+ "error",
85
+ {
86
+ header: {
87
+ file: "config/header.js"
88
+ }
89
+ }
90
+ ]
91
+ }
86
92
  }
87
- }
93
+ ]);
88
94
  ```
89
95
 
90
- config/header.js:
96
+ _config/header.js_:
91
97
 
92
98
  ```js
93
99
  // Copyright 2015
@@ -100,14 +106,16 @@ tree then the header file will not be found.
100
106
 
101
107
  ### Inline Configuration
102
108
 
103
- The inline configuration expects at least two arguments to be given:
109
+ In this configuration mode, the matching rules for the header are given inline.
110
+ The `header` field should contain the following nested properties:
104
111
 
105
- - _comment-type_ which is either `"block"` or `"line"` to indicate what style
112
+ - `commentType` which is either `"block"` or `"line"` to indicate what style
106
113
  of comment should be used.
107
- - _header-contents_ which defines the lines of the header. It can be either a
114
+ - `line` which defines the lines of the header. It can be either a
108
115
  single multiline string / regular expression with the full contents of the
109
116
  header comment or an array with comment lines or regular expressions matching
110
- each line.
117
+ each line. It can also include template replacement strings to enable ESLint's
118
+ auto-fix capabilities.
111
119
 
112
120
  #### Header Contents Configuration
113
121
 
@@ -124,16 +132,29 @@ All of the following configurations will match the header:
124
132
 
125
133
  - **Single string**:
126
134
 
127
- ```json
128
- {
129
- "rules": {
130
- "header/header": [
131
- 2,
132
- "block",
133
- "\n * Copyright (c) 2015\n * My Company\n "
134
- ]
135
+ ```js
136
+ import header from "@tony.ganchev/eslint-plugin-header";
137
+ import { defineConfig } from "eslint/config";
138
+
139
+ export default defineConfig([
140
+ {
141
+ files: ["**/*.js"],
142
+ plugins: {
143
+ "@tony.ganchev": header
144
+ },
145
+ rules: {
146
+ "@tony.ganchev/header": [
147
+ "error",
148
+ {
149
+ header: {
150
+ commentType: "block",
151
+ lines: ["\n * Copyright (c) 2015\n * My Company\n "]
152
+ }
153
+ },
154
+ ]
155
+ }
135
156
  }
136
- }
157
+ ]);
137
158
  ```
138
159
 
139
160
  Note that the above would work for both Windows and POSIX systems even
@@ -149,61 +170,164 @@ All of the following configurations will match the header:
149
170
 
150
171
  - **Single regular expression**:
151
172
 
152
- ```json
153
- {
154
- "rules": {
155
- "header/header": [
156
- 2,
157
- "block",
158
- {
159
- "pattern":
160
- "\\n \\* Copyright \\(c\\) 2015\\n \\* My Company\\n "
161
- }
162
- ]
173
+ You can match the whole header with a regular expression. To do it, simply
174
+ pass a `RegExp` object in place of a string.
175
+
176
+ ```js
177
+ import header from "@tony.ganchev/eslint-plugin-header";
178
+ import { defineConfig } from "eslint/config";
179
+
180
+ export default defineConfig([
181
+ {
182
+ files: ["**/*.js"],
183
+ plugins: {
184
+ "@tony.ganchev": header
185
+ },
186
+ rules: {
187
+ "@tony.ganchev/header": [
188
+ "error",
189
+ {
190
+ header: {
191
+ commentType: "block",
192
+ lines: [
193
+ /\n \* Copyright \(c\) 2015\n \* Company\n /
194
+ ]
195
+ }
196
+ }
197
+ ]
198
+ }
163
199
  }
164
- }
200
+ ]);
201
+ ```
202
+
203
+ If you still use hierarchical configuration, you can define the regular
204
+ expression as a string.
205
+
206
+ ```js
207
+ import header from "@tony.ganchev/eslint-plugin-header";
208
+ import { defineConfig } from "eslint/config";
209
+
210
+ export default defineConfig([
211
+ {
212
+ files: ["**/*.js"],
213
+ plugins: {
214
+ "@tony.ganchev": header
215
+ },
216
+ rules: {
217
+ "@tony.ganchev/header": [
218
+ "error",
219
+ {
220
+ header: {
221
+ commentType: "block",
222
+ lines: [
223
+ { pattern: "\\n \\* Copyright \\(c\\) 2015"
224
+ + "\\n \\* My Company\\n "}
225
+ ]
226
+ }
227
+ }
228
+ ]
229
+ }
230
+ }
231
+ ]);
165
232
  ```
166
233
 
167
234
  Notice the double escaping of the braces. Since these pattern strings into
168
235
  `RegExp` objects, the backslashes need to be present in the string instead
169
236
  of disappear as escape characters.
170
237
 
238
+ You can pass a `RegExp` object to the `pattern` field. This is necessary if
239
+ you want to add an aut-fix for the line as we will explain further in this
240
+ document.
241
+
242
+ ```js
243
+ import header from "@tony.ganchev/eslint-plugin-header";
244
+ import { defineConfig } from "eslint/config";
245
+
246
+ export default defineConfig([
247
+ {
248
+ files: ["**/*.js"],
249
+ plugins: {
250
+ "@tony.ganchev": header
251
+ },
252
+ rules: {
253
+ "@tony.ganchev/header": [
254
+ "error",
255
+ {
256
+ header: {
257
+ commentType: "block",
258
+ lines: [
259
+ { pattern: /Copyright \(c\) 20\d{2}/ }
260
+ ]
261
+ }
262
+ }
263
+ ]
264
+ }
265
+ }
266
+ ]);
267
+ ```
268
+
171
269
  - **Array of strings**:
172
270
 
173
- ```json
174
- {
175
- "rules": {
176
- "header/header": [
177
- 2,
178
- "block",
179
- [
180
- "",
181
- " * Copyright (c) 2015",
182
- " * My Company",
183
- " "
271
+ ```js
272
+ import header from "@tony.ganchev/eslint-plugin-header";
273
+ import { defineConfig } from "eslint/config";
274
+
275
+ export default defineConfig([
276
+ {
277
+ files: ["**/*.js"],
278
+ plugins: {
279
+ "@tony.ganchev": header
280
+ },
281
+ rules: {
282
+ "@tony.ganchev/header": [
283
+ "error",
284
+ {
285
+ header: {
286
+ commentType: "block",
287
+ lines: [
288
+ "",
289
+ " * Copyright (c) 2015",
290
+ " * My Company",
291
+ " "
292
+ ]
293
+ }
294
+ }
184
295
  ]
185
- ]
296
+ }
186
297
  }
187
- }
298
+ ]);
188
299
  ```
189
300
 
190
301
  - **Array of strings and/or patterns**:
191
302
 
192
- ```json
193
- {
194
- "rules": {
195
- "header/header": [
196
- 2,
197
- "block",
198
- [
199
- "",
200
- { "pattern": " \\* Copyright \\(c\\) 2015" },
201
- " * My Company",
202
- " "
303
+ ```js
304
+ import header from "@tony.ganchev/eslint-plugin-header";
305
+ import { defineConfig } from "eslint/config";
306
+
307
+ export default defineConfig([
308
+ {
309
+ files: ["**/*.js"],
310
+ plugins: {
311
+ "@tony.ganchev": header
312
+ },
313
+ rules: {
314
+ "@tony.ganchev/header": [
315
+ "error",
316
+ {
317
+ header: {
318
+ commentType: "block",
319
+ lines: [
320
+ "",
321
+ / \* Copyright \(c\) 2015/,
322
+ " * My Company",
323
+ " "
324
+ ]
325
+ }
326
+ }
203
327
  ]
204
- ]
328
+ }
205
329
  }
206
- }
330
+ ]);
207
331
  ```
208
332
 
209
333
  Regular expressions allow for a number of improvements in the maintainability
@@ -231,21 +355,34 @@ support:
231
355
 
232
356
  We can use a regular expression to support all of these cases for your header:
233
357
 
234
- ```json
235
- {
236
- "rules": {
237
- "header/header": [
238
- 2,
239
- "block",
240
- [
241
- "",
242
- { "pattern": " \\* Copyright \\(c\\) (\\d{4}-)?\\d{4}" },
243
- " * My Company",
244
- " "
358
+ ```js
359
+ import header from "@tony.ganchev/eslint-plugin-header";
360
+ import { defineConfig } from "eslint/config";
361
+
362
+ export default defineConfig([
363
+ {
364
+ files: ["**/*.js"],
365
+ plugins: {
366
+ "@tony.ganchev": header
367
+ },
368
+ rules: {
369
+ "@tony.ganchev/header": [
370
+ "error",
371
+ {
372
+ header: {
373
+ commentType: "block",
374
+ lines: [
375
+ "",
376
+ / \* Copyright \(c\) (\d{4}-)?\d{4}/,
377
+ " * My Company",
378
+ " "
379
+ ]
380
+ }
381
+ }
245
382
  ]
246
- ]
383
+ }
247
384
  }
248
- }
385
+ ]);
249
386
  ```
250
387
 
251
388
  Note on auto-fixes i.e. `eslint --fix`: whenever strings are used to define the
@@ -254,22 +391,35 @@ to replace a header comment that did not pass validation. This is not possible
254
391
  with regular expressions. For regular expression pattern-objects, a second
255
392
  property `template` adds a replacement string.
256
393
 
257
- ```json
258
- {
259
- "rules": {
260
- "header/header": [
261
- 2,
262
- "line",
263
- [
394
+ ```js
395
+ import header from "@tony.ganchev/eslint-plugin-header";
396
+ import { defineConfig } from "eslint/config";
397
+
398
+ export default defineConfig([
399
+ {
400
+ files: ["**/*.js"],
401
+ plugins: {
402
+ "@tony.ganchev": header
403
+ },
404
+ rules: {
405
+ "@tony.ganchev/header": [
406
+ "error",
264
407
  {
265
- "pattern": " Copyright \\(c\\) (\\d{4}-)?\\d{4}",
266
- "template": " Copyright 2025",
267
- },
268
- " My Company"
408
+ header: {
409
+ commentType: "line",
410
+ lines: [
411
+ {
412
+ pattern: / Copyright \(c\) (\d{4}-)?\d{4}/,
413
+ template: " Copyright 2025",
414
+ },
415
+ " My Company"
416
+ ]
417
+ }
418
+ }
269
419
  ]
270
- ]
420
+ }
271
421
  }
272
- }
422
+ ]);
273
423
  ```
274
424
 
275
425
  There are a number of things to consider:
@@ -287,23 +437,35 @@ number of newlines that are enforced after the header.
287
437
 
288
438
  Zero newlines:
289
439
 
290
- ```json
291
- {
292
- "plugins": [
293
- "header"
294
- ],
295
- "rules": {
296
- "header/header": [
297
- 2,
298
- "block",
299
- [
300
- " Copyright now",
301
- "My Company "
302
- ],
303
- 0
304
- ]
440
+ ```js
441
+ import header from "@tony.ganchev/eslint-plugin-header";
442
+ import { defineConfig } from "eslint/config";
443
+
444
+ export default defineConfig([
445
+ {
446
+ files: ["**/*.js"],
447
+ plugins: {
448
+ "@tony.ganchev": header
449
+ },
450
+ rules: {
451
+ "@tony.ganchev/header": [
452
+ "error",
453
+ {
454
+ header: {
455
+ commentType: "block",
456
+ lines: [
457
+ " Copyright now",
458
+ "My Company "
459
+ ],
460
+ },
461
+ trailingEmptyLines: {
462
+ minimum: 0
463
+ }
464
+ }
465
+ ]
466
+ }
305
467
  }
306
- }
468
+ ]);
307
469
  ```
308
470
 
309
471
  ```js
@@ -313,23 +475,35 @@ My Company */ console.log(1)
313
475
 
314
476
  One newline (default):
315
477
 
316
- ```json
317
- {
318
- "plugins": [
319
- "header"
320
- ],
321
- "rules": {
322
- "header/header": [
323
- 2,
324
- "block",
325
- [
326
- " Copyright now",
327
- "My Company "
328
- ],
329
- 1
330
- ]
478
+ ```js
479
+ import header from "@tony.ganchev/eslint-plugin-header";
480
+ import { defineConfig } from "eslint/config";
481
+
482
+ export default defineConfig([
483
+ {
484
+ files: ["**/*.js"],
485
+ plugins: {
486
+ "@tony.ganchev": header
487
+ },
488
+ rules: {
489
+ "@tony.ganchev/header": [
490
+ "error",
491
+ {
492
+ header: {
493
+ commentType: "block",
494
+ lines: [
495
+ " Copyright now",
496
+ "My Company "
497
+ ],
498
+ },
499
+ trailingEmptyLines: {
500
+ minimum: 1
501
+ }
502
+ }
503
+ ]
504
+ }
331
505
  }
332
- }
506
+ ]);
333
507
  ```
334
508
 
335
509
  ```js
@@ -340,23 +514,35 @@ console.log(1)
340
514
 
341
515
  Two newlines:
342
516
 
343
- ```json
344
- {
345
- "plugins": [
346
- "header"
347
- ],
348
- "rules": {
349
- "header/header": [
350
- 2,
351
- "block",
352
- [
353
- " Copyright now",
354
- "My Company "
355
- ],
356
- 2
357
- ]
517
+ ```js
518
+ import header from "@tony.ganchev/eslint-plugin-header";
519
+ import { defineConfig } from "eslint/config";
520
+
521
+ export default defineConfig([
522
+ {
523
+ files: ["**/*.js"],
524
+ plugins: {
525
+ "@tony.ganchev": header
526
+ },
527
+ rules: {
528
+ "@tony.ganchev/header": [
529
+ "error",
530
+ {
531
+ header: {
532
+ commentType: "block",
533
+ lines: [
534
+ " Copyright now",
535
+ "My Company "
536
+ ]
537
+ },
538
+ trailingEmptyLines: {
539
+ minimum: 2
540
+ }
541
+ }
542
+ ]
543
+ }
358
544
  }
359
- }
545
+ ]);
360
546
  ```
361
547
 
362
548
  ```js
@@ -372,36 +558,99 @@ The rule works with both Unix/POSIX and Windows line endings. For ESLint
372
558
  `--fix`, the rule will use the line ending format of the current operating
373
559
  system (via Node's `os` package). This setting can be overwritten as follows:
374
560
 
375
- ```json
376
- "rules": {
377
- "header/header": [
378
- 2,
379
- "block",
380
- [
381
- "Copyright 2018",
382
- "My Company"
383
- ],
384
- {
385
- "lineEndings": "windows"
561
+ ```js
562
+ import header from "@tony.ganchev/eslint-plugin-header";
563
+ import { defineConfig } from "eslint/config";
564
+
565
+ export default defineConfig([
566
+ {
567
+ files: ["**/*.js"],
568
+ plugins: {
569
+ "@tony.ganchev": header
570
+ },
571
+ rules: {
572
+ "@tony.ganchev/header": [
573
+ "error",
574
+ {
575
+ header: {
576
+ commentType: "block",
577
+ lines: [
578
+ "Copyright 2018",
579
+ "My Company"
580
+ ]
581
+ },
582
+ lineEndings: "windows"
583
+ }
584
+ ]
386
585
  }
387
- ]
388
- }
586
+ }
587
+ ]);
389
588
  ```
390
589
 
391
590
  Possible values are `"unix"` for `\n` and `"windows"` for `\r\n` line endings.
591
+ The default value is `"os"` which means assume the system-specific line endings.
392
592
 
393
593
  ## Examples
394
594
 
395
595
  The following examples are all valid.
396
596
 
397
- `"block", "Copyright 2015, My Company"`:
597
+ ```js
598
+ import header from "@tony.ganchev/eslint-plugin-header";
599
+ import { defineConfig } from "eslint/config";
600
+
601
+ export default defineConfig([
602
+ {
603
+ files: ["**/*.js"],
604
+ plugins: {
605
+ "@tony.ganchev": header
606
+ },
607
+ rules: {
608
+ "@tony.ganchev/header": [
609
+ "error",
610
+ {
611
+ header: {
612
+ commentType: "block",
613
+ lines: ["Copyright 2015, My Company"]
614
+ }
615
+ }
616
+ ]
617
+ }
618
+ }
619
+ ]);
620
+ ```
398
621
 
399
622
  ```js
400
623
  /*Copyright 2015, My Company*/
401
624
  console.log(1);
402
625
  ```
403
626
 
404
- `"line", ["Copyright 2015", "My Company"]]`:
627
+ ```js
628
+ import header from "@tony.ganchev/eslint-plugin-header";
629
+ import { defineConfig } from "eslint/config";
630
+
631
+ export default defineConfig([
632
+ {
633
+ files: ["**/*.js"],
634
+ plugins: {
635
+ "@tony.ganchev": header
636
+ },
637
+ rules: {
638
+ "@tony.ganchev/header": [
639
+ "error",
640
+ {
641
+ header: {
642
+ commentType: "line",
643
+ lines: [
644
+ "Copyright 2015",
645
+ "My Company"
646
+ ]
647
+ }
648
+ }
649
+ ]
650
+ }
651
+ }
652
+ ]);
653
+ ```
405
654
 
406
655
  ```js
407
656
  //Copyright 2015
@@ -409,7 +658,33 @@ console.log(1);
409
658
  console.log(1)
410
659
  ```
411
660
 
412
- `"line", [{pattern: "^Copyright \\d{4}$"}, {pattern: "^My Company$"}]]`:
661
+ ```js
662
+ import header from "@tony.ganchev/eslint-plugin-header";
663
+ import { defineConfig } from "eslint/config";
664
+
665
+ export default defineConfig([
666
+ {
667
+ files: ["**/*.js"],
668
+ plugins: {
669
+ "@tony.ganchev": header
670
+ },
671
+ rules: {
672
+ "@tony.ganchev/header": [
673
+ "error",
674
+ {
675
+ header: {
676
+ commentType: "line",
677
+ lines: [
678
+ /^Copyright \d{4}$/,
679
+ /^My Company$/
680
+ ]
681
+ }
682
+ }
683
+ ]
684
+ }
685
+ }
686
+ ]);
687
+ ```
413
688
 
414
689
  ```js
415
690
  //Copyright 2017
@@ -419,13 +694,34 @@ console.log(1)
419
694
 
420
695
  With more decoration:
421
696
 
422
- ```json
423
- "header/header": [2, "block", [
424
- "************************",
425
- " * Copyright 2015",
426
- " * My Company",
427
- " ************************"
428
- ]]
697
+ ```js
698
+ import header from "@tony.ganchev/eslint-plugin-header";
699
+ import { defineConfig } from "eslint/config";
700
+
701
+ export default defineConfig([
702
+ {
703
+ files: ["**/*.js"],
704
+ plugins: {
705
+ "@tony.ganchev": header
706
+ },
707
+ rules: {
708
+ "@tony.ganchev/header": [
709
+ "error",
710
+ {
711
+ header: {
712
+ commentType: "block",
713
+ lines: [
714
+ "************************",
715
+ " * Copyright 2015",
716
+ " * My Company",
717
+ " ************************"
718
+ ]
719
+ }
720
+ }
721
+ ]
722
+ }
723
+ }
724
+ ]);
429
725
  ```
430
726
 
431
727
  ```js
@@ -446,7 +742,7 @@ The following guidelines apply:
446
742
  - **major versions** - new functionality that breaks compatibility.
447
743
  - **minor versions** - new features that do not break compatibility. For the
448
744
  most part we would aim to continue releasing new versions in the 3.x product
449
- line and have opt-in flags for changes in behavior of existign features.
745
+ line and have opt-in flags for changes in behavior of existing features.
450
746
  - **revisions** - bugfixes and minor non-feature improvements that do not break
451
747
  compatibility. Note that bug-fixes are allowed to break compatibility with
452
748
  previous version if the older version regressed previous expected behavior.