![Goodcheck logo](logo/GoodCheck%20Horizontal.png)
# Goodcheck - Regexp based customizable linter
Are you reviewing a pull request if the change contains deprecated API calls?
Do you want to post a comment to ask the developer if a method call satisfies some condition to use that without causing an issue?
What if a misspelling like `Github` for `GitHub` can be found automatically?
Give Goodcheck a try to do them instead of you! 🎉
Goodcheck is a customizable linter.
You can define pairs of patterns and messages.
It checks your program and when it detects a piece of text matching with the defined patterns, it prints your message which tells your teammates why it should be revised and how.
Some part of code reviewing process can be automated.
Everything you have to do is to define the rules, pairs of patterns and messages, and nothing will bother you. 😆
## Installation
```bash
$ gem install goodcheck
```
Or you can use `bundler`!
If you would not like to install Goodcheck to system (e.g. you would not like to install Ruby 2.4 or higher), you can use a docker image. [See below](#docker-images).
## Quickstart
```bash
$ goodcheck init
$ vim goodcheck.yml
$ goodcheck check
```
The `init` command generates template of `goodcheck.yml` configuration file for you.
Edit the config file to define patterns you want to check.
Then run `check` command, and it will print matched texts.
## `goodcheck.yml`
An example of configuration is like the following:
```yaml
rules:
- id: com.example.github
pattern: Github
message: |
GitHub is GitHub, not Github
You may misspelling the name of the service!
justification:
- When you mean a service different from GitHub
- When GitHub is renamed
glob:
- app/views/**/*.html.slim
- config/locales/**/*.yaml
pass:
- Signup via GitHub
fail:
- Signup via Github
```
The *rule* hash contains the following keys.
* `id`: a string to identify rules (required)
* `pattern`: a *pattern* or a sequence of *pattern*s
* `message`: a string to tell writers why the code piece should be revised (required)
* `justification`: a sequence of strings to tell writers when a exception can be allowed (optional)
* `glob`: a *glob* or a sequence of *glob*s (optional)
* `pass`: a string, or a sequence of strings, which does not match given pattern (optional)
* `fail`: a string, or a sequence of strings, which does match given pattern (optional)
### *pattern*
A *pattern* can be a *literal pattern*, *regexp pattern*, *token pattern*, or a string.
When a string is given, it is interpreted as a *literal pattern* with `case_sensitive: true`.
#### *literal pattern*
*literal pattern* allows you to construct a regexp which matches exactly to the `literal` string.
```yaml
id: com.sample.GitHub
pattern:
literal: Github
case_sensitive: true
glob: []
message: Write GitHub, not Github
```
All regexp meta characters included in the `literal` value will be escaped.
`case_sensitive` is an optional key and the default is `true`.
`glob` is an optional key and the default is empty.
#### *regexp pattern*
*regexp pattern* allows you to write a regexp with meta chars.
```yaml
id: com.sample.digits
pattern:
regexp: \d{4,}
case_sensitive: false
multiline: false
glob: []
message: Insert delimiters when writing large numbers
justification:
- When you are not writing numbers, including phone numbers, zip code, ...
```
It accepts two optional attributes, `case_sensitive`, `multiline`, and `glob`.
The default values of `case_sensitive` and `multiline` are `true` and `false` respectively.
The regexp will be passed to `Regexp.compile`.
The precise definition of regular expression can be found in the documentation for Ruby.
#### *token pattern*
*token pattern* compiles to a *tokenized* regexp.
```yaml
id: com.sample.no-blink
pattern:
token: "