diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml index 51d664ba8..174c96883 100644 --- a/.github/workflows/node.js.yml +++ b/.github/workflows/node.js.yml @@ -11,12 +11,12 @@ jobs: test: strategy: matrix: - node-version: [18, 20] + node-version: [18, 20, 22] os: [ubuntu-latest, macOS-latest, windows-latest] runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v3 - - uses: actions/setup-node@v3 + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 with: node-version: ${{ matrix.node-version }} - run: npm --version diff --git a/.github/workflows/npm_publish.yml b/.github/workflows/npm_publish.yml index 5fb6528d7..ff513ea27 100644 --- a/.github/workflows/npm_publish.yml +++ b/.github/workflows/npm_publish.yml @@ -15,7 +15,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v4 with: node-version: 20 - run: ./test.sh @@ -27,7 +27,7 @@ jobs: id-token: write steps: - uses: actions/checkout@v4 - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v4 with: node-version: 20 registry-url: 'https://registry.npmjs.org' diff --git a/bin.mjs b/bin.js similarity index 75% rename from bin.mjs rename to bin.js index d954ed9ac..40d28590c 100755 --- a/bin.mjs +++ b/bin.js @@ -1,6 +1,6 @@ #!/usr/bin/env node import f, { writeFileSync as w } from 'fs' -import i from './index.mjs' +import i from './index.js' let p, a, n, s, o, d @@ -15,11 +15,11 @@ if (a == 'init') { w(n, JSON.stringify(o, 0, /\t/.test(s) ? '\t' : 2) + '\n') p.stdout.write(i()) try { f.mkdirSync('.husky') } catch {} - w('.husky/pre-commit', p.env.npm_config_user_agent.split('/')[0] + ' test\n') + w('.husky/pre-commit', p.env.npm_config_user_agent?.split('/')[0] ?? 'npm' + ' test\n') p.exit() } -d = c => console.error(`${c} command is deprecated`) +d = c => console.error(`${c} command is DEPRECATED`) if (['add', 'set', 'uninstall'].includes(a)) { d(a); p.exit(1) } if (a == 'install') d(a) diff --git a/docs/.vitepress/config.mts b/docs/.vitepress/config.mts index 8a4532744..734ae5870 100644 --- a/docs/.vitepress/config.mts +++ b/docs/.vitepress/config.mts @@ -12,11 +12,12 @@ export default defineConfig({ // outline: [2, 3], socialLinks: [ { icon: 'github', link: 'https://github.com/typicode/husky' }, + { icon: 'twitter', link: 'https://x.com/typicode' } ], - carbonAds: { - code: 'CWYDP53L', - placement: 'typicodegithubio', - }, + // carbonAds: { + // code: 'CWYDP53L', + // placement: 'typicodegithubio', + // }, sidebar: [ { text: 'Introduction', link: '/' }, { text: 'Get Started', link: '/get-started' }, @@ -25,15 +26,7 @@ export default defineConfig({ { text: 'Migrate from v4', link: '/migrate-from-v4' }, ], nav: [ - { - text: 'v9.0.1', - items: [ - { - text: 'Changelog', - link: 'https://github.com/typicode/husky/releases/tag/v9.0.1' - } - ] - } + { text: 'Sponsor', link: 'https://github.com/sponsors/typicode' } ] }, locales: { diff --git a/docs/get-started.md b/docs/get-started.md index 15d4d974c..2283b404e 100644 --- a/docs/get-started.md +++ b/docs/get-started.md @@ -59,5 +59,22 @@ git commit -m "Keep calm and commit" # test script will run every time you commit ``` -_For manual setup and more information, see the [How To](how-to) section._ +## A few words... +### Scripting + +While most of the time, you'll just run a few `npm run` or `npx` commands in your hooks, you can also script them using POSIX shell for custom workflows. + +For example, here's how you can lint your staged files on each commit with only two lines of shell code and no external dependency: + +```shell +# .husky/pre-commit +prettier $(git diff --cached --name-only --diff-filter=ACMR | sed 's| |\\ |g') --write --ignore-unknown +git update-index --again +``` + +_This is a basic but workinkg example, check [lint-staged](https://github.com/lint-staged/lint-staged) if you need more._ + +### Disabling hooks + +Husky doesn't force Git hooks. It can be globally disabled (`HUSKY=0`) or be opt-in if wanted. See the [How To](how-to) section for manual setup and more information. \ No newline at end of file diff --git a/docs/index.md b/docs/index.md index 2b54aa6af..556170c87 100644 --- a/docs/index.md +++ b/docs/index.md @@ -26,6 +26,7 @@ And more: - Adheres to Git's native hook organization - Aligns with [npm](https://docs.npmjs.com/cli/v10/using-npm/scripts#best-practices) best practices using `prepare` script - Opt-in/opt-out options +- Can be globally disabled - User-friendly error messages ## Sponsors @@ -60,7 +61,7 @@ Support this project by becoming a sponsor [here](https://github.com/sponsors/ty ## Used by -Husky is used in [**over 1.3M projects**](https://github.com/typicode/husky/network/dependents?package_id=UGFja2FnZS0xODQzNTgwNg%3D%3D) on GitHub, including: +Husky is used in [**over 1.5M projects**](https://github.com/typicode/husky/network/dependents?package_id=UGFja2FnZS0xODQzNTgwNg%3D%3D) on GitHub, including: - [vercel/next.js](https://github.com/vercel/next.js) - [vercel/hyper](https://github.com/vercel/hyper) diff --git a/docs/migrate-from-v4.md b/docs/migrate-from-v4.md index 3a3fc78b4..80f6aac79 100644 --- a/docs/migrate-from-v4.md +++ b/docs/migrate-from-v4.md @@ -35,10 +35,7 @@ If you were calling locally installed binaries, **you need to run them via your ``` ```shell [.husky/pre-commit (v9)] -# ... -npx --no jest -# or -yarn jest +jest ``` ::: @@ -56,10 +53,7 @@ yarn jest ``` ```shell [.husky/commit-msg (v9)] -# ... -npx --no -- commitlint --edit $1 -# or -yarn commitlint --edit $1 +commitlint --edit $1 ``` ::: @@ -68,5 +62,4 @@ Other environment variables changes: - `HUSKY_SKIP_HOOKS` is replaced by `HUSKY`. - `HUSKY_SKIP_INSTALL` is replaced by `HUSKY`. -- `HUSKY_GIT_PARAMS` is removed. Instead Git parameters should be used directly in scripts (e.g. `$1`). -- `PATH` for locally installed tools is not automatically set anymore. You'll need to use your package manager to run them. +- `HUSKY_GIT_PARAMS` is removed. Instead Git parameters should be used directly in scripts (e.g. `$1`). \ No newline at end of file diff --git a/docs/sponsorkit/sponsors.svg b/docs/sponsorkit/sponsors.svg index 53f650199..3d5338282 100644 --- a/docs/sponsorkit/sponsors.svg +++ b/docs/sponsorkit/sponsors.svg @@ -1,4 +1,4 @@ - + -Bronze Sponsors - risedotcom - +Gold Sponsors + Zuplo + + + + Microsoft + +Silver Sponsors + Kong + +Bronze Sponsors + risedotcom + - Storyblok - + Storyblok + - Better Stack - -Sponsors - Ehren - + Better Stack + +Sponsors + Ehren + - Erik Gross - + Erik Gross + - Cased - + Cased + - Dustin - + Dustin + - Extremely - + Extremely + - - Kenn - + + Jamie + - - Carlos - + + Comarch + - - James - -Backers - + + Mercury + + + + Ray Foss + +Backers + - + - + - - - - + - + - + - + - + - + - + - + - + - -Past Sponsors - + +Past Sponsors + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + + + + - + - + + + - - - - + + + + + - + - + - + - + - + - + + + + - + - + - + - + - + - - + + - + - + - + - + - + - + - + - - - - + + + - + - - - + + + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - + + + - + - - - + + + + - + - + - + - - - - + - + - + + + + - + - + - + - + - + - + - + - + - + - + - + - + - + + + - - + + - + - - - + + + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + + + + - + - + - + - - - - + + + - + - + - + - - - + + + + - + - + - + - - + + - + - + + + + - + - + - + - + - + - + + + + + + + - + - + - - - - + + + - + - + - + + + + - + - + - + - - - + + + + - + diff --git a/husky b/husky index 378dfd749..8edf346db 100644 --- a/husky +++ b/husky @@ -1,27 +1,27 @@ #!/usr/bin/env sh +# shellcheck disable=SC1090 [ "$HUSKY" = "2" ] && set -x -if command -v cygpath >/dev/null 2>&1; then - u0=$(cygpath -u "$0") - if [ "$0" != "$u0" ]; then - exec "$u0" "$@" - fi -fi - -h="${0##*/}" -s="${0%/*/*}/$h" +n=$(basename "$0") +s=$(dirname "$(dirname "$0")")/$n [ ! -f "$s" ] && exit 0 -for f in "${XDG_CONFIG_HOME:-$HOME/.config}/husky/init.sh" "$HOME/.huskyrc"; do - # shellcheck disable=SC1090 - [ -f "$f" ] && . "$f" -done +if [ -f "$HOME/.huskyrc" ]; then + echo "husky - '~/.huskyrc' is DEPRECATED, please move your code to ~/.config/husky/init.sh" +fi +i="${XDG_CONFIG_HOME:-$HOME/.config}/husky/init.sh" +[ -f "$i" ] && . "$i" [ "${HUSKY-}" = "0" ] && exit 0 -sh -e "$s" "$@" -c=$? - -[ $c != 0 ] && echo "husky - $h script failed (code $c)" -[ $c = 127 ] && echo "husky - command not found in PATH=$PATH" -exit $c \ No newline at end of file +c=0 +h() { + [ $c = 0 ] && return + [ $c != 0 ] && echo "husky - $n script failed (code $c)" + [ $c = 127 ] && echo "husky - command not found in PATH=$PATH" + exit 1 +} +trap 'c=$?; h' EXIT +set -e +PATH=node_modules/.bin:$PATH +. "$s" \ No newline at end of file diff --git a/index.d.mts b/index.d.ts similarity index 100% rename from index.d.mts rename to index.d.ts diff --git a/index.mjs b/index.js similarity index 97% rename from index.mjs rename to index.js index dd4e52865..73f55d39a 100644 --- a/index.mjs +++ b/index.js @@ -18,6 +18,5 @@ export default (d = '.husky') => { w(_('.gitignore'), '*') f.copyFileSync(new URL('husky', import.meta.url), _('h')) l.forEach(h => w(_(h), `#!/usr/bin/env sh\n. "\$(dirname "\$0")/h"`, { mode: 0o755 })) - w(_('husky.sh'), '') return '' } \ No newline at end of file diff --git a/package.json b/package.json index c1890fdc8..00355c20b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,7 @@ { "name": "husky", "version": "9.0.11", + "type": "module", "description": "Modern native Git hooks", "keywords": [ "git", @@ -15,9 +16,9 @@ "license": "MIT", "author": "typicode", "bin": { - "husky": "bin.mjs" + "husky": "bin.js" }, - "exports": "./index.mjs", + "exports": "./index.js", "engines": { "node": ">=18" } diff --git a/tea.yaml b/tea.yaml deleted file mode 100644 index 23a017a3f..000000000 --- a/tea.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# https://tea.xyz/what-is-this-file ---- -version: 1.0.0 -codeOwners: - - '0xeB520938F9A236E6ff1D001551f9731F97a38023' -quorum: 1 diff --git a/test.sh b/test.sh index 334b428f9..4153af277 100755 --- a/test.sh +++ b/test.sh @@ -8,7 +8,8 @@ sh test/3_from-sub-dir.sh sh test/4_not-git-dir.sh sh test/5_git_command_not_found.sh sh test/6_command_not_found.sh -sh test/7_set_u.sh -sh test/8_husky_0.sh -sh test/9_init.sh -sh test/10_time.sh +sh test/7_node_modules_path.sh +sh test/8_set_u.sh +sh test/9_husky_0.sh +sh test/10_init.sh +sh test/11_time.sh diff --git a/test/9_init.sh b/test/10_init.sh similarity index 100% rename from test/9_init.sh rename to test/10_init.sh diff --git a/test/10_time.sh b/test/11_time.sh similarity index 72% rename from test/10_time.sh rename to test/11_time.sh index 89a7cd8c8..9cbcece4f 100755 --- a/test/10_time.sh +++ b/test/11_time.sh @@ -6,5 +6,5 @@ install npx --no-install husky git add package.json -echo "echo pre-commit" >.husky/pre-commit +echo "echo pre-commit" > .husky/pre-commit time git commit -m foo diff --git a/test/7_node_modules_path.sh b/test/7_node_modules_path.sh new file mode 100755 index 000000000..ec72811e6 --- /dev/null +++ b/test/7_node_modules_path.sh @@ -0,0 +1,11 @@ +#!/bin/sh +. test/functions.sh +setup +install + +npx --no-install husky + +# Test pre-commit +git add package.json +echo 'echo "$PATH" | grep -q "node_modules/.bin"' > .husky/pre-commit +expect 0 "git commit -m foo" diff --git a/test/7_set_u.sh b/test/8_set_u.sh similarity index 100% rename from test/7_set_u.sh rename to test/8_set_u.sh diff --git a/test/8_husky_0.sh b/test/9_husky_0.sh similarity index 100% rename from test/8_husky_0.sh rename to test/9_husky_0.sh