
# 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 for use 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 the code reviewing process can be automated.
With Goodcheck the only thing you have to do is define the rules, pairing patterns with messages, and then those same patterns wonβt bother you anymore. π
## Table of contents
- [Installation](#installation)
- [Quickstart](#quickstart)
- [Defining rules](#defining-rules)
- [Pattern](#pattern)
- [Glob](#glob)
- [A rule with _negated_ pattern](#a-rule-with-negated-pattern)
- [A rule without pattern](#a-rule-without-pattern)
- [Triggers](#triggers)
- [Importing rules](#importing-rules)
- [Excluding files](#excluding-files)
- [Commands](#commands)
- [Downloaded rules](#downloaded-rules)
- [Disabling rules with inline comments](#disabling-rules-with-inline-comments)
- [Docker images](#docker-images)
- [Development](#development)
- [Contributing](#contributing)
## Installation
```shell-session
$ gem install goodcheck
```
Or you can use [`bundler`](https://bundler.io)!
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](#docker-images).
## Quickstart
```shell-session
$ goodcheck init
$ vim goodcheck.yml
$ goodcheck check
```
The `init` command generates a 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.
### Cheatsheet
You can download a [printable cheatsheet](cheatsheet.pdf) from this repository.
## Defining rules
A `goodcheck.yml` example of the configuration is like the following:
```yaml
rules:
- id: com.example.github
pattern: Github
message: |
GitHub is GitHub, not Github
You may be 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
```
A *rule* hash under a `rules` list contains the following keys:
* `id` - a string to identify rules (required)
* [`pattern`](#pattern) - a *pattern* or a sequence of *pattern*s (optional)
* `message` - a string to tell writers why the code piece should be revised (required)
* `justification` - a sequence of strings to tell writers when an exception can be allowed (optional)
* [`glob`](#glob) - a *glob* or a sequence of *glob*s (optional)
* `pass` - a string or a sequence of strings, which does not match the given pattern (optional)
* `fail` - a string or a sequence of strings, which does match the given pattern (optional)
### Pattern
A pattern can be a *literal pattern*, *regexp pattern*, *token pattern*, or a string.
#### String literal
A string literal represents a *literal pattern* or *regexp pattern*.
```yaml
pattern:
- This is a literal pattern
- /This is a regexp pattern/
- /This is a regexp pattern with the casefold option/i
- /This is a regexp pattern with the multiline option/m
```
If a string value begins with `/` and ends with `/`, it is a *regexp pattern*.
You can optionally specify regexp options like `/casefold/i` or `/multiline/m`.
#### Literal pattern
A *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
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`.
#### Regexp pattern
A *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
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` and `multiline`.
The default values of `case_sensitive` and `multiline` are `true` and `false` respectively.
The regexp will be passed to [`Regexp.compile`](https://ruby-doc.org/core-2.7.0/Regexp.html#method-c-compile).
The precise definition of regular expressions can be found in the documentation for Ruby.
#### Token pattern
A *token pattern* compiles to a *tokenized* regexp.
```yaml
id: com.sample.no-blink
pattern:
token: "