UNPKG

@nozomiishii/lefthook-config

Version:
114 lines (78 loc) 4.12 kB
# @nozomiishii/lefthook-config English | [日本語](./README.ja.md) Shared [lefthook](https://github.com/evilmartians/lefthook) config. This package follows a **preset + fragments** layout: a thin preset (`recommended.yaml`) that `extends` reusable fragments (`hooks/<hook>/<job>.yaml`). Consumers can either pull the whole preset or cherry-pick individual fragments. <!-- Main Image --> <br> <div align="center"> <img src="https://media.giphy.com/media/US7vLRTU5sAPcQcEHx/giphy.gif" alt="Coding" width="480" /> </div> <div align="right"> <small>via Danielle Chenette on GIPHY</small> </div> <br> ## Install Use the [`nozo`](../nozo) CLI: ```sh pnpx nozo init ``` This adds `lefthook` and `@nozomiishii/lefthook-config` to your `devDependencies` (pinned) and writes a `lefthook.yaml` that extends the recommended preset. Auxiliary runtimes (currently `git-harvest`, used by the `cleanup-worktrees-and-branches` post-merge fragment) are wrapped by shims that this package ships under its own `bin` field, so they are exposed as `node_modules/.bin/nozo-*` without requiring consumers to add them as direct dependencies. ## Use the full preset `lefthook.yaml`: ```yaml extends: - node_modules/@nozomiishii/lefthook-config/recommended.yaml ``` Then: ```sh pnpx lefthook install ``` ## Cherry-pick fragments `lefthook.yaml`: ```yaml extends: - node_modules/@nozomiishii/lefthook-config/hooks/commit-msg/commitlint.yaml - node_modules/@nozomiishii/lefthook-config/hooks/post-merge/update-node-modules.yaml ``` ## Available fragments - `hooks/commit-msg/commitlint.yaml` — runs `nozo-commitlint` (provided by `@nozomiishii/commitlint-config`) - `hooks/post-merge/update-node-modules.yaml` — pnpm > bun > npm > yarn - `hooks/post-merge/cleanup-worktrees-and-branches.yaml` — runs [`git-harvest`](https://github.com/nozomiishii/git-harvest) via the `nozo-git-harvest` shim shipped by this package - `hooks/pre-commit/yaml.yaml` — fails the commit when staged files use the `.yml` extension (enforces `.yaml`) ## Authoring rules (important) These rules exist because of [evilmartians/lefthook#1258](https://github.com/evilmartians/lefthook/issues/1258) and other monorepo footguns. Please keep them. ### Rule 1: extends paths start with `node_modules/<pkg>/...` Lefthook does not change `root` during recursive `extends`. File-relative paths inside fragments resolve from the consumer git root and silently get ignored. - ❌ `extends: - ./hooks/commit-msg/commitlint.yaml` - ❌ `extends: - ../_shared/common.yaml` - ✅ `extends: - node_modules/@nozomiishii/lefthook-config/hooks/commit-msg/commitlint.yaml` ### Rule 2: do not extend the preset and a fragment that the preset already extends Lefthook errors with `possible recursion in extends: path X is specified multiple times`. ```yaml # bad — preset already pulls in commitlint.yaml, listing it again triggers recursion extends: - node_modules/@nozomiishii/lefthook-config/recommended.yaml - node_modules/@nozomiishii/lefthook-config/hooks/commit-msg/commitlint.yaml ``` Pick one: either the preset, or cherry-pick fragments — not both. ### Rule 3: shim binaries are namespaced Bins are in a flat namespace. `commitlint-config` exposes its shim as `nozo-commitlint`, not `commitlint`, to avoid colliding with `@commitlint/cli`'s own bin. ### Rule 4: hooks invoke shims directly, not via `nozo` ```yaml # fast path run: node_modules/.bin/nozo-commitlint --edit {1} # extra spawn (lefthook -> nozo -> shim -> commitlint) run: node_modules/.bin/nozo run commitlint --edit {1} ``` ### Rule 5: each shim lives where its config package lives Most runtime tools have their own `@nozomiishii/<x>-config` package, and that package ships the `nozo-<x>` shim (e.g. `@nozomiishii/commitlint-config` ships `nozo-commitlint`). `lefthook-config` itself is the exception: it composes a few auxiliary runtimes (currently `git-harvest`) that don't have a dedicated config package, so it ships those shims (`nozo-git-harvest`) directly. The principle is "one shim per runtime, owned by exactly one package" — never duplicate.