diff --git a/docs/mdbook/SUMMARY.md b/docs/mdbook/SUMMARY.md index 4199f2b8..53902c8c 100644 --- a/docs/mdbook/SUMMARY.md +++ b/docs/mdbook/SUMMARY.md @@ -35,7 +35,7 @@ - [`refetch_frequency`](./configuration/refetch_frequency.md) - [`configs`](./configuration/configs.md) - [Git hook](./configuration/Hook.md) - - [`files` (global)](./configuration/files-global.md) + - [`files`](./configuration/files-global.md) - [`parallel`](./configuration/parallel.md) - [`piped`](./configuration/piped.md) - [`follow`](./configuration/follow.md) @@ -70,3 +70,6 @@ - [`use_stdin`](./configuration/use_stdin.md) - [`priority`](./configuration/priority.md) - [Usage](./usage.md) + - [Commands](./usage/commands.md) + - [ENV variables](./usage/env.md) + - [Tips](./usage/tips.md) diff --git a/docs/mdbook/configuration/Hook.md b/docs/mdbook/configuration/Hook.md index 2f640a7b..edfe7f67 100644 --- a/docs/mdbook/configuration/Hook.md +++ b/docs/mdbook/configuration/Hook.md @@ -1,2 +1,40 @@ ## Git hook +Contains settings for the git hook (commands, scripts, skip rules, etc.). You can specify any Git hook or your own custom, e.g. `test` + +### Hook options + +- [`files`](./files-global.md) +- [`parallel`](./parallel.md) +- [`piped`](./piped.md) +- [`follow`](./follow.md) +- [`exclude_tags`](./exclude_tags.md) +- [`skip`](./skip.md) +- [`only`](./only.md) +- [`commands`](./Commands.md) + - [`run`](./run.md) + - [`skip`](./skip.md) + - [`only`](./only.md) + - [`tags`](./tags.md) + - [`glob`](./glob.md) + - [`files`](./files.md) + - [`file_types`](./file_types.md) + - [`env`](./env.md) + - [`root`](./root.md) + - [`exclude`](./exclude.md) + - [`fail_text`](./fail_text.md) + - [`stage_fixed`](./stage_fixed.md) + - [`interactive`](./interactive.md) + - [`use_stdin`](./use_stdin.md) + - [`priority`](./priority.md) +- [`scripts`](./Scripts.md) + - [`runner`](./runner.md) + - [`skip`](./skip.md) + - [`only`](./only.md) + - [`tags`](./tags.md) + - [`env`](./env.md) + - [`fail_text`](./fail_text.md) + - [`stage_fixed`](./stage_fixed.md) + - [`interactive`](./interactive.md) + - [`use_stdin`](./use_stdin.md) + - [`priority`](./priority.md) diff --git a/docs/mdbook/configuration/file_types.md b/docs/mdbook/configuration/file_types.md index 762987e9..7f5f1c76 100644 --- a/docs/mdbook/configuration/file_types.md +++ b/docs/mdbook/configuration/file_types.md @@ -11,7 +11,8 @@ Filter files in a [`run`](./run.md) templates by their type. Supported types: |`symlink` | A symlink file. | |`not symlink` | Any non-symlink file. | -> [!IMPORTANT] +> IMPORTANT +> > When passed multiple file types all constraints will be applied to the resulting list of files. **Examples** diff --git a/docs/mdbook/configuration/remotes.md b/docs/mdbook/configuration/remotes.md index fa902c60..d66d46b5 100644 --- a/docs/mdbook/configuration/remotes.md +++ b/docs/mdbook/configuration/remotes.md @@ -1,8 +1,5 @@ ## `remotes` -> [!IMPORTANT] -> :test_tube: This feature is in **Beta** version - You can provide multiple remote configs if you want to share yours lefthook configurations across many projects. Lefthook will automatically download and merge configurations into your local `lefthook.yml`. You can use [`extends`](./extends.md) but the paths must be relative to the remote repository root. diff --git a/docs/mdbook/configuration/run.md b/docs/mdbook/configuration/run.md index 1194d1e1..05c9c486 100644 --- a/docs/mdbook/configuration/run.md +++ b/docs/mdbook/configuration/run.md @@ -4,7 +4,7 @@ This is a mandatory option for a command. This is actually a command that is exe You can use files templates that will be substituted with the appropriate files on execution: -- `{files}` - custom [`files`](#files) command result. +- `{files}` - custom [`files`](./files.md) 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. @@ -72,7 +72,7 @@ pre-push: Simply run `bundle exec rubocop` on all files with `.rb` extension excluding `application.rb` and `routes.rb` files. -> [!NOTE] +> NOTE > > `--force-exclusion` will apply `Exclude` configuration setting of Rubocop. @@ -136,8 +136,6 @@ commit-msg: run: 'test $(grep -c "^Signed-off-by: " {1}) -lt 2' ``` -**Notes** - #### Rubocop If using `{all_files}` with RuboCop, it will ignore RuboCop's `Exclude` configuration setting. To avoid this, pass `--force-exclusion`. diff --git a/docs/mdbook/configuration/skip_output.md b/docs/mdbook/configuration/skip_output.md index 55f1d2fe..2c775c89 100644 --- a/docs/mdbook/configuration/skip_output.md +++ b/docs/mdbook/configuration/skip_output.md @@ -1,6 +1,5 @@ ### `skip_output` -> [!IMPORTANT] > **DEPRECATED** This feature is deprecated and might be removed in future versions. Please, use `[output]` instead for managing verbosity. You can manage the verbosity using the `skip_output` config. You can set whether lefthook should print some parts of its output. diff --git a/docs/mdbook/usage.md b/docs/mdbook/usage.md index 8f04b05a..253db533 100644 --- a/docs/mdbook/usage.md +++ b/docs/mdbook/usage.md @@ -1 +1,28 @@ # Usage + +- [Commands](./usage/commands.md) + - [`lefthook install`](./usage/commands.md#lefthook-install) + - [`lefthook uninstall`](./usage/commands.md#lefthook-uninstall) + - [`lefthook add`](./usage/commands.md#lefthook-add) + - [`lefthook run`](./usage/commands.md#lefthook-run) + - [`lefthook version`](./usage/commands.md#lefthook-version) + - [`lefthook self-update`](./usage/commands.md#lefthook-self-update) +- [ENV variables](./usage/env.md) + - [`LEFTHOOK`](./usage/env.md#lefthook) + - [`LEFTHOOK_EXCLUDE`](./usage/env.md#lefthook_exclude) + - [`LEFTHOOK_OUTPUT`](./usage/env.md#lefthook_output) + - [`LEFTHOOK_QUIET`](./usage/env.md#lefthook_quiet) + - [`LEFTHOOK_VERBOSE`](./usage/env.md#lefthook_verbose) + - [`LEFTHOOK_BIN`](./usage/env.md#lefthook_bin) + - [`NO_COLOR`](./usage/env.md#no_color) + - [`CLICOLOR_FORCE`](./usage/env.md#clicolor_force) +- [Tips](./usage/tips.md) + - [Local config](./usage/tips.md#local-config) + - [Disable lefthook in CI](./usage/tips.md#disable-lefthook-in-ci) + - [Commitlint example](./usage/tips.md#commitlint-example) + - [Parallel execution](./usage/tips.md#parallel-execution) + - [Concurrent files overrides](./usage/tips.md#concurrent-files-overrides) + - [Capture ARGS from git in the script](./usage/tips.md#capture-args-from-git-in-the-script) + - [Git LFS support](./usage/tips.md#git-lfs-support) + - [Pass stdin to a command or script](./usage/tips.md#pass-stdin-to-a-command-or-script) + - [Using an interactive command or script](./usage/tips.md#using-an-interactive-command-or-script) diff --git a/docs/mdbook/usage/commands.md b/docs/mdbook/usage/commands.md new file mode 100644 index 00000000..ed2971d7 --- /dev/null +++ b/docs/mdbook/usage/commands.md @@ -0,0 +1,121 @@ +## Commands + +Use `lefthook help` or `lefthook -h/--help` to discover available commands and their options. + +### `lefthook install` + +`lefthook install` creates an empty `lefthook.yml` if a configuration file does not exist and updates git hooks to use lefthook. Run `lefthook install` after cloning the git repo. + +> NOTE +> +> NPM package `lefthook` installs the hooks in a postinstall script automatically. + +### `lefthook uninstall` + +`lefthook uninstall` clears git hooks affected by lefthook. If you have lefthook installed as an NPM package you should remove it manually. + +### `lefthook add` + +`lefthook add pre-commit` will create a file `.git/hooks/pre-commit`. This is the same lefthook does for [`install`](#lefthook-install) command but you don't need to create a configuration first. + +To use custom scripts as hooks create the required directories with `lefthook add pre-commit --dirs`. + +**Example** + +```bash +$ lefthook add pre-push --dirs +``` + +Describe pre-push commands in `lefthook.yml`: + +```yml +pre-push: + scripts: + "audit.sh": + runner: bash +``` + +Edit the script: + +```bash +$ vim .lefthook/pre-push/audit.sh +... +``` + +Run `git push` and lefthook will run `bash audit.sh` as a pre-push hook. + +### `lefthook run` + +`lefthook run` executes the commands and scripts configured for a given hook. Generated hooks call `lefthook run` implicitly. + +**Example** + +```yml +# lefthook.yml + +pre-commit: + commands: + lint: + run: yarn lint --fix + +test: + commands: + js-test: + run: yarn test +``` + +Install the hook. + +```bash +$ lefthook install +``` + +Run `test`. + +```bash +$ lefthook run test # will run 'yarn test' +``` + +Commit changes. + +```bash +$ git commit # will run pre-commit hook ('yarn lint --fix') +``` + +Or run manually also + +```bash +$ lefthook run pre-commit +``` + +You can also specify a flag to run only some commands: + +```bash +$ lefthook run pre-commit --commands lint +``` + +and optionally run either on all files (any `{staged_files}` placeholder acts as `{all_files}`) or a list of files: + +```bash +$ lefthook run pre-commit --all-files +$ lefthook run pre-commit --file file1.js --file file2.js +``` + +(if both are specified, `--all-files` is ignored) + +### `lefthook version` + +`lefthook version` prints the current binary version. Print the commit hash with `lefthook version --full` + +**Example** + +```bash +$ lefthook version --full + +1.1.3 bb099d13c24114d2859815d9d23671a32932ffe2 +``` + +### `lefthook self-update` + +`lefthook self-update` updates the binary with the latest lefthook release on Github. This command is available only if you install lefthook from sources or download the binary from the Github Releases. For other ways use package-specific commands to update lefthook. + diff --git a/docs/mdbook/usage/env.md b/docs/mdbook/usage/env.md new file mode 100644 index 00000000..b8c469ec --- /dev/null +++ b/docs/mdbook/usage/env.md @@ -0,0 +1,70 @@ +## ENV variables + +### `LEFTHOOK` + +Use `LEFTHOOK=0 git ...` or `LEFTHOOK=false git ...` to disable lefthook when running git commands. + +**Example** + +```bash +LEFTHOOK=0 git commit -am "Lefthook skipped" +``` + +### `LEFTHOOK_EXCLUDE` + +Use `LEFTHOOK_EXCLUDE={list of tags or command names to be excluded}` to skip some commands or scripts by tag or name (for commands only). See the [`exclude_tags`](../configuration/exclude_tags.md) configuration option for more details. + +**Example** + +```bash +LEFTHOOK_EXCLUDE=ruby,security,lint git commit -am "Skip some tag checks" +``` + +### `LEFTHOOK_OUTPUT` + +Use `LEFTHOOK_OUTPUT={list of output values}` to specify what to print in your output. You can also set `LEFTHOOK_OUTPUT=false` to disable all output except for errors. Refer to the [`output`](../configuration/output.md) configuration option for more details. + +**Example** + +```bash +$ LEFTHOOK_OUTPUT=summary lefthook run pre-commit +summary: (done in 0.52 seconds) +✔️ lint +``` + +### `LEFTHOOK_QUIET` + +You can skip some outputs printed by lefthook by setting the `LEFTHOOK_QUIET` environment variable. Provide a list of output types to be skipped. See the [`skip_output`](../configuration/skip_output.md) configuration option for more details. + +**Example** + +```bash +$ LEFTHOOK_QUIET=meta,execution lefthook run pre-commit + + EXECUTE > lint + +SUMMARY: (done in 0.01 seconds) +🥊 lint +``` + +### `LEFTHOOK_VERBOSE` + +Set `LEFTHOOK_VERBOSE=1` or `LEFTHOOK_VERBOSE=true` to enable verbose printing. + +### `LEFTHOOK_BIN` + +Set `LEFTHOOK_BIN` to a location where lefthook is installed to use that instead of trying to detect from the it the PATH or from a package manager. + +Useful for cases when: + +- lefthook is installed multiple ways, and you want to be explicit about which one is used (example: installed through homebrew, but also is in Gemfile but you are using a ruby version manager like rbenv that prepends it to the path) +- debugging and/or developing lefthook + +### `NO_COLOR` + +Set `NO_COLOR=true` to disable colored output in lefthook and all subcommands that lefthook calls. + +### `CLICOLOR_FORCE` + +Set `CLICOLOR_FORCE=true` to force colored output in lefthook and all subcommands. + diff --git a/docs/mdbook/usage/tips.md b/docs/mdbook/usage/tips.md new file mode 100644 index 00000000..02f64f53 --- /dev/null +++ b/docs/mdbook/usage/tips.md @@ -0,0 +1,128 @@ +## Tips + +### Local config + +Use `lefthook-local.yml` to overwrite or extend options from the main config. (Don't forget to add this file to `.gitignore`) + +### Disable lefthook in CI + +When using NPM package `lefthook` set `CI=true` in your CI (if it does not set automatically). When `CI=true` is set lefthook NPM package won't install the hooks in the postinstall script. + +### Commitlint example + +Let's create a bash script to check conventional commit status `.lefthook/commit-msg/commitlint.sh`: + +```bash +echo $(head -n1 $1) | npx commitlint --color +``` + +Now we can ask lefthook to run our bash script by adding this code to +`lefthook.yml` file: + +```yml +# lefthook.yml + +commit-msg: + scripts: + "commitlint.sh": + runner: bash +``` + +When you try to commit `git commit -m "haha bad commit text"` script `commitlint.sh` will be executed. Since commit text doesn't match the default config or custom config that you setup for `commitlint`, the process will be interrupted. + +### Parallel execution + +You can enable parallel execution if you want to speed up your checks. +Lets imagine we have the following rules to lint the whole project: + +``` +bundle exec rubocop --parallel && \ +bundle exec danger && \ +yarn eslint --ext .es6 app/assets/javascripts && \ +yarn eslint --ext .es6 test/javascripts && \ +yarn eslint --ext .es6 plugins/**/assets/javascripts && \ +yarn eslint --ext .es6 plugins/**/test/javascripts && \ +yarn eslint app/assets/javascripts test/javascripts +``` + +Rewrite it in lefthook custom group. We call it `lint`: + +```yml +# lefthook.yml + +lint: + parallel: true + commands: + rubocop: + run: bundle exec rubocop --parallel + danger: + run: bundle exec danger + eslint-assets: + run: yarn eslint --ext .es6 app/assets/javascripts + eslint-test: + run: yarn eslint --ext .es6 test/javascripts + eslint-plugins-assets: + run: yarn eslint --ext .es6 plugins/**/assets/javascripts + eslint-plugins-test: + run: yarn eslint --ext .es6 plugins/**/test/javascripts + eslint-assets-tests: + run: yarn eslint app/assets/javascripts test/javascripts +``` + +Then call this group directly: + +``` +lefthook run lint +``` + +### Concurrent files overrides + +To prevent concurrent problems with read/write files try `flock` +utility. + +```yml +# lefthook.yml + +graphql-schema: + glob: "{Gemfile.lock,app/graphql/**/*}" + run: flock webpack/application/typings/graphql-schema.json yarn typings:update && git diff --exit-code --stat HEAD webpack/application/typings +frontend-tests: + glob: "**/*.js" + run: flock -s webpack/application/typings/graphql-schema.json yarn test --findRelatedTests {files} +frontend-typings: + glob: "**/*.js" + run: flock -s webpack/application/typings/graphql-schema.json yarn run flow focus-check {files} +``` + +### Capture ARGS from git in the script + +Example script for `prepare-commit-msg` hook: + +```bash +COMMIT_MSG_FILE=$1 +COMMIT_SOURCE=$2 +SHA1=$3 + +# ... +``` + +### Git LFS support + +> If git-lfs binary is not installed and not required in your project, LFS hooks won't be executed, and you won't be warned about it. + +Lefthook runs LFS hooks internally for the following hooks: + +- post-checkout +- post-commit +- post-merge +- pre-push + +Errors are suppressed if git LFS is not required for the project. You can use [`LEFTHOOK_VERBOSE`](./env.md#lefthook_verbose) ENV to make lefthook show git LFS output. + +### Pass stdin to a command or script + +When you need to read the data from stdin – specify [`use_stdin: true`](../configuration/use_stdin.md). This option is good when you write a command or script that receives data from git using stdin (for the `pre-push` hook, for example). + +### Using an interactive command or script + +When you need to interact with user – specify [`interactive: true`](../configuration/interactive.md). Lefthook will connect to the current TTY and forward it to your command's or script's stdin.