Git hooks to integrate with pre-commit.
Add to .pre-commit-config.yaml
in your git repo:
- repo: https://github.com/jumanjihouse/pre-commit-hooks
sha: 1.10.1
hooks:
- id: check-mailmap
- id: fasterer
- id: forbid-binary
- id: forbid-space-in-indent
- id: git-check # Configure in .gitattributes
- id: git-dirty # Configure in .gitignore
- id: reek
- id: require-ascii
- id: rubocop
- id: script-must-have-extension
- id: script-must-not-have-extension
- id: shellcheck
- id: shfmt
If you want to invoke the checks as a git pre-commit hook, run:
pre-commit install
If you want to run the checks on-demand (outside of git hooks), run:
pre-commit run --all-files --verbose
The test harness of this git repo uses the second approach to run the checks on-demand.
Detect botched name/email translations in git history.
git shortlog -sn
is useful to summarize contributors.
However, it gets muddy when an email address is associated with multiple names.
Reasons include:
- the author's full name was messed up
- not always written the same way
- the author has multiple email addresses
Sample output for good condition:
$ pre-commit run check-mailmap --all-files --verbose
[check-mailmap] Detect if an email address needs to be added to mailmap.......................Passed
Sample output for bad condition:
$ pre-commit run check-mailmap --all-files --verbose
[check-mailmap] Detect if an email address needs to be added to mailmap.......................Failed
hookid: check-mailmap
The following email addresses are associated with more than one name:
billy.bob@example.com
jdoe@example.com
The associations include:
2 Billy Bob <billy.bob@example.com>
2 Bubba <billy.bob@example.com>
13 John Doe <jdoe@example.com>
4 jdoe <jdoe@example.com>
Suggest ways to improve speed of Ruby code.
fasterer
suggests speed improvements that you can check in detail at the
fast-ruby repo.
Note: You should not follow the suggestions blindly.
Prevent binary files from being committed.
Fail if a file appears to be a binary filetype.
Override with an exclude
regular expression,
such as the example here.
Prevent files with spaces within indentation from being committed.
Fail if a file contains spaces within indentation.
Override with an exclude
regular expression,
such as the example here.
Check both committed and uncommitted files for git conflict markers and
whitespace errors according to core.whitespace
and conflict-marker-size
configuration in a git repo.
This hook uses git
itself to perform the checks.
The git-scm book describes
here
that there are six core.whitespace
checks.
Enabled by default:
blank-at-eol
, which looks for spaces at the end of a lineblank-at-eof
, which looks for blank lines at the end of a filespace-before-tab
, which looks for spaces before tabs at the beginning of a line
Disabled by default:
indent-with-non-tab
, which looks for lines that begin with spaces instead of tabs (and is controlled by thetabwidth
option)tab-in-indent
, which looks for tabs in the indentation portion of a linecr-at-eol
, which looks for carriage returns at the end of a line
The git documentation describes here how to configure the various checks.
The recommended place to persist the configuration is the .gitattributes
file,
described here.
It provides fine control over configuration per file path for both
core.whitespace
and conflict-marker-size
.
Real-world examples of .gitattributes
file to configure overrides per path:
During the pre-commit stage, do nothing.
Otherwise, detect whether the git tree contains modified, staged, or untracked files.
This is useful to run near the end of a CI process to see if a build step has modified the git tree in unexpected ways.
The recommended place to persist the configuration is the .gitignore
file,
described here.
Detect code smells in Ruby code.
Reek is a tool that examines Ruby classes, modules and methods and reports any Code Smells it finds.
For an excellent introduction to Code Smells and Reek check out this blog post or that one. There is also this talk from RubyConfBY (there is also a slide deck if you prefer that).
Note: You should not follow the suggestions blindly.
This hook uses the identify
library of pre-commit to identify ruby scripts.
If the file is a ruby script, then run reek against the file.
The recommended place to persist the configuration is the .reek
file,
described here.
You can also create in-line comments in the source code for individual overrides.
Requires that text files have ascii-encoding. This is useful to detect files that have unicode characters.
Use the built-in overrides from the pre-commit framework.
RuboCop is a Ruby static code analyzer. Out of the box it enforces many of the guidelines outlined in the community Ruby Style Guide.
This hook uses the identify
library of pre-commit to identify ruby scripts.
If the file is a ruby script, then run rubocop against the file.
Additionally, run rubocop-rspec against rspec files.
Most aspects of rubocop behavior can be tweaked via various configuration options.
Rubocop-rspec is documented here.
The Google shell style guide states:
Libraries must have a
.sh
extension and should not be executable.
This hook checks for conformance.
Filter on files that are both shell
and non-executable
.
types: [shell, non-executable]
Suppose your local style guide is the opposite of the default.
In other words, you require executable scripts to end with .sh
.
Put this in your .pre-commit-config.yaml
:
- repo: https://github.com/jumanjihouse/pre-commit-hooks
rev: <version>
hooks:
- id: script-must-have-extension
name: Local policy is to use .sh extension for shell scripts
types: [shell, executable]
Note the use of "name" to override the hook's default name and provide context for the override.
The Google shell style guide states:
Executables should have no extension (strongly preferred)
This hook checks for conformance.
Filter on files that are both shell
and executable
.
types: [shell, executable]
You can use this hook to forbid filename extensions on other types of files.
Put something like this in your .pre-commit-config.yaml
:
- repo: https://github.com/jumanjihouse/pre-commit-hooks
rev: <version>
hooks:
- id: script-must-not-have-extension
name: Local policy is to exclude extension from all shell files
types: [shell]
- id: script-must-not-have-extension
name: Executable Ruby scripts must not have a file extension
types: [ruby, executable]
Note the use of "name" to override the hook's default name and provide context for the override.
Run shellcheck against scripts.
This hook uses the identify
library of pre-commit to identify shell scripts.
If the file is a shell script, then run shellcheck against the file.
By default, this hooks passes -e SC1091
to shellcheck.
Override locally with the args
parameter in .pre-commit-config.yaml
.
shellcheck
hook requires
shellcheck.
Run shfmt
against scripts with args.
This hook uses the identify
library of pre-commit to identify shell scripts.
If the file is a shell script, then run shfmt against the file.
By default, this hooks passes -l -i 2 -ci
to shfmt to conform to the
Google Shell Style Guide.
Override locally with the args
parameter in .pre-commit-config.yaml
.
shfmt
hook requires
shfmt.
Please see CONTRIBUTING.md.
Please see TESTING.md.
The code in this repo is licensed under the MIT License.