run
Note:
run
command is treated differently on Unix-like systems (macOS, Linux) and Windows:
- *nix: commands get wrapped with
sh -c '<run>'
- Windows: commands execute natively
So, when on *nix systems you can use pipes, builtins of a Bourne Shell, etc. For Windows the capabilities are limited by a single command.
This is a mandatory option for a command. This is actually a command that is executed for the hook.
You can use files templates that will be substituted with the appropriate files on execution:
{files}
- customfiles
command result.{staged_files}
- staged files which you try to commit.{push_files}
- files that are committed but not pushed.{all_files}
- all files tracked by git.{cmd}
- shorthand for the command fromlefthook.yml
.{0}
- shorthand for the single space-joint string of git hook arguments.{N}
- shorthand for the N-th git hook argument.
Note: Command line length has a limit on every system. If your list of files is quite long, lefthook splits your files list to fit in the limit and runs few commands sequentially.
Example
Run yarn lint
on pre-commit
hook.
# lefthook.yml
pre-commit:
commands:
lint:
run: yarn lint
{files}
template
Run go vet
only on files listed with git ls-files -m
command with .go
extension.
# lefthook.yml
pre-commit:
commands:
govet:
files: git ls-files -m
glob: "*.go"
run: go vet {files}
{staged_files}
template
Run yarn eslint
only on staged files with .js
, .ts
, .jsx
, and .tsx
extensions.
# lefthook.yml
pre-commit:
commands:
eslint:
glob: "*.{js,ts,jsx,tsx}"
run: yarn eslint {staged_files}
{push_files}
template
If you want to lint files only before pushing them.
# lefthook.yml
pre-push:
commands:
eslint:
glob: "*.{js,ts,jsx,tsx}"
run: yarn eslint {push_files}
{all_files}
template
Simply run bundle exec rubocop
on all files with .rb
extension excluding application.rb
and routes.rb
files.
Note:
--force-exclusion
will applyExclude
configuration setting of Rubocop
# lefthook.yml
pre-commit:
commands:
rubocop:
tags:
- backend
- style
glob: "*.rb"
exclude:
- config/application.rb
- config/routes.rb
run: bundle exec rubocop --force-exclusion {all_files}
{cmd}
template
# lefthook.yml
pre-commit:
commands:
lint:
run: yarn lint
scripts:
"good_job.js":
runner: node
You can wrap it in docker runner locally:
# lefthook-local.yml
pre-commit:
commands:
lint:
run: docker run -it --rm <container_id_or_name> {cmd}
scripts:
"good_job.js":
runner: docker run -it --rm <container_id_or_name> {cmd}
Git arguments
Make sure commits are signed.
# lefthook.yml
# Note: commit-msg hook takes a single parameter,
# the name of the file that holds the proposed commit log message.
# Source: https://git-scm.com/docs/githooks#_commit_msg
commit-msg:
commands:
multiple-sign-off:
run: 'test $(grep -c "^Signed-off-by: " {1}) -lt 2'
Rubocop
If using {all_files}
with RuboCop, it will ignore RuboCop's Exclude
configuration setting. To avoid this, pass --force-exclusion
.
Quotes
If you want to have all your files quoted with double quotes "
or single quotes '
, quote the appropriate shorthand:
# lefthook.yml
pre-commit:
commands:
lint:
glob: "*.js"
# Quoting with double quotes `"` might be helpful for Windows users
run: yarn eslint "{staged_files}" # will run `yarn eslint "file1.js" "file2.js" "[strange name].js"`
test:
glob: "*.{spec.js}"
run: yarn test '{staged_files}' # will run `yarn eslint 'file1.spec.js' 'file2.spec.js' '[strange name].spec.js'`
format:
glob: "*.js"
# Will quote where needed with single quotes
run: yarn test {staged_files} # will run `yarn eslint file1.js file2.js '[strange name].spec.js'`
Scripts
# lefthook.yml
pre-commit:
jobs:
- name: a whole script in a run
run: |
for file in $(ls .); do
yarn lint $file
done