goodcheck 2.5.1 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (79) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +48 -2
  3. data/LICENSE +1 -1
  4. data/README.md +7 -444
  5. data/lib/goodcheck.rb +9 -4
  6. data/lib/goodcheck/analyzer.rb +13 -9
  7. data/lib/goodcheck/buffer.rb +11 -16
  8. data/lib/goodcheck/cli.rb +79 -57
  9. data/lib/goodcheck/commands/check.rb +41 -27
  10. data/lib/goodcheck/commands/config_loading.rb +28 -5
  11. data/lib/goodcheck/commands/init.rb +4 -2
  12. data/lib/goodcheck/commands/pattern.rb +2 -1
  13. data/lib/goodcheck/commands/test.rb +38 -30
  14. data/lib/goodcheck/config.rb +68 -1
  15. data/lib/goodcheck/config_loader.rb +41 -31
  16. data/lib/goodcheck/error.rb +3 -0
  17. data/lib/goodcheck/exit_status.rb +8 -0
  18. data/lib/goodcheck/glob.rb +14 -3
  19. data/lib/goodcheck/import_loader.rb +61 -17
  20. data/lib/goodcheck/issue.rb +3 -3
  21. data/lib/goodcheck/location.rb +28 -0
  22. data/lib/goodcheck/logger.rb +4 -4
  23. data/lib/goodcheck/reporters/json.rb +6 -1
  24. data/lib/goodcheck/reporters/text.rb +44 -11
  25. data/lib/goodcheck/rule.rb +3 -1
  26. data/lib/goodcheck/unarchiver.rb +40 -0
  27. data/lib/goodcheck/version.rb +1 -1
  28. metadata +47 -84
  29. data/.github/workflows/release.yml +0 -16
  30. data/.github/workflows/test.yml +0 -46
  31. data/.gitignore +0 -13
  32. data/.rubocop.yml +0 -5
  33. data/Dockerfile +0 -13
  34. data/Gemfile +0 -6
  35. data/Rakefile +0 -75
  36. data/bin/console +0 -14
  37. data/bin/setup +0 -8
  38. data/cheatsheet.pdf +0 -0
  39. data/docusaurus/.dockerignore +0 -2
  40. data/docusaurus/.gitignore +0 -12
  41. data/docusaurus/Dockerfile +0 -10
  42. data/docusaurus/docker-compose.yml +0 -18
  43. data/docusaurus/docs/commands.md +0 -69
  44. data/docusaurus/docs/configuration.md +0 -300
  45. data/docusaurus/docs/development.md +0 -15
  46. data/docusaurus/docs/getstarted.md +0 -46
  47. data/docusaurus/docs/rules.md +0 -79
  48. data/docusaurus/website/README.md +0 -193
  49. data/docusaurus/website/core/Footer.js +0 -100
  50. data/docusaurus/website/package.json +0 -14
  51. data/docusaurus/website/pages/en/index.js +0 -207
  52. data/docusaurus/website/pages/en/versions.js +0 -118
  53. data/docusaurus/website/sidebars.json +0 -11
  54. data/docusaurus/website/siteConfig.js +0 -171
  55. data/docusaurus/website/static/css/code-block-buttons.css +0 -39
  56. data/docusaurus/website/static/css/custom.css +0 -245
  57. data/docusaurus/website/static/img/favicon.ico +0 -0
  58. data/docusaurus/website/static/js/code-block-buttons.js +0 -47
  59. data/docusaurus/website/versioned_docs/version-1.0.0/commands.md +0 -70
  60. data/docusaurus/website/versioned_docs/version-1.0.0/configuration.md +0 -296
  61. data/docusaurus/website/versioned_docs/version-1.0.0/development.md +0 -16
  62. data/docusaurus/website/versioned_docs/version-1.0.0/getstarted.md +0 -47
  63. data/docusaurus/website/versioned_docs/version-1.0.0/rules.md +0 -81
  64. data/docusaurus/website/versioned_docs/version-1.0.2/rules.md +0 -79
  65. data/docusaurus/website/versioned_docs/version-2.4.0/configuration.md +0 -301
  66. data/docusaurus/website/versioned_docs/version-2.4.3/rules.md +0 -80
  67. data/docusaurus/website/versioned_sidebars/version-1.0.0-sidebars.json +0 -11
  68. data/docusaurus/website/versioned_sidebars/version-1.0.2-sidebars.json +0 -11
  69. data/docusaurus/website/versioned_sidebars/version-2.4.0-sidebars.json +0 -11
  70. data/docusaurus/website/versions.json +0 -11
  71. data/docusaurus/website/yarn.lock +0 -6806
  72. data/goodcheck.gemspec +0 -35
  73. data/goodcheck.yml +0 -10
  74. data/logo/GoodCheck Horizontal.pdf +0 -899
  75. data/logo/GoodCheck Horizontal.png +0 -0
  76. data/logo/GoodCheck Horizontal.svg +0 -55
  77. data/logo/GoodCheck logo.png +0 -0
  78. data/logo/GoodCheck vertical.png +0 -0
  79. data/sample.yml +0 -57
@@ -1,39 +0,0 @@
1
- /* "Copy" code block button */
2
- pre {
3
- position: relative;
4
- }
5
-
6
- pre .btnIcon {
7
- position: absolute;
8
- top: 4px;
9
- z-index: 2;
10
- cursor: pointer;
11
- border: 1px solid transparent;
12
- padding: 0;
13
- color: $primaryColor;
14
- background-color: transparent;
15
- height: 30px;
16
- transition: all .25s ease-out;
17
- }
18
-
19
- pre .btnIcon:hover {
20
- text-decoration: none;
21
- }
22
-
23
- .btnIcon__body {
24
- align-items: center;
25
- display: flex;
26
- }
27
-
28
- .btnIcon svg {
29
- fill: currentColor;
30
- margin-right: .4em;
31
- }
32
-
33
- .btnIcon__label {
34
- font-size: 11px;
35
- }
36
-
37
- .btnClipboard {
38
- right: 10px;
39
- }
@@ -1,245 +0,0 @@
1
- .index-container h2, h1 {
2
- color: $primaryColor;
3
- }
4
-
5
- .splash-container {
6
- background: linear-gradient(180deg, aliceblue 0%, #FFFFFF 74.48%);;
7
- }
8
-
9
- .splash-container h1 {
10
- margin-top: 10%;
11
- font-size: 48px;
12
- }
13
-
14
- .splash-container .description-container {
15
- font-size: 24px;
16
- color: $primaryColor;
17
- padding-bottom: 40px;
18
- }
19
-
20
- .splash-container .button, .productShowcaseSection .button {
21
- font-size: 24px;
22
- padding: 20px 40px;
23
- border: none;
24
- background: #83BF4A;
25
- color: #fff;
26
- transition: background 0.3s, color 0.3s;
27
- }
28
-
29
- .splash-container .button:hover, .productShowcaseSection .button:hover {
30
- background: hsl(91, 70%, 57%);
31
- color: #fff;
32
- }
33
-
34
- /* Buttons */
35
-
36
- .button {
37
- font-size: 18px;
38
- padding: 16px;
39
- text-transform: none;
40
- }
41
-
42
-
43
- /* index code colors */
44
-
45
- .yaml-key {
46
- color: #a3db46;
47
- }
48
-
49
- .yaml-syntax {
50
- color: #cccccc;
51
- }
52
-
53
- .yaml-value {
54
- color: hsl(194, 78%, 51%);
55
- }
56
-
57
- .terminal-highlight {
58
- color: red;
59
- }
60
-
61
- .showcaseBackground {
62
- background: $lightColor;
63
- }
64
-
65
- /* code */
66
-
67
- .code-container {
68
- font-family: Consolas, Monaco, "Andale Mono", "Ubuntu Mono", monospace;
69
- }
70
-
71
- .code-top {
72
- background: $primaryColor;
73
- color: white;
74
- padding: 10px;
75
- border-top-left-radius: 10px;
76
- border-top-right-radius: 10px;
77
- }
78
-
79
- .code-content {
80
- width: 100%;
81
- padding: 10px;
82
- margin: 0;
83
- background: hsl(210, 5%, 30%);
84
- color: hsl(0, 0%, 70%);
85
- overflow-y: scroll;
86
- }
87
-
88
- .code-result {
89
- color: hsl(0, 0%, 100%);
90
- background: hsl(0, 0%, 10%);
91
- padding: 10px;
92
- }
93
-
94
- .code-terminal {
95
- background: hsl(30, 12%, 7%);
96
- margin: 0;
97
- padding: 10px 10px 15px 10px;
98
- border-bottom-left-radius: 10px;
99
- border-bottom-right-radius: 10px;
100
- }
101
-
102
- .code-terminal p {
103
- color: hsl(0, 0%, 70%);
104
- }
105
-
106
- .code-container {
107
- width: 60%;
108
- }
109
-
110
- .description-container {
111
- width: 40%;
112
- text-align: left;
113
- padding-right: 40px;
114
- }
115
-
116
- .section-container {
117
- background: #eaeef3;
118
- }
119
-
120
- .section-container, .feature-container {
121
- padding: 60px;
122
- }
123
-
124
- .section-container, .splash-container, .center-container {
125
- display: flex;
126
- justify-content: center;
127
- }
128
-
129
- .section-grid {
130
- display: flex;
131
- justify-content: space-between;
132
- flex-wrap: wrap;
133
- }
134
-
135
- .section-card {
136
- max-width: 30%;
137
- padding-bottom: 40px;
138
- }
139
-
140
- .feature-container {
141
- display: flex;
142
- justify-content: space-between;
143
- }
144
-
145
- blockquote {
146
- background-color: rgba(201, 255, 174, 0.3);
147
- border-left: 8px solid #d7ff95;
148
- padding: 15px 30px 15px 15px;
149
- }
150
-
151
- /* navigation */
152
-
153
- .toc .toggleNav .navGroup .navGroupCategoryTitle {
154
- display: none;
155
- }
156
-
157
- .toc .toggleNav ul li a {
158
- border: none;
159
- color: #717171;
160
- display: block;
161
- font-size: 16px;
162
- font-weight: 600;
163
- padding: 4px 0;
164
- transition: color 0.3s;
165
- }
166
-
167
- .onPageNav {
168
- flex: 0 0 280px;
169
- }
170
-
171
- .onPageNav ul li {
172
- font-size: 16px;
173
- line-height: 24px;
174
- padding-bottom: 8px;
175
- }
176
-
177
- .separateOnPageNav .docsNavContainer {
178
- flex: 0 0 140px;
179
- }
180
-
181
- @media only screen and (min-width: 1400px) {
182
-
183
- .section-grid {
184
- max-width: 1360px;
185
- }
186
-
187
- .feature-container {
188
- width: 1480px;
189
- }
190
-
191
- }
192
-
193
- @media only screen and (max-width: 1500px) {
194
-
195
- .section-grid {
196
- max-width: 1060px;
197
- }
198
-
199
- .feature-container {
200
- width: 1180px;
201
- }
202
- }
203
-
204
- @media only screen and (max-width: 1023px) {
205
-
206
- .splash-container h1 {
207
- margin-top: 20px;
208
- font-size: 48px;
209
- }
210
-
211
- .splash-container .description-container {
212
- text-align: center;
213
- }
214
-
215
- .code-container {
216
- width: 99.5%;
217
- }
218
-
219
- .description-container {
220
- width: 100%;
221
- max-width: 40em;
222
- padding-right: 0;
223
- }
224
-
225
- .feature-container {
226
- display: block;
227
- min-width: 300px;
228
- }
229
-
230
- .section-container, .section-container, .feature-container {
231
- padding: 20px;
232
- }
233
- }
234
-
235
- @media only screen and (max-width: 735px) {
236
-
237
- .description-container {
238
- text-align: left;
239
- }
240
-
241
- .section-card {
242
- max-width: 100%;
243
- }
244
-
245
- }
@@ -1,47 +0,0 @@
1
- // Turn off ESLint for this file because it's sent down to users as-is.
2
- /* eslint-disable */
3
- window.addEventListener('load', function() {
4
- function button(label, ariaLabel, icon, className) {
5
- const btn = document.createElement('button');
6
- btn.classList.add('btnIcon', className);
7
- btn.setAttribute('type', 'button');
8
- btn.setAttribute('aria-label', ariaLabel);
9
- btn.innerHTML =
10
- '<div class="btnIcon__body">' +
11
- icon +
12
- '<strong class="btnIcon__label">' +
13
- label +
14
- '</strong>' +
15
- '</div>';
16
- return btn;
17
- }
18
-
19
- function addButtons(codeBlockSelector, btn) {
20
- document.querySelectorAll(codeBlockSelector).forEach(function(code) {
21
- code.parentNode.appendChild(btn.cloneNode(true));
22
- });
23
- }
24
-
25
- const copyIcon =
26
- '<svg width="12" height="12" viewBox="340 364 14 15" xmlns="http://www.w3.org/2000/svg"><path fill="currentColor" d="M342 375.974h4v.998h-4v-.998zm5-5.987h-5v.998h5v-.998zm2 2.994v-1.995l-3 2.993 3 2.994v-1.996h5v-1.995h-5zm-4.5-.997H342v.998h2.5v-.997zm-2.5 2.993h2.5v-.998H342v.998zm9 .998h1v1.996c-.016.28-.11.514-.297.702-.187.187-.422.28-.703.296h-10c-.547 0-1-.452-1-.998v-10.976c0-.546.453-.998 1-.998h3c0-1.107.89-1.996 2-1.996 1.11 0 2 .89 2 1.996h3c.547 0 1 .452 1 .998v4.99h-1v-2.995h-10v8.98h10v-1.996zm-9-7.983h8c0-.544-.453-.996-1-.996h-1c-.547 0-1-.453-1-.998 0-.546-.453-.998-1-.998-.547 0-1 .452-1 .998 0 .545-.453.998-1 .998h-1c-.547 0-1 .452-1 .997z" fill-rule="evenodd"/></svg>';
27
-
28
- addButtons(
29
- '.hljs',
30
- button('Copy', 'Copy code to clipboard', copyIcon, 'btnClipboard'),
31
- );
32
-
33
- const clipboard = new ClipboardJS('.btnClipboard', {
34
- target: function(trigger) {
35
- return trigger.parentNode.querySelector('code');
36
- },
37
- });
38
-
39
- clipboard.on('success', function(event) {
40
- event.clearSelection();
41
- const textEl = event.trigger.querySelector('.btnIcon__label');
42
- textEl.textContent = 'Copied';
43
- setTimeout(function() {
44
- textEl.textContent = 'Copy';
45
- }, 2000);
46
- });
47
- });
@@ -1,70 +0,0 @@
1
- ---
2
- id: version-1.0.0-commands
3
- title: Commands
4
- sidebar_label: Commands
5
- original_id: commands
6
- ---
7
-
8
-
9
- ## `goodcheck init [options]`
10
-
11
- The `init` command generates an example of a configuration file.
12
-
13
- Available options are:
14
-
15
- * `-c=[CONFIG]`, `--config=[CONFIG]` to specify the configuration file name to generate.
16
- * `--force` to allow overwriting of an existing config file.
17
-
18
- ## `goodcheck check [options] targets...`
19
-
20
- The `check` command checks your programs under `targets...`.
21
- You can pass:
22
-
23
- * Directory paths, or
24
- * Paths to files.
25
-
26
- When you omit `targets`, it checks all files in `.`.
27
-
28
- Available options are:
29
-
30
- * `-c [CONFIG]`, `--config=[CONFIG]` to specify the configuration file.
31
- * `-R [rule]`, `--rule=[rule]` to specify the rules you want to check.
32
- * `--format=[text|json]` to specify output format.
33
- * `-v`, `--verbose` to be verbose.
34
- * `--debug` to print all debug messages.
35
- * `--force` to ignore downloaded caches.
36
-
37
- `goodcheck check` exits with:
38
-
39
- * `0` when it does not find any matching text fragment.
40
- * `2` when it finds some matching text.
41
- * `1` when it finds some error.
42
-
43
- You can check its exit status to identify if the tool finds some pattern or not.
44
-
45
- ## `goodcheck test [options]`
46
-
47
- The `test` command tests rules.
48
- The test contains:
49
-
50
- * Validation of rule `id` uniqueness.
51
- * If `pass` examples does not match with any of `pattern`s.
52
- * If `fail` examples matches with some of `pattern`s.
53
-
54
- Use `test` command when you add a new rule to be sure you are writing rules correctly.
55
-
56
- Available options are:
57
-
58
- * `-c [CONFIG]`, `--config=[CONFIG]` to specify the configuration file.
59
- * `-v`, `--verbose` to be verbose.
60
- * `--debug` to print all debug messages.
61
- * `--force` to ignore downloaded caches
62
-
63
- ## `goodcheck pattern [options] ids...`
64
-
65
- The `pattern` command prints the regular expressions generated from the patterns.
66
- The command is for debugging patterns, especially token patterns.
67
-
68
- The available option is:
69
-
70
- * `-c [CONFIG]`, `--config=[CONFIG]` to specify the configuration file.
@@ -1,296 +0,0 @@
1
- ---
2
- id: version-1.0.0-configuration
3
- title: Configuration
4
- sidebar_label: Configuration
5
- original_id: configuration
6
- ---
7
-
8
- ## `goodcheck.yml`
9
-
10
- An example of the configuration is like the following:
11
-
12
- ```yaml
13
- rules:
14
- - id: com.example.github
15
- pattern: Github
16
- message: |
17
- GitHub is GitHub, not Github
18
-
19
- You may misspelling the name of the service!
20
- justification:
21
- - When you mean a service different from GitHub
22
- - When GitHub is renamed
23
- glob:
24
- - app/views/**/*.html.slim
25
- - config/locales/**/*.yaml
26
- pass:
27
- - <a>Signup via GitHub</a>
28
- fail:
29
- - <a>Signup via Github</a>
30
- ```
31
-
32
- The *rule* hash contains the following keys.
33
-
34
- * `id`: a string to identify rules (required)
35
- * `pattern`: a *pattern* or a sequence of *pattern*s
36
- * `message`: a string to tell writers why the code piece should be revised (required)
37
- * `justification`: a sequence of strings to tell writers when an exception can be allowed (optional)
38
- * `glob`: a *glob* or a sequence of *glob*s (optional)
39
- * `pass`: a string, or a sequence of strings, which does not match the given pattern (optional)
40
- * `fail`: a string, or a sequence of strings, which does match the given pattern (optional)
41
-
42
- ## *pattern*
43
-
44
- A *pattern* can be a *literal pattern*, *regexp pattern*, *token pattern*, or a string.
45
-
46
- ### String literal
47
-
48
- String literal represents a *literal pattern* or *regexp pattern*.
49
-
50
- ```yaml
51
- pattern:
52
- - This is a literal pattern
53
- - /This is a regexp pattern/
54
- ```
55
-
56
- If the string value begins with `/` and ends with `/`, it is a *regexp pattern*.
57
- You can optionally specify regexp options like `/casefold/i` or `/multiline/m`.
58
-
59
- ### *literal pattern*
60
-
61
- *literal pattern* allows you to construct a regexp which matches exactly to the `literal` string.
62
-
63
- ```yaml
64
- id: com.sample.GitHub
65
- pattern:
66
- literal: Github
67
- case_sensitive: true
68
- message: Write GitHub, not Github
69
- ```
70
-
71
- All regexp meta characters included in the `literal` value will be escaped.
72
- `case_sensitive` is an optional key and the default is `true`.
73
-
74
- ### *regexp pattern*
75
-
76
- *regexp pattern* allows you to write a regexp with meta chars.
77
-
78
- ```yaml
79
- id: com.sample.digits
80
- pattern:
81
- regexp: \d{4,}
82
- case_sensitive: false
83
- multiline: false
84
- message: Insert delimiters when writing large numbers
85
- justification:
86
- - When you are not writing numbers, including phone numbers, zip code, ...
87
- ```
88
-
89
- It accepts two optional attributes, `case_sensitive` and `multiline`.
90
- The default values of `case_sensitive` and `multiline` are `true` and `false` respectively.
91
-
92
- The regexp will be passed to `Regexp.compile`.
93
- The precise definition of regular expressions can be found in the documentation for Ruby.
94
-
95
- ### *token pattern*
96
-
97
- *token pattern* compiles to a *tokenized* regexp.
98
-
99
- ```yaml
100
- id: com.sample.no-blink
101
- pattern:
102
- token: "<blink"
103
- case_sensitive: false
104
- message: Stop using <blink> tag
105
- glob: "**/*.html"
106
- justification:
107
- - If Lynx is the major target of the web site
108
- ```
109
-
110
- It tries to tokenize the input and generates a regexp which matches a sequence of tokens.
111
- The tokenization is heuristic and may not work well for your programming language.
112
- In that case, try using *regexp pattern*.
113
-
114
- The generated regexp of `<blink` is `<\s*blink\b/m`.
115
- It matches with `<blink />` and `< BLINK>`, but does not match with `https://www.chromium.org/blink`.
116
-
117
- It accepts one optional attribute `case_sensitive`.
118
- The default value of `case_sensitive` is `true`.
119
- Note that the generated regexp is in multiline mode.
120
-
121
- Token patterns can have an optional `where` attribute and *variable bindings*.
122
-
123
- ```yaml
124
- pattern:
125
- - token: bgcolor=${color:string}
126
- where:
127
- color: true
128
- ```
129
-
130
- The variable binding consists of *variable name* and *variable type*, where `color` and `string` in the example above respectively. You have to add a key of the *variable name* in `where` attribute.
131
-
132
- We have 8 built-in patterns:
133
-
134
- * `string`
135
- * `int`
136
- * `float`
137
- * `number`
138
- * `url`
139
- * `email`
140
- * `word`
141
- * `identifier`
142
-
143
- You can find the exact definitions of the types in the definition of `Goodcheck::Pattern::Token` (`@@TYPES`).
144
-
145
- You can omit the type of variable binding.
146
-
147
- ```yaml
148
- pattern:
149
- - token: margin-left: ${size}px;
150
- where:
151
- size: true
152
- - token: backgroundColor={${color}}
153
- where:
154
- color: true
155
- ```
156
-
157
- In this case, the following character will be used to detect the range of binding. In the first example above, the `px` will be used as the marker for the end of `size` binding.
158
-
159
- If parens or brackets are surrounding the variable, Goodcheck tries to match with nested ones in the variable. It expands five levels of nesting. See the example of matches with the second `backgroundColor` pattern:
160
-
161
- - `backgroundColor={color}` Matches (`color=="color"`)
162
- - `backgroundColor={{ red: red(), green: green(), blue: green()-1 }}` Matches (`color=="{ red: red(), green: green(), blue: green()-1 }"`)
163
- - `backgroundColor={ {{{{{{}}}}}} }` Matches (`color==" {{{{{{}}}}}"`)
164
-
165
- ## *glob*
166
-
167
- A *glob* can be a string, or a hash.
168
-
169
- ```yaml
170
- glob:
171
- pattern: "legacy/**/*.rb"
172
- encoding: EUC-JP
173
- ```
174
-
175
- The hash can have an optional `encoding` attribute.
176
- You can specify the encoding of the file by the names defined for Ruby.
177
- The list of all available encoding names can be found by `$ ruby -e "puts Encoding.name_list"`.
178
- The default value is `UTF-8`.
179
-
180
- If you write a string as a `glob`, the string value can be the `pattern` of the glob, without `encoding` attribute.
181
-
182
- If you omit the `glob` attribute in a rule, the rule will be applied to all files given to `goodcheck`.
183
-
184
- If both your rule and its pattern has `glob`, Goodcheck will scan the pattern with files matching the `glob` condition in the pattern.
185
-
186
- ```yaml
187
- rules:
188
- - id: glob_test
189
- pattern:
190
- - literal: 123 # This pattern applies to .css files
191
- glob: "*.css"
192
- - literal: abc # This pattern applies to .txt files
193
- glob: "*.txt"
194
- ```
195
-
196
- ## A rule with _negated_ pattern
197
-
198
- Goodcheck rules are usually to detect _something is included in a file_.
199
- You can define the _negated_ rules for the opposite, _something is missing in a file_.
200
-
201
- ```yaml
202
- rules:
203
- - id: negated
204
- not:
205
- pattern:
206
- <!DOCTYPE html>
207
- message: Write a doctype on HTML files.
208
- glob: "**/*.html"
209
- ```
210
-
211
- ## A rule without `pattern`
212
-
213
- You can define a rule without `pattern`.
214
- The rule emits an issue on each file specified with `glob`.
215
- You cannot omit `glob` from a rule definition without `pattern`.
216
-
217
- ```yaml
218
- rules:
219
- - id: without_pattern
220
- message: |
221
- Read the operation manual for DB migration: https://example.com/guides/123
222
- glob: db/schema.rb
223
- ```
224
-
225
- The output will be something like:
226
-
227
- ```
228
- $ goodcheck check
229
- db/schema.rb:-:# This file is auto-generated from the current state of the database. Instead: Read the operation manual for DB migration: https://example.com/guides/123
230
- ```
231
-
232
- ## Triggers
233
-
234
- Version 2.0.0 introduces a new abstraction to define patterns, trigger.
235
- You can continue using `pattern`s in `rule`, but using `trigger` allows more flexible pattern definition and more precise testing.
236
-
237
- ```
238
- rules:
239
- - id: trigger
240
- message: Using trigger
241
- trigger:
242
- - pattern: <blink
243
- glob: "**/*.html"
244
- fail:
245
- - <blink></blink>
246
- - not:
247
- pattern:
248
- token: <meta charset="UTF-8">
249
- case_sensitive: false
250
- glob: "**/*.html"
251
- pass: |
252
- <html>
253
- <meta charset="utf-8"></meta>
254
- </html>
255
- ```
256
-
257
- You can continue existing `pattern` definitions, but using `goodcheck test` against `pattern`s with `glob` does not work.
258
- If your `pattern` definition includes `glob`, switching to `trigger` would make sense.
259
-
260
- ## Importing rules
261
-
262
- `goodcheck.yml` can have an optional `import` attribute.
263
-
264
- ```yaml
265
- import:
266
- - /usr/share/goodcheck/rules.yml
267
- - lib/goodcheck/rules.yml
268
- - https://some.host/shared/rules.yml
269
- ```
270
-
271
- The value of `import` can be an array of:
272
-
273
- - A string which represents an absolute file path,
274
- - A string which represents a relative file path from the config file, or
275
- - A http/https URL which represents the location of rules
276
-
277
- The rules file is a YAML file with an array of rules.
278
-
279
- ## Downloaded rules
280
-
281
- Downloaded rules are cached in `cache` directory in *goodcheck home directory*.
282
- The *goodcheck home directory* is `~/.goodcheck`, but you can customize the location with `GOODCHECK_HOME` environment variable.
283
-
284
- The cache expires in 3 minutes.
285
-
286
- ## Excluding files
287
-
288
- `goodcheck.yml` can have an optional `exclude` attribute.
289
-
290
- ```yaml
291
- exclude:
292
- - node_modules
293
- - vendor
294
- ```
295
-
296
- The value of `exclude` can be a string or an array of strings representing the glob pattern for excluded files.