@tony.ganchev/eslint-plugin-header 3.2.5 → 3.3.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 +291 -2
- package/lib/rules/eslint-utils.js +1 -1
- package/lib/rules/header.js +536 -537
- package/lib/rules/header.schema.js +24 -6
- package/package.json +9 -8
- package/types/lib/rules/header.d.ts +18 -0
- package/types/lib/rules/header.d.ts.map +1 -1
- package/types/lib/rules/header.schema.d.ts.map +1 -1
package/README.md
CHANGED
|
@@ -20,7 +20,9 @@ and banner comments in JavaScript and TypeScript files.
|
|
|
20
20
|
2. [Providing To-year in Auto-fix](#providing-to-year-in-auto-fix)
|
|
21
21
|
3. [Trailing Empty Lines Configuration](#trailing-empty-lines-configuration)
|
|
22
22
|
4. [Line Endings](#line-endings)
|
|
23
|
-
3. [
|
|
23
|
+
3. [Support for Leading Comments](#support-for-leading-comments)
|
|
24
|
+
1. [Notes on Behavior](#notes-on-behavior)
|
|
25
|
+
4. [Examples](#examples)
|
|
24
26
|
4. [Comparison to Alternatives](#comparison-to-alternatives)
|
|
25
27
|
1. [Compared to eslint-plugin-headers](#compared-to-eslint-plugin-headers)
|
|
26
28
|
1. [Health Scans](#health-scans)
|
|
@@ -659,6 +661,293 @@ export default defineConfig([
|
|
|
659
661
|
Possible values are `"unix"` for `\n` and `"windows"` for `\r\n` line endings.
|
|
660
662
|
The default value is `"os"` which means assume the system-specific line endings.
|
|
661
663
|
|
|
664
|
+
### Support for Leading Comments
|
|
665
|
+
|
|
666
|
+
_NOTE: This feature is still experimental and as such may break between minor
|
|
667
|
+
versions and revisions._
|
|
668
|
+
|
|
669
|
+
_NOTE: This feature will **only** be available with the modern object-based
|
|
670
|
+
configuration._
|
|
671
|
+
|
|
672
|
+
Some frameworks such as [Jest](https://jestjs.io/) change behavior based on
|
|
673
|
+
pragma comments such as:
|
|
674
|
+
|
|
675
|
+
```js
|
|
676
|
+
/** @jest-environement node */
|
|
677
|
+
```
|
|
678
|
+
|
|
679
|
+
The problem with these is that they are not part of the header comment and
|
|
680
|
+
should be allowed to appear before the header comment. The `leadingComments`
|
|
681
|
+
option allows you to specify a set of comments that are allowed to appear before
|
|
682
|
+
the header comment. It is configured as an array of comments-matching rules
|
|
683
|
+
similar to the `header` section. For example to match the following header with
|
|
684
|
+
a leading pragma:
|
|
685
|
+
|
|
686
|
+
```js
|
|
687
|
+
/** @jest-environement node */
|
|
688
|
+
/* Copyright 2015, My Company */
|
|
689
|
+
```
|
|
690
|
+
|
|
691
|
+
... we can use the following configuration:
|
|
692
|
+
|
|
693
|
+
```ts
|
|
694
|
+
import header, { HeaderOptions } from "@tony.ganchev/eslint-plugin-header";
|
|
695
|
+
import { defineConfig } from "eslint/config";
|
|
696
|
+
|
|
697
|
+
export default defineConfig([
|
|
698
|
+
{
|
|
699
|
+
files: ["**/*.js"],
|
|
700
|
+
plugins: {
|
|
701
|
+
"@tony.ganchev": header
|
|
702
|
+
},
|
|
703
|
+
rules: {
|
|
704
|
+
"@tony.ganchev/header": [
|
|
705
|
+
"error",
|
|
706
|
+
{
|
|
707
|
+
header: {
|
|
708
|
+
commentType: "block",
|
|
709
|
+
lines: [" Copyright 2015, My Company "]
|
|
710
|
+
},
|
|
711
|
+
leadingComments: {
|
|
712
|
+
comments: [
|
|
713
|
+
{
|
|
714
|
+
commentType: "block",
|
|
715
|
+
lines: ["* @jest-environement node "]
|
|
716
|
+
}
|
|
717
|
+
]
|
|
718
|
+
}
|
|
719
|
+
} as HeaderOptions
|
|
720
|
+
]
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
]);
|
|
724
|
+
```
|
|
725
|
+
|
|
726
|
+
Assuming you need to tolerate more pragmas, you can have a longer list of
|
|
727
|
+
comments e.g.
|
|
728
|
+
|
|
729
|
+
```ts
|
|
730
|
+
import header, { HeaderOptions } from "@tony.ganchev/eslint-plugin-header";
|
|
731
|
+
import { defineConfig } from "eslint/config";
|
|
732
|
+
|
|
733
|
+
export default defineConfig([
|
|
734
|
+
{
|
|
735
|
+
files: ["**/*.js"],
|
|
736
|
+
plugins: {
|
|
737
|
+
"@tony.ganchev": header
|
|
738
|
+
},
|
|
739
|
+
rules: {
|
|
740
|
+
"@tony.ganchev/header": [
|
|
741
|
+
"error",
|
|
742
|
+
{
|
|
743
|
+
header: {
|
|
744
|
+
commentType: "block",
|
|
745
|
+
lines: [" Copyright 2015, My Company "]
|
|
746
|
+
},
|
|
747
|
+
leadingComments: {
|
|
748
|
+
comments: [
|
|
749
|
+
{
|
|
750
|
+
commentType: "block",
|
|
751
|
+
lines: ["* @jest-environement node "]
|
|
752
|
+
},
|
|
753
|
+
{
|
|
754
|
+
commentType: "line",
|
|
755
|
+
lines: [" @ts-ignore"]
|
|
756
|
+
}
|
|
757
|
+
]
|
|
758
|
+
}
|
|
759
|
+
} as HeaderOptions
|
|
760
|
+
]
|
|
761
|
+
}
|
|
762
|
+
}
|
|
763
|
+
]);
|
|
764
|
+
```
|
|
765
|
+
|
|
766
|
+
You can also use file-based configuration for any of these allowed comments.
|
|
767
|
+
|
|
768
|
+
#### Notes on Behavior
|
|
769
|
+
|
|
770
|
+
There are a number of things to consider when validating headers when allowing
|
|
771
|
+
some leading comments. It is important to understand the algorithm behind.
|
|
772
|
+
During validation, the rule breaks up all comments before the first actual code
|
|
773
|
+
token based either on the beginning and end of a block comments or based on the
|
|
774
|
+
separation of line comments by more than one line. These discrete comment blocks
|
|
775
|
+
are then validated against both the header-matching rule and all the leading
|
|
776
|
+
comment-matching rules.
|
|
777
|
+
|
|
778
|
+
For each comment, header is tested first and if it matches, validation completes
|
|
779
|
+
successfully. If not, the algorithm verifies that the comment satisfies at least
|
|
780
|
+
one comment matcher and if so, validation moves to the next comment.
|
|
781
|
+
|
|
782
|
+
If the comment matches neither the header, nor any of the leading comment
|
|
783
|
+
matchers, validation fails. To provide good troubleshooting information, errors
|
|
784
|
+
are reported for the header matcher, followed by all leading comment matchers.
|
|
785
|
+
While the information may seem overwhelming, this helps developers understand
|
|
786
|
+
all possible failures and let them pick the essential one.
|
|
787
|
+
|
|
788
|
+
Let's have the following configuration example:
|
|
789
|
+
|
|
790
|
+
```ts
|
|
791
|
+
import header, { HeaderOptions } from "@tony.ganchev/eslint-plugin-header";
|
|
792
|
+
import { defineConfig } from "eslint/config";
|
|
793
|
+
|
|
794
|
+
export default defineConfig([
|
|
795
|
+
{
|
|
796
|
+
files: ["**/*.js"],
|
|
797
|
+
plugins: {
|
|
798
|
+
"@tony.ganchev": header
|
|
799
|
+
},
|
|
800
|
+
rules: {
|
|
801
|
+
"@tony.ganchev/header": [
|
|
802
|
+
"error",
|
|
803
|
+
{
|
|
804
|
+
header: {
|
|
805
|
+
commentType: "block",
|
|
806
|
+
lines: [" Copyright 2015, My Company "]
|
|
807
|
+
},
|
|
808
|
+
leadingComments: {
|
|
809
|
+
comments: [
|
|
810
|
+
{
|
|
811
|
+
commentType: "block",
|
|
812
|
+
lines: ["* @jest-environement node "]
|
|
813
|
+
},
|
|
814
|
+
{
|
|
815
|
+
commentType: "line",
|
|
816
|
+
lines: [" @ts-ignore"]
|
|
817
|
+
}
|
|
818
|
+
]
|
|
819
|
+
}
|
|
820
|
+
} as HeaderOptions
|
|
821
|
+
]
|
|
822
|
+
}
|
|
823
|
+
}
|
|
824
|
+
]);
|
|
825
|
+
```
|
|
826
|
+
|
|
827
|
+
Let's lint the following piece of code:
|
|
828
|
+
|
|
829
|
+
```js
|
|
830
|
+
/** @jest-environement node */
|
|
831
|
+
/* Copyright 2010, My Company */
|
|
832
|
+
|
|
833
|
+
console.log(1);
|
|
834
|
+
```
|
|
835
|
+
|
|
836
|
+
The following errors would be shown:
|
|
837
|
+
|
|
838
|
+
```bash
|
|
839
|
+
2:1 error leading comment validation failed: should be a line comment
|
|
840
|
+
@tony.ganchev/header
|
|
841
|
+
2:3 error header line does not match expected after this position;
|
|
842
|
+
expected: 'Copyright 2015, My Company'
|
|
843
|
+
@tony.ganchev/header
|
|
844
|
+
2:3 error leading comment validation failed: line does not match expected
|
|
845
|
+
after this position; expected: '* @jest-environement node '
|
|
846
|
+
@tony.ganchev/header
|
|
847
|
+
```
|
|
848
|
+
|
|
849
|
+
Notice how all errors are reported on the second line. That is because the first
|
|
850
|
+
line passes validation against the first leading comment matcher, while the
|
|
851
|
+
second fails validation against all matchers.
|
|
852
|
+
|
|
853
|
+
Requiring an empty line between line leading comments is important as it keeps
|
|
854
|
+
the rule simple and fast but needs to be kept into account. Let's take the
|
|
855
|
+
following configuration for example:
|
|
856
|
+
|
|
857
|
+
```ts
|
|
858
|
+
import header, { HeaderOptions } from "@tony.ganchev/eslint-plugin-header";
|
|
859
|
+
import { defineConfig } from "eslint/config";
|
|
860
|
+
|
|
861
|
+
export default defineConfig([
|
|
862
|
+
{
|
|
863
|
+
files: ["**/*.js"],
|
|
864
|
+
plugins: {
|
|
865
|
+
"@tony.ganchev": header
|
|
866
|
+
},
|
|
867
|
+
rules: {
|
|
868
|
+
"@tony.ganchev/header": [
|
|
869
|
+
"error",
|
|
870
|
+
{
|
|
871
|
+
header: {
|
|
872
|
+
commentType: "block",
|
|
873
|
+
lines: [" Copyright 2015, My Company "]
|
|
874
|
+
},
|
|
875
|
+
leadingComments: {
|
|
876
|
+
comments: [
|
|
877
|
+
{
|
|
878
|
+
commentType: "line",
|
|
879
|
+
lines: [" foo"]
|
|
880
|
+
},
|
|
881
|
+
{
|
|
882
|
+
commentType: "line",
|
|
883
|
+
lines: [" bar"]
|
|
884
|
+
}
|
|
885
|
+
]
|
|
886
|
+
}
|
|
887
|
+
} as HeaderOptions
|
|
888
|
+
]
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
]);
|
|
892
|
+
```
|
|
893
|
+
|
|
894
|
+
This configuration would successfully lint any of the following snippets:
|
|
895
|
+
|
|
896
|
+
```js
|
|
897
|
+
// foo
|
|
898
|
+
|
|
899
|
+
// bar
|
|
900
|
+
/* Copyright 2015, My Company */
|
|
901
|
+
console.log();
|
|
902
|
+
```
|
|
903
|
+
|
|
904
|
+
```js
|
|
905
|
+
// bar
|
|
906
|
+
|
|
907
|
+
// foo
|
|
908
|
+
|
|
909
|
+
/* Copyright 2015, My Company */
|
|
910
|
+
console.log();
|
|
911
|
+
```
|
|
912
|
+
|
|
913
|
+
```js
|
|
914
|
+
// bar
|
|
915
|
+
|
|
916
|
+
// bar
|
|
917
|
+
/* Copyright 2015, My Company */
|
|
918
|
+
console.log();
|
|
919
|
+
```
|
|
920
|
+
|
|
921
|
+
It will not pass the following snippets though:
|
|
922
|
+
|
|
923
|
+
```js
|
|
924
|
+
// foo
|
|
925
|
+
// bar
|
|
926
|
+
|
|
927
|
+
/* Copyright 2015, My Company */
|
|
928
|
+
console.log();
|
|
929
|
+
```
|
|
930
|
+
|
|
931
|
+
```js
|
|
932
|
+
// bar
|
|
933
|
+
// foo
|
|
934
|
+
/* Copyright 2015, My Company */
|
|
935
|
+
console.log();
|
|
936
|
+
```
|
|
937
|
+
|
|
938
|
+
```js
|
|
939
|
+
// bar
|
|
940
|
+
// bar
|
|
941
|
+
|
|
942
|
+
/* Copyright 2015, My Company */
|
|
943
|
+
console.log();
|
|
944
|
+
```
|
|
945
|
+
|
|
946
|
+
Finally, it is worth noting that the current version accepts an arbitrary number
|
|
947
|
+
of empty lines in between comments. The only expectation still in place is that
|
|
948
|
+
there is no empty line after a shebang comment. Any of these details may change
|
|
949
|
+
through configuration in the future.
|
|
950
|
+
|
|
662
951
|
### Examples
|
|
663
952
|
|
|
664
953
|
The following examples are all valid.
|
|
@@ -937,4 +1226,4 @@ Backward-compatibility does not cover the following functional aspects:
|
|
|
937
1226
|
|
|
938
1227
|
## License
|
|
939
1228
|
|
|
940
|
-
MIT
|
|
1229
|
+
MIT, see [license file](./LICENSE.md) for more details.
|
|
@@ -36,7 +36,7 @@ module.exports = {
|
|
|
36
36
|
* @param {RuleContext} context ESLint execution context.
|
|
37
37
|
* @returns {SourceCode} The source-code object.
|
|
38
38
|
*/
|
|
39
|
-
contextSourceCode: function(context) {
|
|
39
|
+
contextSourceCode: function (context) {
|
|
40
40
|
return context.sourceCode
|
|
41
41
|
|| /** @type {RuleContext & { getSourceCode: () => SourceCode }} */(context).getSourceCode();
|
|
42
42
|
}
|