mirror of
https://github.com/hanzoai/husky.git
synced 2026-09-24 16:59:45 +00:00
@@ -12,7 +12,7 @@ Before creating an issue, please check:
|
||||
https://typicode.github.io/husky/#/?id=troubleshoot
|
||||
|
||||
If you're migrating from husky 4, see:
|
||||
https://typicode.github.io/husky/#/?id=migrate-from-v4-to-v5
|
||||
https://typicode.github.io/husky/#/?id=migrate-from-v4-to-v6
|
||||
|
||||
**Context**
|
||||
Please describe your issue and provide some context:
|
||||
|
||||
@@ -22,5 +22,5 @@ jobs:
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- run: npm ci
|
||||
- run: npm run postinstall --if-present
|
||||
- run: npm test
|
||||
|
||||
|
||||
+1
-2
@@ -1,2 +1 @@
|
||||
By contributing, you agree to release your modifications under the MIT
|
||||
license (see the file LICENSE-MIT).
|
||||
By contributing, you agree to release your modifications under the MIT license (see the file LICENSE-MIT).
|
||||
|
||||
@@ -1 +1,21 @@
|
||||
License Zero Parity 7.0.0 (see LICENSE-PARITY file) and MIT (contributions, see LICENSE-MIT file) with exception License Zero Patron 1.0.0 (see LICENSE-PATRON file)
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2021 typicode
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
@@ -1,71 +0,0 @@
|
||||
# The Parity Public License 7.0.0
|
||||
|
||||
Contributor: Typicode
|
||||
|
||||
Source Code: https://github.com/typicode/husky
|
||||
|
||||
## Purpose
|
||||
|
||||
This license allows you to use and share this software for free, but you have to share software that builds on it alike.
|
||||
|
||||
## Agreement
|
||||
|
||||
In order to receive this license, you have to agree to its rules. Those rules are both obligations under that agreement and conditions to your license. Don't do anything with this software that triggers a rule you can't or won't follow.
|
||||
|
||||
## Notices
|
||||
|
||||
Make sure everyone who gets a copy of any part of this software from you, with or without changes, also gets the text of this license and the contributor and source code lines above.
|
||||
|
||||
## Copyleft
|
||||
|
||||
[Contribute](#contribute) software you develop, operate, or analyze with this software, including changes or additions to this software. When in doubt, [contribute](#contribute).
|
||||
|
||||
## Prototypes
|
||||
|
||||
You don't have to [contribute](#contribute) any change, addition, or other software that meets all these criteria:
|
||||
|
||||
1. You don't use it for more than thirty days.
|
||||
|
||||
2. You don't share it outside the team developing it, other than for non-production user testing.
|
||||
|
||||
3. You don't develop, operate, or analyze other software with it for anyone outside the team developing it.
|
||||
|
||||
## Reverse Engineering
|
||||
|
||||
You may use this software to operate and analyze software you can't [contribute](#contribute) in order to develop alternatives you can and do [contribute](#contribute).
|
||||
|
||||
## Contribute
|
||||
|
||||
To [contribute](#contribute) software:
|
||||
|
||||
1. Publish all source code for the software in the preferred form for making changes through a freely accessible distribution system widely used for similar source code so the contributor and others can find and copy it.
|
||||
|
||||
2. Make sure every part of the source code is available under this license or another license that allows everything this license does, such as [the Blue Oak Model License 1.0.0](https://blueoakcouncil.org/license/1.0.0), [the Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0.html), [the MIT license](https://spdx.org/licenses/MIT.html), or [the two-clause BSD license](https://spdx.org/licenses/BSD-2-Clause.html).
|
||||
|
||||
3. Take these steps within thirty days.
|
||||
|
||||
4. Note that this license does _not_ allow you to change the license terms for this software. You must follow [Notices](#notices).
|
||||
|
||||
## Excuse
|
||||
|
||||
You're excused for unknowingly breaking [Copyleft](#copyleft) if you [contribute](#contribute) as required, or stop doing anything requiring this license, within thirty days of learning you broke the rule. You're excused for unknowingly breaking [Notices](#notices) if you take all practical steps to comply within thirty days of learning you broke the rule.
|
||||
|
||||
## Defense
|
||||
|
||||
Don't make any legal claim against anyone accusing this software, with or without changes, alone or with other technology, of infringing any patent.
|
||||
|
||||
## Copyright
|
||||
|
||||
The contributor licenses you to do everything with this software that would otherwise infringe their copyright in it.
|
||||
|
||||
## Patent
|
||||
|
||||
The contributor licenses you to do everything with this software that would otherwise infringe any patents they can license or become able to license.
|
||||
|
||||
## Reliability
|
||||
|
||||
The contributor can't revoke this license.
|
||||
|
||||
## No Liability
|
||||
|
||||
***As far as the law allows, this software comes as is, without any warranty or condition, and the contributor won't be liable to anyone for any damages related to this software or this license, under any kind of legal claim.***
|
||||
@@ -1,63 +0,0 @@
|
||||
# Patron License 1.0.0
|
||||
|
||||
Payment Platforms:
|
||||
- https://github.com/sponsors/typicode
|
||||
- https://opencollective.com/husky
|
||||
- https://www.patreon.com/typicode
|
||||
|
||||
Participating Contributors:
|
||||
- Typicode
|
||||
|
||||
## Purpose
|
||||
|
||||
This license gives everyone patronizing contributors to this software permission to ignore any noncommercial or copyleft rules of its free public license, while continuing to protect contributors from liability.
|
||||
|
||||
## Acceptance
|
||||
|
||||
In order to agree to these terms and receive a license, you must qualify under [Patrons](#patrons). The rules of these terms are both obligations under your agreement and conditions to your license. That agreement and your license continue only while you qualify as a patron. You must not do anything with this software that triggers a rule that you cannot or will not follow.
|
||||
|
||||
## Patrons
|
||||
|
||||
To accept these terms, you must be enrolled to make regular payments through any of the payment platforms pages listed above, in amounts qualifying you for a tier that includes a "patron license" or otherwise identifies a license under these terms as a reward.
|
||||
|
||||
## Scope
|
||||
|
||||
Except under [Seat](#seat) and [Applications](#applications), you may not sublicense or transfer any agreement or license under these terms to anyone else.
|
||||
|
||||
## Seat
|
||||
|
||||
If a legal entity, rather than an individual, accepts these terms, the entity may sublicense one individual employee or independent contractor at any given time. If the employee or contractor breaks any rule of these terms, the entity will stand directly responsible.
|
||||
|
||||
## Applications
|
||||
|
||||
If you combine this software with other software in a larger application, you may sublicense this software as part of your larger application, and allow further sublicensing in turn, under these rules:
|
||||
|
||||
1. Your larger application must have significant additional content or functionality beyond that of this software, and end users must license your larger application primarily for that added content or functionality.
|
||||
|
||||
2. You may not sublicense anyone to break any rule of the public license for this software for any changes of their own or any software besides your larger application.
|
||||
|
||||
3. You may build, and sublicense for, as many larger applications as you like.
|
||||
|
||||
## Copyright
|
||||
|
||||
Each contributor licenses you to do everything with this software that would otherwise infringe that contributor's copyright in it.
|
||||
|
||||
## Notices
|
||||
|
||||
You must ensure that everyone who gets a copy of any part of this software from you, with or without changes, also gets the texts of both this license and the free public license for this software.
|
||||
|
||||
## Excuse
|
||||
|
||||
If anyone notifies you in writing that you have not complied with [Notices](#notices), you can keep your agreement and your license by taking all practical steps to comply within 30 days after the notice. If you do not do so, your agreement under these terms ends immediately, and your license ends with it.
|
||||
|
||||
## Patent
|
||||
|
||||
Each contributor licenses you to do everything with this software that would otherwise infringe any patent claims they can license or become able to license.
|
||||
|
||||
## Reliability
|
||||
|
||||
No contributor can revoke this license, but your license may end if you break any rule of these terms.
|
||||
|
||||
## No Liability
|
||||
|
||||
***As far as the law allows, this software comes as is, without any warranty or condition, and no contributor will be liable to anyone for any damages related to this software or this license, under any kind of legal claim.***
|
||||
@@ -1,50 +1,45 @@
|
||||
# husky
|
||||
|
||||
[](https://opencollective.com/husky) [](https://www.npmjs.org/package/husky) [](https://github.com/typicode/husky/actions)
|
||||
[](https://opencollective.com/husky) [](https://www.npmjs.org/package/husky) [](https://github.com/typicode/husky/actions)
|
||||
|
||||
> Git hooks made easy
|
||||
> Modern native Git hooks made easy
|
||||
|
||||
Husky improves your commits and more 🐶 *woof!*
|
||||
|
||||
- [**Documentation v5 - ❤️ 100% free for Open Source and recommended for Sponsors (🎁 non-sponsors can try it for 30-days)**](https://typicode.github.io/husky)
|
||||
- [Documentation v4 - actively maintained and recommended for other projects](https://github.com/typicode/husky/tree/v4)
|
||||
# Usage
|
||||
|
||||
👋 [Jan 23, 2021: Read husky 5 announcement and see what's new](https://blog.typicode.com/husky-5/)
|
||||
Edit `package.json > prepare` script:
|
||||
|
||||
Note: __husky 5 is a major version with breaking changes.__ Upgrading from v4 to v5 requires additional steps, please see the docs.
|
||||
```sh
|
||||
npm set-script prepare "husky install"
|
||||
```
|
||||
|
||||
Add a hook:
|
||||
|
||||
```sh
|
||||
npx husky add .husky/pre-commit "npm test"
|
||||
```
|
||||
|
||||
Make a commit:
|
||||
|
||||
```sh
|
||||
$ git commit -m "Keep calm and commit"
|
||||
```
|
||||
|
||||
For more use cases, see documentation.
|
||||
|
||||
## Documentation
|
||||
|
||||
https://typicode.github.io/husky
|
||||
|
||||
__Important__ Upgrading from v4 to v6 requires additional steps, please see the docs.
|
||||
|
||||
## License
|
||||
|
||||
You're viewing documentation for husky 5, which is free to use in Open Source projects and in early access for Sponsors.
|
||||
|
||||
To use this new version at work, you can become a sponsor on [GitHub Sponsors](https://github.com/sponsors/typicode) or [Open Collective](https://opencollective.com/husky) (monthly or yearly donations are supported). __You can also try it for 30-days.__
|
||||
|
||||
__If you can't sponsor Husky, that's okay, [husky 4](https://github.com/typicode/husky/tree/master) is free for any project. During the early access, v4 will continue to receive maintainance updates.__
|
||||
|
||||
After the early access, husky 5 will be MIT again.
|
||||
|
||||
__And once again, it's free for Open Source. Also since husky is a devDependency the license is limited to your project only.__
|
||||
|
||||
### Context
|
||||
|
||||
I left my job to be able to work on Open Source. This will allow to compensate for the time on this release and fund new projects. Thank you for your understanding and support!
|
||||
|
||||
__If you have any questions/doubts about the temporary license, feel free to [email](https://github.com/typicode) me. I'll be happy to answer! :)__
|
||||
|
||||
### Excuse
|
||||
|
||||
If you've mistakenly installed husky 5 at work, no worries. You're excused for unknowingly breaking the license and can try husky 5 for 30-days.
|
||||
|
||||
See [LICENSE-PARITY](https://github.com/typicode/husky/blob/main/LICENSE-PARITY) excuse section for more details.
|
||||
|
||||
# Sponsors
|
||||
|
||||
Many thanks to everyone who is funding my work! 🙏
|
||||
MIT
|
||||
|
||||
## Companies
|
||||
|
||||
<!-- for (let i = 0; i < 40; i++) console.log(`[](https://opencollective.com/husky/backer/${i}/website)`) -->
|
||||
|
||||
<a href="https://opencollective.com/husky/tiers/sponsor/0/website"><img src="https://opencollective.com/husky/tiers/sponsor/0/avatar.svg" height="80px"></a>
|
||||
<a href="https://opencollective.com/husky/tiers/sponsor/1/website"><img src="https://opencollective.com/husky/tiers/sponsor/1/avatar.svg" height="80px"></a>
|
||||
<a href="https://opencollective.com/husky/tiers/sponsor/2/website"><img src="https://opencollective.com/husky/tiers/sponsor/2/avatar.svg" height="80px"></a>
|
||||
@@ -52,55 +47,7 @@ Many thanks to everyone who is funding my work! 🙏
|
||||
<a href="https://opencollective.com/husky/tiers/sponsor/4/website"><img src="https://opencollective.com/husky/tiers/sponsor/4/avatar.svg" height="80px"></a>
|
||||
<a href="https://opencollective.com/husky/tiers/sponsor/5/website"><img src="https://opencollective.com/husky/tiers/sponsor/5/avatar.svg" height="80px"></a>
|
||||
<a href="https://opencollective.com/husky/tiers/sponsor/6/website"><img src="https://opencollective.com/husky/tiers/sponsor/6/avatar.svg" height="80px"></a>
|
||||
<a href="https://opencollective.com/husky/tiers/sponsor/7/website"><img src="https://opencollective.com/husky/tiers/sponsor/7/avatar.svg" height="80px"></a>
|
||||
<a href="https://opencollective.com/husky/tiers/sponsor/8/website"><img src="https://opencollective.com/husky/tiers/sponsor/8/avatar.svg" height="80px"></a>
|
||||
<a href="https://opencollective.com/husky/tiers/sponsor/9/website"><img src="https://opencollective.com/husky/tiers/sponsor/9/avatar.svg" height="80px"></a>
|
||||
|
||||
[Become a sponsor and have your logo here and in the docs](https://opencollective.com/husky/contribute/sponsor-9986/checkout)
|
||||
|
||||
## Individuals
|
||||
|
||||
Find Husky helpful? Become a sponsor and show your appreciation with a monthly donation on [Open Collective](https://opencollective.com/husky). You can also tip with a one-time donation.
|
||||
|
||||
[](https://opencollective.com/husky/backer/0/website)
|
||||
[](https://opencollective.com/husky/backer/1/website)
|
||||
[](https://opencollective.com/husky/backer/2/website)
|
||||
[](https://opencollective.com/husky/backer/3/website)
|
||||
[](https://opencollective.com/husky/backer/4/website)
|
||||
[](https://opencollective.com/husky/backer/5/website)
|
||||
[](https://opencollective.com/husky/backer/6/website)
|
||||
[](https://opencollective.com/husky/backer/7/website)
|
||||
[](https://opencollective.com/husky/backer/8/website)
|
||||
[](https://opencollective.com/husky/backer/9/website)
|
||||
[](https://opencollective.com/husky/backer/10/website)
|
||||
[](https://opencollective.com/husky/backer/11/website)
|
||||
[](https://opencollective.com/husky/backer/12/website)
|
||||
[](https://opencollective.com/husky/backer/13/website)
|
||||
[](https://opencollective.com/husky/backer/14/website)
|
||||
[](https://opencollective.com/husky/backer/15/website)
|
||||
[](https://opencollective.com/husky/backer/16/website)
|
||||
[](https://opencollective.com/husky/backer/17/website)
|
||||
[](https://opencollective.com/husky/backer/18/website)
|
||||
[](https://opencollective.com/husky/backer/19/website)
|
||||
[](https://opencollective.com/husky/backer/20/website)
|
||||
[](https://opencollective.com/husky/backer/21/website)
|
||||
[](https://opencollective.com/husky/backer/22/website)
|
||||
[](https://opencollective.com/husky/backer/23/website)
|
||||
[](https://opencollective.com/husky/backer/24/website)
|
||||
[](https://opencollective.com/husky/backer/25/website)
|
||||
[](https://opencollective.com/husky/backer/26/website)
|
||||
[](https://opencollective.com/husky/backer/27/website)
|
||||
[](https://opencollective.com/husky/backer/28/website)
|
||||
[](https://opencollective.com/husky/backer/29/website)
|
||||
[](https://opencollective.com/husky/backer/30/website)
|
||||
[](https://opencollective.com/husky/backer/31/website)
|
||||
[](https://opencollective.com/husky/backer/32/website)
|
||||
[](https://opencollective.com/husky/backer/33/website)
|
||||
[](https://opencollective.com/husky/backer/34/website)
|
||||
[](https://opencollective.com/husky/backer/35/website)
|
||||
[](https://opencollective.com/husky/backer/36/website)
|
||||
[](https://opencollective.com/husky/backer/37/website)
|
||||
[](https://opencollective.com/husky/backer/38/website)
|
||||
[](https://opencollective.com/husky/backer/39/website)
|
||||
|
||||
GitHub sponsors can be viewed on my [sponsors page](https://github.com/sponsors/typicode#sponsors). All past and current Open Collective sponsors can be viewed on [Husky's Open Collective](https://opencollective.com/husky).
|
||||
The full list of Sponsors can be viewed in the docs, on Open Collective and on GitHub sponsors.
|
||||
|
||||
+76
-46
@@ -1,32 +1,61 @@
|
||||
[](https://opencollective.com/husky) [](https://www.npmjs.org/package/husky) [](https://github.com/typicode/husky/actions)
|
||||
|
||||
> Git hooks made easy
|
||||
> Modern native git hooks made easy
|
||||
|
||||
Husky improves your commits and more 🐶 _woof!_
|
||||
|
||||
You can use it to **lint your commit messages**, **run tests**, **lint code**, etc... when you commit or push. Husky supports [all](https://git-scm.com/docs/githooks) Git hooks.
|
||||
|
||||
# Announcement
|
||||
|
||||
**👋 [Read husky 5 announcement and see what's new](https://dev.to/typicode/what-s-new-in-husky-5-32g5)**
|
||||
|
||||
?> You're viewing documentation for husky v5, which is free to use in Open Source projects ❤️ and in early access for Sponsors 🎁. To use this new version at work, you can become a sponsor on [GitHub Sponsors](https://github.com/sponsors/typicode) or [Open Collective](https://opencollective.com/husky).<br><br>If you can't sponsor Husky, that's okay, [husky v4](https://github.com/typicode/husky/tree/master) is free to use in any project.
|
||||
|
||||
# Features
|
||||
|
||||
- Zero dependencies
|
||||
- Lightweight (`~0.02MB` vs `~1MB` for husky 4)
|
||||
- Fast (`~0.01s` vs `~0.5s` for husky 4)
|
||||
- Supports macOS, Linux and Windows
|
||||
- Zero dependencies and lightweight (`6 kB`)
|
||||
- Powered by modern new Git feature (`core.hooksPath`)
|
||||
- Follows [npm](https://docs.npmjs.com/cli/v7/using-npm/scripts#best-practices) and [Yarn](https://yarnpkg.com/advanced/lifecycle-scripts#a-note-about-postinstall) best practices regarding autoinstall
|
||||
- User-friendly messages
|
||||
- Optional install
|
||||
- __Like husky 4, supports__
|
||||
- macOS, Linux and Windows
|
||||
- Git GUIs
|
||||
- Custom directories
|
||||
- Monorepos
|
||||
|
||||
# Used by
|
||||
|
||||
The new husky is used by these awesome projects:
|
||||
|
||||
- [webpack/webpack](https://github.com/webpack/webpack)
|
||||
- [angular/angular](https://github.com/angular/angular)
|
||||
- [angular/angular-cli](https://github.com/angular/angular-cli)
|
||||
- [angular/components](https://github.com/angular/components)
|
||||
- [vercel/hyper](https://github.com/vercel/hyper)
|
||||
- [blitz-js/blitz](https://github.com/blitz-js/blitz)
|
||||
- [facebook/docusaurus](https://github.com/facebook/docusaurus)
|
||||
- [typescript-eslint/typescript-eslint](https://github.com/typescript-eslint/typescript-eslint)
|
||||
- [11ty/eleventy](https://github.com/11ty/eleventy)
|
||||
- [stylelint/stylelint](https://github.com/stylelint/stylelint)
|
||||
- [rollup/rollup](https://github.com/rollup/rollup)
|
||||
- [tauri-apps/tauri](https://github.com/tauri-apps/tauri)
|
||||
- [NativeScript/NativeScript](https://github.com/NativeScript/NativeScript)
|
||||
- [formatjs/formatjs](https://github.com/formatjs/formatjs)
|
||||
- [react-bootstrap/react-bootstrap](https://github.com/react-bootstrap/react-bootstrap)
|
||||
- [react-dnd/react-dnd](https://github.com/react-dnd/react-dnd)
|
||||
- [react-grid-layout/react-grid-layout](https://github.com/react-grid-layout/react-grid-layout)
|
||||
- [snabbdom/snabbdom](https://github.com/snabbdom/snabbdom)
|
||||
- [logaretm/vee-validate](https://github.com/logaretm/vee-validate)
|
||||
- [zenorocha/clipboard.js](https://github.com/zenorocha/clipboard.js)
|
||||
- [NodeBB/NodeBB](https://github.com/NodeBB/NodeBB)
|
||||
- And [__more__](https://github.com/typicode/husky/network/dependents?package_id=UGFja2FnZS0xODQzNTgwNg%3D%3D)
|
||||
|
||||
# Usage
|
||||
|
||||
Already using husky? See [Migrate from 4 to 5](/?id=migrate-from-v4-to-v5).
|
||||
Already using husky? See [Migrate from 4 to 6](/?id=migrate-from-v4-to-v6).
|
||||
|
||||
## Automatic (recommended)
|
||||
|
||||
```shell
|
||||
npm install husky --save-dev && npx husky init
|
||||
npx @husky/init && npm install # npm
|
||||
npx @husky/init && yarn # Yarn 1
|
||||
yarn dlx @husky/init --yarn2 && yarn # Yarn 2
|
||||
```
|
||||
|
||||
The command above will setup husky, modify `package.json` and create a sample `pre-commit` hook that you can edit. By default, it will run `npm test` when you commit.
|
||||
@@ -57,6 +86,12 @@ npx husky install
|
||||
|
||||
3. To automatically have Git hooks enabled after install, edit `package.json`
|
||||
|
||||
```shell
|
||||
npm set-script prepare "husky install"
|
||||
```
|
||||
|
||||
You should have:
|
||||
|
||||
```js
|
||||
// package.json
|
||||
{
|
||||
@@ -66,11 +101,11 @@ npx husky install
|
||||
}
|
||||
```
|
||||
|
||||
!> **Yarn v2 doesn't support `prepare` lifecycle script, so husky needs to be installed differently (this doesn't apply to yarn v1 though). See [Yarn v2 install](/?id=yarn-v2).**
|
||||
!> **Yarn 2 doesn't support `prepare` lifecycle script, so husky needs to be installed differently (this doesn't apply to Yarn 1 though). See [Yarn 2 install](/?id=yarn-v2).**
|
||||
|
||||
### Add a hook
|
||||
### Create a hook
|
||||
|
||||
To add a hook, use `husky add <file> [cmd]` (don't forget to run `husky install` before).
|
||||
To add a command to a hook or create a new one, use `husky add <file> [cmd]` (don't forget to run `husky install` before).
|
||||
|
||||
```shell
|
||||
npx husky add .husky/pre-commit "npm test"
|
||||
@@ -92,7 +127,7 @@ If `npm test` command fails, your commit will be automatically aborted.
|
||||
npm uninstall husky
|
||||
```
|
||||
|
||||
## Yarn v2
|
||||
## Yarn 2
|
||||
|
||||
### Install
|
||||
|
||||
@@ -100,7 +135,7 @@ npm uninstall husky
|
||||
|
||||
```shell
|
||||
yarn add husky --dev
|
||||
yarn add pinst --dev # if your package is not private
|
||||
yarn add pinst --dev # ONLY if your package is not private
|
||||
```
|
||||
|
||||
2. Enable Git hooks
|
||||
@@ -114,7 +149,7 @@ yarn husky install
|
||||
```js
|
||||
// package.json
|
||||
{
|
||||
"private": true,
|
||||
"private": true, // ← your package is private, you only need postinstall
|
||||
"scripts": {
|
||||
"postinstall": "husky install"
|
||||
}
|
||||
@@ -126,7 +161,7 @@ yarn husky install
|
||||
```js
|
||||
// package.json
|
||||
{
|
||||
"private": false,
|
||||
"private": false, // ← your package is public
|
||||
"scripts": {
|
||||
"postinstall": "husky install",
|
||||
"prepublishOnly": "pinst --disable",
|
||||
@@ -245,8 +280,8 @@ git config gitflow.path.hooks .husky
|
||||
|
||||
**Note:**
|
||||
|
||||
- If you are configuring git-flow _after_ you have installed Husky, the git-flow setup process will correctly suggest the .husky directory.
|
||||
- If you have set a [custom directory](/?id=custom-directory) for Husky you need to specify that (ex. `git config gitflow.path.hooks .config/husky`)
|
||||
- If you are configuring git-flow _after_ you have installed husky, the git-flow setup process will correctly suggest the .husky directory.
|
||||
- If you have set a [custom directory](/?id=custom-directory) for husky you need to specify that (ex. `git config gitflow.path.hooks .config/husky`)
|
||||
|
||||
To **revert** the git-flow hooks directory back to its default you need to reset the config to point to the default Git hooks directory.
|
||||
|
||||
@@ -316,16 +351,6 @@ fi
|
||||
yarn ...
|
||||
```
|
||||
|
||||
# Free for Open Source, early access for Sponsors
|
||||
|
||||
How it works?
|
||||
|
||||
- If you have an Open Source project, you're free to install or upgrade husky to v5 ❤️
|
||||
- If you have a commercial project and are a Sponsor, you can start using v5 today at work 🎁
|
||||
- You can try it for 30-days and if you've mistakenly installed husky 5 in a commercial projects, you're excused (see [Parity License](https://github.com/typicode/husky/blob/main/LICENSE-PARITY) for more details).
|
||||
|
||||
To acquire a proprietary-use license, simply go to [GitHub Sponsors](https://github.com/sponsors/typicode) or [Open Collective](https://opencollective.com/husky).
|
||||
|
||||
# Breaking changes
|
||||
|
||||
Environment variables:
|
||||
@@ -335,11 +360,11 @@ Environment variables:
|
||||
- `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.
|
||||
|
||||
# Migrate from v4 to v5
|
||||
# Migrate from v4 to v6
|
||||
|
||||
## husky-4-to-5 CLI
|
||||
## husky-4-to-6 CLI
|
||||
|
||||
See [husky-4-to-5](https://github.com/typicode/husky-4-to-5) CLI to quickly migrate from v4 to v5.
|
||||
See [husky-4-to-6](https://github.com/typicode/husky-4-to-5) CLI to quickly migrate from v4 to v6.
|
||||
|
||||
## Package scripts
|
||||
|
||||
@@ -355,7 +380,7 @@ If you were calling `package.json` scripts using `npm` or `yarn`, **you can simp
|
||||
```
|
||||
|
||||
```shell
|
||||
# .husky/pre-commit (v5)
|
||||
# .husky/pre-commit (v6)
|
||||
# ...
|
||||
npm test
|
||||
npm run foo
|
||||
@@ -375,7 +400,7 @@ If you were calling directly locally installed binaries, **you need to run them
|
||||
```
|
||||
|
||||
```shell
|
||||
# .husky/pre-commit (v5)
|
||||
# .husky/pre-commit (v6)
|
||||
# ...
|
||||
npx --no-install jest
|
||||
yarn jest
|
||||
@@ -395,7 +420,7 @@ Previous `HUSKY_GIT_PARAMS` environment variable is replaced by native params `$
|
||||
```
|
||||
|
||||
```shell
|
||||
# .husky/commit-msg (v5)
|
||||
# .husky/commit-msg (v6)
|
||||
# ...
|
||||
npx --no-install commitlint --edit $1
|
||||
# or
|
||||
@@ -406,9 +431,7 @@ yarn commitlint --edit $1
|
||||
|
||||
## Companies
|
||||
|
||||
<!-- for (let i = 0; i < 40; i++) console.log(`[](https://opencollective.com/husky/backer/${i}/website)`) -->
|
||||
|
||||
Does your company use Husky? Ask your manager or marketing team if your company would be interested in supporting this project.
|
||||
Does your company use husky? Ask your manager or marketing team if your company would be interested in supporting this project.
|
||||
|
||||
<a href="https://opencollective.com/husky/tiers/sponsor/0/website"><img src="https://opencollective.com/husky/tiers/sponsor/0/avatar.svg" height="80px"></a>
|
||||
<a href="https://opencollective.com/husky/tiers/sponsor/1/website"><img src="https://opencollective.com/husky/tiers/sponsor/1/avatar.svg" height="80px"></a>
|
||||
@@ -423,7 +446,7 @@ Does your company use Husky? Ask your manager or marketing team if your company
|
||||
|
||||
## Individuals
|
||||
|
||||
Find Husky helpful? Become a backer and show your appreciation with a monthly donation on [Open Collective](https://opencollective.com/husky). You can also tip with a one-time donation.
|
||||
Find husky helpful? Become a backer and show your appreciation with a monthly donation on [Open Collective](https://opencollective.com/husky). You can also tip with a one-time donation.
|
||||
|
||||
[](https://opencollective.com/husky/backer/0/website)
|
||||
[](https://opencollective.com/husky/backer/1/website)
|
||||
@@ -465,11 +488,18 @@ Find Husky helpful? Become a backer and show your appreciation with a monthly do
|
||||
[](https://opencollective.com/husky/backer/37/website)
|
||||
[](https://opencollective.com/husky/backer/38/website)
|
||||
[](https://opencollective.com/husky/backer/39/website)
|
||||
[](https://opencollective.com/husky/backer/40/website)
|
||||
[](https://opencollective.com/husky/backer/41/website)
|
||||
[](https://opencollective.com/husky/backer/42/website)
|
||||
[](https://opencollective.com/husky/backer/43/website)
|
||||
[](https://opencollective.com/husky/backer/44/website)
|
||||
[](https://opencollective.com/husky/backer/45/website)
|
||||
[](https://opencollective.com/husky/backer/46/website)
|
||||
[](https://opencollective.com/husky/backer/47/website)
|
||||
[](https://opencollective.com/husky/backer/48/website)
|
||||
|
||||
GitHub sponsors can be viewed on my [profile](https://github.com/typicode). All past and current Open Collective sponsors can be viewed on [Husky's Open Collective](https://opencollective.com/husky).
|
||||
GitHub sponsors can be viewed on my [profile](https://github.com/typicode). All past and current Open Collective sponsors can be viewed on [here](https://opencollective.com/husky).
|
||||
|
||||
# License
|
||||
|
||||
[License Zero Parity 7.0.0](https://paritylicense.com/versions/7.0.0.html) and MIT (contributions) with exception [License Zero Patron 1.0.0](https://patronlicense.com/versions/1.0.0).
|
||||
|
||||
👉 See the [announcement](/?id=announcement) for more details.
|
||||
MIT
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
<meta charset="UTF-8" />
|
||||
<title>Husky - Git hooks</title>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
|
||||
<meta name="description" content="Git hooks made easy" />
|
||||
<meta name="description" content="Modern native Git hooks made easy" />
|
||||
<meta
|
||||
name="viewport"
|
||||
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
module.exports = {
|
||||
preset: 'ts-jest',
|
||||
testEnvironment: 'node',
|
||||
};
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"packages": [
|
||||
"packages/*"
|
||||
],
|
||||
"version": "6.0.0"
|
||||
}
|
||||
Generated
+19523
-964
File diff suppressed because it is too large
Load Diff
+19
-78
@@ -1,89 +1,30 @@
|
||||
{
|
||||
"name": "husky",
|
||||
"version": "5.2.0",
|
||||
"description": "Git hooks made easy",
|
||||
"bin": {
|
||||
"husky": "lib/bin.js"
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"bootstrap": "lerna bootstrap",
|
||||
"build": "del-cli \"packages/**/lib\" && lerna exec -- tsc && cpy --cwd=./packages/husky src/husky.sh lib",
|
||||
"lint": "eslint . --ext .ts --ignore-path .gitignore",
|
||||
"test": "sh test/_run_all.sh",
|
||||
"serve": "docsify serve docs",
|
||||
"prepare": "npm run build && node packages/husky/lib/bin.js install"
|
||||
},
|
||||
"files": [
|
||||
"/lib",
|
||||
"/scripts",
|
||||
"LICENSE",
|
||||
"LICENSE-MIT",
|
||||
"LICENSE-PARITY",
|
||||
"LICENSE-PATRON"
|
||||
],
|
||||
"author": "Typicode <[email protected]>",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@commitlint/cli": "^12.0.1",
|
||||
"@commitlint/config-conventional": "^12.0.1",
|
||||
"@commitlint/prompt-cli": "^12.0.1",
|
||||
"@tsconfig/node10": "^1.0.7",
|
||||
"@types/node": "^14.14.25",
|
||||
"@types/jest": "^26.0.22",
|
||||
"@types/node": "^14.14.37",
|
||||
"@typicode/eslint-config": "^0.1.2",
|
||||
"cpy-cli": "^3.1.1",
|
||||
"del-cli": "^3.0.1",
|
||||
"docsify-cli": "^4.4.2",
|
||||
"type-fest": "^0.21.2",
|
||||
"typescript": "^4.1.3"
|
||||
},
|
||||
"scripts": {
|
||||
"prebuild": "del-cli lib",
|
||||
"build": "tsc",
|
||||
"serve": "docsify serve docs",
|
||||
"lint": "eslint . --ext .js,.ts --ignore-path .gitignore",
|
||||
"prepare": "npm run build && node lib/bin install",
|
||||
"preuninstall": "node lib/bin uninstall",
|
||||
"preversion": "npm run build",
|
||||
"postversion": "git push && git push --tags && npm publish",
|
||||
"pretest": "npm run build --silent && npm pack --silent",
|
||||
"test": "sh ./test/init.sh && sh ./test/init-yarn-2.sh && sh ./test/default.sh && sh ./test/sub-dir.sh && sh ./test/config-dir.sh && sh ./test/not-git-dir.sh && sh ./test/set-add.sh",
|
||||
"posttest": "rm husky-*.tgz",
|
||||
"commit": "commit"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/typicode/husky.git"
|
||||
},
|
||||
"keywords": [
|
||||
"git",
|
||||
"hook",
|
||||
"hooks",
|
||||
"test",
|
||||
"lint",
|
||||
"applypatch-msg",
|
||||
"pre-applypatch",
|
||||
"post-applypatch",
|
||||
"pre-commit",
|
||||
"pre-merge-commit",
|
||||
"prepare-commit-msg",
|
||||
"commit-msg",
|
||||
"post-commit",
|
||||
"pre-rebase",
|
||||
"post-checkout",
|
||||
"post-merge",
|
||||
"pre-push",
|
||||
"post-update",
|
||||
"push-to-checkout",
|
||||
"pre-auto-gc",
|
||||
"post-rewrite",
|
||||
"sendemail-validate"
|
||||
],
|
||||
"author": "Typicode <[email protected]>",
|
||||
"license": "Parity-7.0.0 AND MIT WITH Patron-1.0.0",
|
||||
"bugs": {
|
||||
"url": "https://github.com/typicode/husky/issues"
|
||||
},
|
||||
"homepage": "https://github.com/typicode/husky#readme",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/typicode"
|
||||
},
|
||||
{
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/husky"
|
||||
"docsify-cli": "^4.4.3",
|
||||
"husky": "^5.2.0",
|
||||
"jest": "^26.6.3",
|
||||
"lerna": "^4.0.0",
|
||||
"ts-jest": "^26.5.4",
|
||||
"typescript": "^4.2.3"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020
|
||||
Copyright (c) 2021 typicode
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -0,0 +1,37 @@
|
||||
# husky
|
||||
|
||||
[](https://opencollective.com/husky)
|
||||
|
||||
> Modern native Git hooks made easy
|
||||
|
||||
Husky improves your commits and more 🐶 *woof!*
|
||||
|
||||
# Usage
|
||||
|
||||
Edit `package.json > prepare` script and run it once:
|
||||
|
||||
```sh
|
||||
npm set-script prepare "husky install" && npm run prepare
|
||||
```
|
||||
|
||||
Add a hook:
|
||||
|
||||
```sh
|
||||
npx husky add .husky/pre-commit "npm test"
|
||||
```
|
||||
|
||||
Make a commit:
|
||||
|
||||
```sh
|
||||
$ git commit -m "Keep calm and commit"
|
||||
```
|
||||
|
||||
# Documentation
|
||||
|
||||
https://typicode.github.io/husky
|
||||
|
||||
__Important__ upgrading from v4 to v6 requires additional steps, please see the docs.
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"name": "husky",
|
||||
"version": "6.0.0",
|
||||
"description": "Modern native Git hooks made easy",
|
||||
"bin": "lib/bin.js",
|
||||
"main": "lib/index.js",
|
||||
"files": [
|
||||
"lib"
|
||||
],
|
||||
"keywords": [
|
||||
"git",
|
||||
"hooks",
|
||||
"pre-commit"
|
||||
],
|
||||
"author": "Typicode <[email protected]>",
|
||||
"license": "MIT",
|
||||
"homepage": "https://typicode.github.io/husky",
|
||||
"repository": "github:typicode/husky",
|
||||
"funding": "https://github.com/sponsors/typicode"
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
#!/usr/bin/env node
|
||||
import fs = require('fs')
|
||||
import path = require('path')
|
||||
import { PackageJson } from 'type-fest'
|
||||
|
||||
import { add, install, set, uninstall } from './'
|
||||
|
||||
function readPkg(): PackageJson {
|
||||
return JSON.parse(
|
||||
fs.readFileSync(path.join(__dirname, '../package.json'), 'utf-8'),
|
||||
) as PackageJson
|
||||
}
|
||||
|
||||
const pkg = readPkg()
|
||||
|
||||
const [, , cmd, ...args] = process.argv
|
||||
|
||||
function version() {
|
||||
console.log(pkg.version)
|
||||
}
|
||||
|
||||
function help() {
|
||||
console.log(`Usage
|
||||
husky install [dir] (default: .husky)
|
||||
husky uninstall
|
||||
husky set|add <file> [cmd]`)
|
||||
}
|
||||
|
||||
function misuse() {
|
||||
help()
|
||||
process.exit(2)
|
||||
}
|
||||
|
||||
const cmds: { [key: string]: (...args: string[]) => void } = {
|
||||
install(dir: string): void {
|
||||
args.length > 1 ? misuse() : install(dir)
|
||||
},
|
||||
uninstall,
|
||||
set(...args) {
|
||||
args.length === 0 || args.length > 2 ? misuse() : set(args[0], args[1])
|
||||
},
|
||||
add(...args) {
|
||||
args.length === 0 || args.length > 2 ? misuse() : add(args[0], args[1])
|
||||
},
|
||||
'--version': version,
|
||||
'-v': version,
|
||||
}
|
||||
|
||||
cmds[cmd] ? cmds[cmd](...args) : help()
|
||||
@@ -0,0 +1,89 @@
|
||||
import fs = require('fs')
|
||||
import cp = require('child_process')
|
||||
import path = require('path')
|
||||
|
||||
function l(msg: string): void {
|
||||
console.log(`husky - ${msg}`)
|
||||
}
|
||||
|
||||
export function install(dir = '.husky'): void {
|
||||
// Ensure that we're inside a git repository
|
||||
if (cp.spawnSync('git', ['rev-parse']).status !== 0) {
|
||||
l('not a Git repository, skipping hooks installation')
|
||||
return
|
||||
}
|
||||
|
||||
// Custom dir help
|
||||
const url = 'https://typicode.github.io/husky/#/?id=custom-directory'
|
||||
|
||||
// Ensure that we're not trying to install outside of cwd
|
||||
if (!path.resolve(process.cwd(), dir).startsWith(process.cwd())) {
|
||||
throw new Error(`.. not allowed (see ${url})`)
|
||||
}
|
||||
|
||||
// Ensure that cwd is git top level
|
||||
if (!fs.existsSync('.git')) {
|
||||
throw new Error(`.git can't be found (see ${url})`)
|
||||
}
|
||||
|
||||
try {
|
||||
// Create .husky/_
|
||||
fs.mkdirSync(path.join(dir, '_'), { recursive: true })
|
||||
|
||||
// Create .husky/.gitignore
|
||||
fs.writeFileSync(path.join(dir, '.gitignore'), '_\n')
|
||||
|
||||
// Copy husky.sh to .husky/_/husky.sh
|
||||
fs.copyFileSync(
|
||||
path.join(__dirname, 'husky.sh'),
|
||||
path.join(dir, '_/husky.sh'),
|
||||
)
|
||||
|
||||
// Configure repo
|
||||
const { error } = cp.spawnSync('git', ['config', 'core.hooksPath', dir])
|
||||
if (error) {
|
||||
throw error
|
||||
}
|
||||
} catch (e) {
|
||||
l('Git hooks failed to install')
|
||||
throw e
|
||||
}
|
||||
|
||||
l('Git hooks installed')
|
||||
}
|
||||
|
||||
export function set(file: string, cmd: string): void {
|
||||
const dir = path.dirname(file)
|
||||
if (!fs.existsSync(dir)) {
|
||||
throw new Error(
|
||||
`can't create hook, ${dir} directory doesn't exist (try running husky install)`,
|
||||
)
|
||||
}
|
||||
|
||||
fs.writeFileSync(
|
||||
file,
|
||||
`#!/bin/sh
|
||||
. "$(dirname "$0")/_/husky.sh"
|
||||
|
||||
${cmd}
|
||||
`,
|
||||
{ mode: 0o0755 },
|
||||
)
|
||||
|
||||
l(`created ${file}`)
|
||||
}
|
||||
|
||||
export function add(file: string, cmd: string): void {
|
||||
if (fs.existsSync(file)) {
|
||||
fs.appendFileSync(file, `${cmd}\n`)
|
||||
l(`updated ${file}`)
|
||||
} else {
|
||||
set(file, cmd)
|
||||
}
|
||||
}
|
||||
|
||||
export function uninstall(): void {
|
||||
cp.spawnSync('git', ['config', '--unset', 'core.hooksPath'], {
|
||||
stdio: 'inherit',
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"rootDir": "./src",
|
||||
"outDir": "./lib"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2021 typicode
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -0,0 +1,17 @@
|
||||
# @husky/init
|
||||
|
||||
> Install and setup husky quickly
|
||||
|
||||
```shell
|
||||
npx @husky/init && npm install # npm
|
||||
npx @husky/init && yarn # Yarn 1
|
||||
npx @husky/init --yarn2 && yarn # Yarn 2
|
||||
```
|
||||
|
||||
# Documentation
|
||||
|
||||
https://typicode.github.io/husky
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "@husky/init",
|
||||
"version": "6.0.0",
|
||||
"description": "",
|
||||
"bin": "lib/bin.js",
|
||||
"dependencies": {
|
||||
"husky": "6.0.0"
|
||||
},
|
||||
"author": "Typicode <[email protected]>",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"type-fest": "^1.0.1"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
#!/usr/bin/env node
|
||||
import fs = require('fs')
|
||||
import { install, set } from 'husky'
|
||||
import { PackageJson } from 'type-fest'
|
||||
|
||||
import { updatePkg } from '.'
|
||||
|
||||
const [, , arg] = process.argv
|
||||
|
||||
// Read package.json
|
||||
const str = fs.readFileSync('package.json', 'utf-8')
|
||||
const pkg = JSON.parse(str) as PackageJson
|
||||
|
||||
// Update package.json
|
||||
updatePkg(pkg, arg === '--yarn2')
|
||||
|
||||
// Write package.json
|
||||
const regex = /^[ ]+|\t+/m
|
||||
const indent = regex.exec(str)?.[0]
|
||||
fs.writeFileSync('package.json', `${JSON.stringify(pkg, null, indent)}\n`)
|
||||
console.log('husky - updated package.json')
|
||||
|
||||
// Install husky
|
||||
install()
|
||||
|
||||
// Add pre-commit sample
|
||||
set('.husky/pre-commit', 'npm test')
|
||||
@@ -0,0 +1,20 @@
|
||||
import { PackageJson } from 'type-fest'
|
||||
|
||||
export function updatePkg(pkg: PackageJson, isYarn2: boolean): PackageJson {
|
||||
pkg.devDependencies ||= {}
|
||||
pkg.devDependencies.husky = '^6.0.0'
|
||||
if (isYarn2) {
|
||||
pkg.scripts ||= {}
|
||||
pkg.scripts.postinstall = 'husky install'
|
||||
if (pkg.private !== true) {
|
||||
pkg.scripts.prepublishOnly = 'pinst --disable'
|
||||
pkg.scripts.postpublish = 'pinst --enable'
|
||||
pkg.devDependencies.pinst = '^2.0.0'
|
||||
}
|
||||
} else {
|
||||
pkg.scripts ||= {}
|
||||
pkg.scripts.prepare = 'husky install'
|
||||
}
|
||||
|
||||
return pkg
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"rootDir": "./src",
|
||||
"outDir": "./lib"
|
||||
}
|
||||
}
|
||||
-96
@@ -1,96 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
import fs from 'fs'
|
||||
import path from 'path'
|
||||
import { PackageJson } from 'type-fest'
|
||||
|
||||
import { init } from './commands/init'
|
||||
import { install } from './commands/install'
|
||||
import { add, set } from './commands/set_add'
|
||||
import { uninstall } from './commands/uninstall'
|
||||
|
||||
function readPkg(): PackageJson {
|
||||
return JSON.parse(
|
||||
fs.readFileSync(path.join(__dirname, '../package.json'), 'utf-8'),
|
||||
) as PackageJson
|
||||
}
|
||||
|
||||
const pkg = readPkg()
|
||||
|
||||
const [, , cmd, ...args] = process.argv
|
||||
|
||||
function version() {
|
||||
console.log(pkg.version)
|
||||
}
|
||||
|
||||
function help() {
|
||||
console.log(`Usage
|
||||
|
||||
husky init
|
||||
husky install [dir] (default: .husky)
|
||||
husky uninstall
|
||||
husky set <file> [cmd]
|
||||
husky add <file> [cmd]
|
||||
|
||||
Examples
|
||||
husky init
|
||||
|
||||
husky install
|
||||
husky install .config/husky
|
||||
|
||||
husky set .husky/pre-commit
|
||||
husky set .husky/pre-commit "npm test"
|
||||
husky set .config/husky/pre-commit "npm test"
|
||||
|
||||
husky add .husky/pre-commit
|
||||
husky add .husky/pre-commit "npm test"
|
||||
husky add .config/husky/pre-commit "npm test"
|
||||
`)
|
||||
}
|
||||
|
||||
switch (cmd) {
|
||||
case 'init': {
|
||||
const isYarn2 = String(process.env.npm_config_user_agent).startsWith(
|
||||
'yarn/2',
|
||||
)
|
||||
init(isYarn2)
|
||||
break
|
||||
}
|
||||
case 'install': {
|
||||
if (args.length > 2) {
|
||||
help()
|
||||
process.exit(2)
|
||||
}
|
||||
install(args[0])
|
||||
break
|
||||
}
|
||||
case 'uninstall': {
|
||||
uninstall()
|
||||
break
|
||||
}
|
||||
case 'set': {
|
||||
if (args.length === 0 || args.length > 2) {
|
||||
help()
|
||||
process.exit(2)
|
||||
}
|
||||
set(args[0], args[1])
|
||||
break
|
||||
}
|
||||
case 'add': {
|
||||
if (args.length === 0 || args.length > 2) {
|
||||
help()
|
||||
process.exit(2)
|
||||
}
|
||||
add(args[0], args[1])
|
||||
break
|
||||
}
|
||||
case '--version': {
|
||||
version()
|
||||
break
|
||||
}
|
||||
case '-v': {
|
||||
version()
|
||||
break
|
||||
}
|
||||
default:
|
||||
help()
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
import fs from 'fs'
|
||||
import { PackageJson } from 'type-fest'
|
||||
|
||||
import { l } from '../log'
|
||||
import { install } from './install'
|
||||
import { set } from './set_add'
|
||||
|
||||
const regex = /^[ ]+|\t+/m
|
||||
|
||||
export function init(isYarn2: boolean): void {
|
||||
// Read package.json
|
||||
const str = fs.readFileSync('package.json', 'utf-8')
|
||||
const pkg = JSON.parse(str) as PackageJson
|
||||
|
||||
// Update package.json fields
|
||||
if (isYarn2) {
|
||||
pkg.scripts ||= {}
|
||||
pkg.scripts.postinstall = 'husky install'
|
||||
if (pkg.private !== true) {
|
||||
pkg.scripts.prepublishOnly = 'pinst --disable'
|
||||
pkg.scripts.postpublish = 'pinst --enable'
|
||||
pkg.devDependencies ||= {}
|
||||
pkg.devDependencies.pinst = '^2.0.0'
|
||||
}
|
||||
} else {
|
||||
pkg.scripts ||= {}
|
||||
pkg.scripts.prepare = 'husky install'
|
||||
}
|
||||
|
||||
// Write package.json
|
||||
const indent = regex.exec(str)?.[0]
|
||||
fs.writeFileSync('package.json', `${JSON.stringify(pkg, null, indent)}\n`)
|
||||
l('updated package.json')
|
||||
|
||||
// Install husky
|
||||
install()
|
||||
|
||||
// Add pre-commit sample
|
||||
set('.husky/pre-commit', 'npm test')
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
import cp from 'child_process'
|
||||
import fs from 'fs'
|
||||
import path from 'path'
|
||||
|
||||
import { l } from '../log'
|
||||
|
||||
const customDirHelp = 'https://typicode.github.io/husky/#/?id=custom-directory'
|
||||
|
||||
export function install(dir = '.husky'): void {
|
||||
// Ensure that we're inside a git repository
|
||||
if (cp.spawnSync('git', ['rev-parse']).status !== 0) {
|
||||
l('not a Git repository, skipping hooks installation')
|
||||
return
|
||||
}
|
||||
|
||||
// Ensure that we're not trying to install outside of cwd
|
||||
const absoluteHooksDir = path.resolve(process.cwd(), dir)
|
||||
if (!absoluteHooksDir.startsWith(process.cwd())) {
|
||||
throw new Error(`.. not allowed (see ${customDirHelp})`)
|
||||
}
|
||||
|
||||
// Ensure that cwd is git top level
|
||||
if (!fs.existsSync('.git')) {
|
||||
throw new Error(`.git can't be found (see ${customDirHelp})`)
|
||||
}
|
||||
|
||||
try {
|
||||
// Create .husky/_
|
||||
fs.mkdirSync(path.join(dir, '_'), { recursive: true })
|
||||
|
||||
// Create .husky/.gitignore
|
||||
fs.writeFileSync(path.join(dir, '.gitignore'), '_\n', 'utf-8')
|
||||
|
||||
// Copy husky.sh to .husky/_/husky.sh
|
||||
fs.copyFileSync(
|
||||
path.join(__dirname, '../../scripts/husky.sh'),
|
||||
path.join(dir, '_/husky.sh'),
|
||||
)
|
||||
|
||||
// Configure repo
|
||||
const { error } = cp.spawnSync('git', ['config', 'core.hooksPath', dir])
|
||||
if (error) {
|
||||
throw error
|
||||
}
|
||||
} catch (e) {
|
||||
l('Git hooks failed to install')
|
||||
throw e
|
||||
}
|
||||
|
||||
l('Git hooks installed')
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
import fs from 'fs'
|
||||
import path from 'path'
|
||||
|
||||
import { l } from '../log'
|
||||
|
||||
function data(cmd: string) {
|
||||
return `#!/bin/sh
|
||||
. "$(dirname "$0")/_/husky.sh"
|
||||
|
||||
${cmd}
|
||||
`
|
||||
}
|
||||
|
||||
// Show "./file" instead of just "file"
|
||||
function format(file: string): string {
|
||||
return `${path.dirname(file)}${path.sep}${path.basename(file)}`
|
||||
}
|
||||
|
||||
export function set(file: string, cmd: string): void {
|
||||
const dir = path.dirname(file)
|
||||
if (!fs.existsSync(dir)) {
|
||||
throw new Error(
|
||||
`can't create hook, ${dir} directory doesn't exist (try running husky install)`,
|
||||
)
|
||||
}
|
||||
|
||||
fs.writeFileSync(file, data(cmd), { mode: 0o0755 })
|
||||
|
||||
l(`created ${format(file)}`)
|
||||
}
|
||||
|
||||
export function add(file: string, cmd: string): void {
|
||||
if (fs.existsSync(file)) {
|
||||
fs.appendFileSync(file, `${cmd}\n`)
|
||||
l(`updated ${format(file)}`)
|
||||
} else {
|
||||
set(file, cmd)
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
import cp from 'child_process'
|
||||
|
||||
export function uninstall(): void {
|
||||
cp.spawnSync('git', ['config', '--unset', 'core.hooksPath'], {
|
||||
stdio: 'inherit',
|
||||
})
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
export function l(msg: string): void {
|
||||
console.log(`husky - ${msg}`)
|
||||
}
|
||||
+35
-17
@@ -1,38 +1,56 @@
|
||||
# Exit on error
|
||||
set -eu
|
||||
|
||||
function title {
|
||||
function setup {
|
||||
name="$(basename $0)"
|
||||
testDir="/tmp/husky-test-$name"
|
||||
echo
|
||||
echo "-------------------"
|
||||
echo "+ $1"
|
||||
echo "+ $name"
|
||||
echo "-------------------"
|
||||
echo
|
||||
}
|
||||
|
||||
# Create $1 and install tgz
|
||||
function cd_and_install_tgz {
|
||||
# Create directory
|
||||
mkdir -p $1
|
||||
# Create test directory
|
||||
rm -rf "$testDir"
|
||||
mkdir -p "$testDir"
|
||||
cd "$testDir"
|
||||
|
||||
# Install tarball generated by pretest script
|
||||
cp ./husky-*.tgz $1/husky.tgz
|
||||
cd $1 && npm init -y > /dev/null && npm install husky.tgz
|
||||
}
|
||||
|
||||
function init_git {
|
||||
git init
|
||||
# Init git
|
||||
git init --quiet
|
||||
git config user.email "test@test"
|
||||
git config user.name "test"
|
||||
|
||||
# Init package.json
|
||||
npm_config_loglevel="error"
|
||||
npm init -y 1>/dev/null
|
||||
}
|
||||
|
||||
function test_hooksPath {
|
||||
function install {
|
||||
npm install ../husky.tgz
|
||||
}
|
||||
|
||||
function expect {
|
||||
set +e
|
||||
sh -c "$2"
|
||||
exitCode="$?"
|
||||
set -e
|
||||
if [ $exitCode != "$1" ]; then
|
||||
error "expect command \"$2\" to exit with code $1 (got $exitCode)"
|
||||
fi
|
||||
}
|
||||
|
||||
function expect_hooksPath_to_be {
|
||||
readonly hooksPath=`git config core.hooksPath`
|
||||
if [ "$hooksPath" != "$1" ]; then
|
||||
echo -e "\e[0;31mERROR:\e[m core.hooksPath should be $1, was $hooksPath"
|
||||
exit 1
|
||||
error "core.hooksPath should be $1, was $hooksPath"
|
||||
fi
|
||||
}
|
||||
|
||||
function error {
|
||||
echo -e "\e[0;31mERROR:\e[m $1"
|
||||
exit 1
|
||||
}
|
||||
|
||||
function ok {
|
||||
echo -e "\e[0;32mOK\e[m"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
set -e
|
||||
npm run bootstrap
|
||||
npm run build
|
||||
(cd packages/husky && npm pack && mv husky-*.tgz /tmp/husky.tgz)
|
||||
(cd packages/init && npm link)
|
||||
sh test/config-dir.sh
|
||||
sh test/default.sh
|
||||
sh test/init.sh
|
||||
sh test/not-git-dir.sh
|
||||
sh test/set-add.sh
|
||||
sh test/sub-dir.sh
|
||||
+7
-17
@@ -1,25 +1,15 @@
|
||||
# shellcheck shell=bash
|
||||
|
||||
# shellcheck source=./_functions.sh
|
||||
. "$(dirname "$0")/_functions.sh"
|
||||
setup
|
||||
install
|
||||
|
||||
# Example:
|
||||
# .config/husky
|
||||
title "config directory"
|
||||
tempDir="/tmp/husky-config-dir-test"
|
||||
configDir="$tempDir/.config"
|
||||
|
||||
rm -rf $tempDir
|
||||
cd_and_install_tgz $tempDir
|
||||
mkdir $configDir
|
||||
|
||||
init_git
|
||||
# Test custom dir support
|
||||
mkdir .config
|
||||
npx --no-install husky install .config/husky
|
||||
npx --no-install husky add .config/husky/pre-commit "echo \"msg from pre-commit hook\" && exit 1"
|
||||
npx --no-install husky add .config/husky/pre-commit "echo \"pre-commit\" && exit 1"
|
||||
|
||||
# Test core.hooksPath
|
||||
test_hooksPath ".config/husky"
|
||||
expect_hooksPath_to_be ".config/husky"
|
||||
|
||||
# Test pre-commit
|
||||
git add package.json
|
||||
git commit -m "should fail" || ok
|
||||
expect 1 "git commit -m foo"
|
||||
|
||||
+6
-14
@@ -1,25 +1,17 @@
|
||||
# shellcheck shell=bash
|
||||
|
||||
# shellcheck source=./_functions.sh
|
||||
. "$(dirname "$0")/_functions.sh"
|
||||
setup
|
||||
install
|
||||
|
||||
title "default"
|
||||
tempDir="/tmp/husky-default-test"
|
||||
|
||||
rm -rf $tempDir
|
||||
cd_and_install_tgz $tempDir
|
||||
|
||||
init_git
|
||||
npx --no-install husky install
|
||||
npx --no-install husky add .husky/pre-commit "echo \"msg from pre-commit hook\" && exit 1"
|
||||
|
||||
# Test core.hooksPath
|
||||
test_hooksPath ".husky"
|
||||
expect_hooksPath_to_be ".husky"
|
||||
|
||||
# Test pre-commit
|
||||
git add package.json
|
||||
git commit -m "should fail" || ok
|
||||
npx --no-install husky add .husky/pre-commit "echo \"pre-commit\" && exit 1"
|
||||
expect 1 "git commit -m foo"
|
||||
|
||||
# Uninstall
|
||||
npx --no-install husky uninstall
|
||||
git config core.hooksPath || ok
|
||||
expect 1 "git config core.hooksPath"
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
# shellcheck shell=bash
|
||||
|
||||
# shellcheck source=./_functions.sh
|
||||
. "$(dirname "$0")/_functions.sh"
|
||||
|
||||
title "yarn v1"
|
||||
tempDir="/tmp/husky-yarn-1-test"
|
||||
|
||||
rm -rf $tempDir
|
||||
|
||||
# generated by pretest script
|
||||
tgz="./husky-*.tgz"
|
||||
|
||||
# Create directory
|
||||
mkdir -p $tempDir
|
||||
|
||||
# Install
|
||||
cp $tgz $tempDir/husky.tgz
|
||||
cd $tempDir
|
||||
yarn init -y && yarn add ./husky.tgz
|
||||
|
||||
init_git
|
||||
yarn husky init
|
||||
npm set-script test "echo \"msg from pre-commit hook\" && exit 1"
|
||||
|
||||
# Test package.json scripts
|
||||
grep '"prepare": "husky install"' package.json || ok
|
||||
|
||||
# Test core.hooksPath
|
||||
test_hooksPath ".husky"
|
||||
|
||||
# Test pre-commit
|
||||
git add package.json
|
||||
git commit -m "should fail" || ok
|
||||
|
||||
# Uninstall
|
||||
yarn remove husky
|
||||
git config core.hooksPath || ok
|
||||
@@ -1,46 +0,0 @@
|
||||
# shellcheck shell=bash
|
||||
|
||||
# shellcheck source=./_functions.sh
|
||||
. "$(dirname "$0")/_functions.sh"
|
||||
|
||||
title "yarn v2"
|
||||
tempDir="/tmp/husky-yarn-2-test"
|
||||
|
||||
rm -rf $tempDir
|
||||
|
||||
# generated by pretest script
|
||||
tgz="./husky-*.tgz"
|
||||
|
||||
# Create directory
|
||||
mkdir -p $tempDir
|
||||
|
||||
# Install
|
||||
cp $tgz $tempDir/husky.tgz
|
||||
cd $tempDir
|
||||
yarn set version berry && yarn init -y && yarn add ./husky.tgz
|
||||
|
||||
init_git
|
||||
yarn husky init
|
||||
yarn # will install pinst
|
||||
npm set-script test "echo \"msg from pre-commit hook\" && exit 1"
|
||||
|
||||
# Test package.json scripts
|
||||
grep '"postinstall": "husky install"' package.json || ok
|
||||
grep '"prepublishOnly": "pinst --disable"' package.json || ok
|
||||
grep '"postpublish": "pinst --enable"' package.json || ok
|
||||
|
||||
# Test core.hooksPath
|
||||
test_hooksPath ".husky"
|
||||
|
||||
# Test pre-commit
|
||||
git add package.json
|
||||
git commit -m "should fail" || ok
|
||||
|
||||
# Uninstall
|
||||
# Prevent yarn remove from failing due to missing husky command in postinstall
|
||||
npm set-script postinstall ""
|
||||
yarn remove husky
|
||||
|
||||
# Yarn 2 doesn't run husky's uninstall script, so core.hooksPath is still set
|
||||
# and needs to be manually removed
|
||||
git config core.hooksPath && ok
|
||||
+7
-19
@@ -1,28 +1,16 @@
|
||||
# shellcheck shell=bash
|
||||
|
||||
# shellcheck source=./_functions.sh
|
||||
. "$(dirname "$0")/_functions.sh"
|
||||
setup
|
||||
npm link @husky/init
|
||||
|
||||
title "init"
|
||||
tempDir="/tmp/husky-init-npm-test"
|
||||
|
||||
rm -rf $tempDir
|
||||
cd_and_install_tgz $tempDir
|
||||
|
||||
init_git
|
||||
npx --no-install husky init
|
||||
npm set-script test "echo \"msg from pre-commit hook\" && exit 1"
|
||||
npx --no-install init
|
||||
npm set-script test "echo \"pre-commit hook\" && exit 1"
|
||||
|
||||
# Test package.json scripts
|
||||
grep '"prepare": "husky install"' package.json || ok
|
||||
expect 0 "grep '\"prepare\": \"husky install\"' package.json"
|
||||
|
||||
# Test core.hooksPath
|
||||
test_hooksPath ".husky"
|
||||
expect_hooksPath_to_be ".husky"
|
||||
|
||||
# Test pre-commit
|
||||
git add package.json
|
||||
git commit -m "should fail" || ok
|
||||
|
||||
# Uninstall
|
||||
npx --no-install husky uninstall
|
||||
git config core.hooksPath || ok
|
||||
expect 1 "git commit -m foo"
|
||||
|
||||
+4
-10
@@ -1,13 +1,7 @@
|
||||
# shellcheck shell=bash
|
||||
|
||||
# shellcheck source=./_functions.sh
|
||||
. "$(dirname "$0")/_functions.sh"
|
||||
|
||||
title "not git dir"
|
||||
tempDir="/tmp/husky-not-git-dir"
|
||||
|
||||
rm -rf $tempDir
|
||||
cd_and_install_tgz $tempDir
|
||||
setup
|
||||
install
|
||||
|
||||
# Should not fail
|
||||
npx --no-install husky install && ok
|
||||
rm -rf .git
|
||||
expect 0 "npx --no-install husky install"
|
||||
|
||||
+2
-9
@@ -1,16 +1,9 @@
|
||||
# shellcheck shell=bash
|
||||
|
||||
# shellcheck source=./_functions.sh
|
||||
. "$(dirname "$0")/_functions.sh"
|
||||
setup
|
||||
install
|
||||
|
||||
title "set add"
|
||||
tempDir="/tmp/husky-set-add"
|
||||
f=".husky/pre-commit"
|
||||
|
||||
rm -rf $tempDir
|
||||
cd_and_install_tgz $tempDir
|
||||
|
||||
init_git
|
||||
npx --no-install husky install
|
||||
|
||||
npx --no-install husky add $f "foo"
|
||||
|
||||
+7
-16
@@ -1,23 +1,14 @@
|
||||
# shellcheck shell=bash
|
||||
|
||||
# shellcheck source=./_functions.sh
|
||||
. "$(dirname "$0")/_functions.sh"
|
||||
setup
|
||||
|
||||
# Example:
|
||||
# .git
|
||||
# sub/package.json
|
||||
title "sub directory"
|
||||
tempDir="/tmp/husky-sub-dir-test"
|
||||
subDir="$tempDir/sub"
|
||||
|
||||
rm -rf $tempDir
|
||||
cd_and_install_tgz $subDir
|
||||
|
||||
cd $tempDir
|
||||
init_git
|
||||
|
||||
# Edit package.json in sub directory
|
||||
cd $subDir
|
||||
mkdir sub
|
||||
cd sub
|
||||
npm install ../../husky.tgz
|
||||
cat > package.json << EOL
|
||||
{
|
||||
"scripts": {
|
||||
@@ -30,11 +21,11 @@ EOL
|
||||
npm run prepare
|
||||
|
||||
# Add hook
|
||||
npx --no-install husky add pre-commit "echo \"msg from pre-commit hook\" && exit 1"
|
||||
npx --no-install husky add .husky/pre-commit "echo \"pre-commit hook\" && exit 1"
|
||||
|
||||
# Test core.hooksPath
|
||||
test_hooksPath "sub/.husky"
|
||||
expect_hooksPath_to_be "sub/.husky"
|
||||
|
||||
# Test pre-commit
|
||||
git add package.json
|
||||
git commit -m "should fail" || ok
|
||||
expect 1 "git commit -m foo"
|
||||
|
||||
+1
-2
@@ -1,8 +1,7 @@
|
||||
{
|
||||
"extends": "@tsconfig/node10/tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"rootDir": "./src",
|
||||
"outDir": "./lib",
|
||||
"declaration": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"noImplicitReturns": true,
|
||||
|
||||
Reference in New Issue
Block a user