typicode / husky

Git hooks made easy 🐶 woof!
https://typicode.github.io/husky
MIT License
31.75k stars 999 forks source link

shareable config #245

Closed travi closed 3 years ago

travi commented 6 years ago

have you considered a shareable config? i find myself using the same scripts across almost all of my node projects, so it would be great to be able to extend a config that i publish as a node package as a starting point.

ideally, support would look similar to those available from

with the upcoming support for config files through cosmicconfig, adding support for extending other files seems like a very natural fit.

i like the convention of those listed above where a package named husky-config-travi could be used as "extends": "travi", which would apply the config from the dependency, but allow additional config to define more information or override config from the shareable config.

does supporting something along these lines seem reasonable? i think it would be a huge help in my personal projects and those for my team.

as an example use case, we just had a conversation about a change we want to try out, but trying it consistently across all projects will require updating each individually (and possibly changing them all back if the change is one we decide we dont like). defining the change in a shareable config would limit the actual definition to a single place and only require us to update that package through npm (which we already automate with greenkeeper and greenkeeper-keeper).

typicode commented 6 years ago

Hi @travi,

I like the idea :) (I think there's another issue suggesting something similar) What kind of hook would you share in your team? I'd like to understand what a real world example would look like.

travi commented 6 years ago

sorry about missing an existing issue. i guess my search terms missed the mark.

as far as the hooks we would want to share, we are pretty solid on commitmsg and precommit:

the others we are still trying to figure out exactly where we want to land, which leads to the desire to experiement, but consistently, that i mentioned earlier:

our builds are pretty fast, but if you make a commit (runs npm t), push that commit (we'd like to run npm t), find that you have to pull remote changes first (runs npm it), and then push (would run npm t yet again), its enough to be a bit annoying for fairly rare benefit. therefore, we're still experimenting with what the best balance is for those last few. being able to experiment consistently across all of our projects would be hugely helpful :)

weslexcore commented 6 years ago

+1 would be beneficial to have a .husky file that I can configure in outside of package.json - I use husky across multiple projects and also help teams with setting their projects up and being able to point them to a config file / just use my config file would be beneficial.

travi commented 6 years ago

in case it is helpful, i ran across a library called ex-config that is meant to work with cosmicconfig to support extension of other config. i havent looked very deep to understand if it would support what i mentioned above, but figured it was worth at least including here.

otakustay commented 6 years ago

In my case we provide a fe-tools package for all frontend projects, I'm trying to let this package automatically install husky hooks for project, however after npm install fe-tools the project looks like:

package.json
/node_modules
  /fe-tools
    /node_modules
      /husky

Although I can use a postinstall npm script to modify root package.json and add husky section, I don't know how to initialize git hooks for project, and how git hooks can locate husky correctly (since it is hidden inside fe-tools package)

It could be very useful if husky can provide a Node API which initialize all things above, look like:

"scripts": {
  "postinstall": "node init.js"
}

and within init.js:

const husky = require('husky'); // This can locate husky package correctly

// cwd() will be the root of project, not `fe-tools` package directory,
// update package.json and add git hooks here,
// husky's location can be resolved using `require.resolve` within husky package itself
husky.initialize(process.cwd());
travi commented 5 years ago

any chance this will make the cut for v1.0?

dv29 commented 5 years ago

Any update on this?

mrmckeb commented 5 years ago

Would you like some help with this issue?

pwentz commented 5 years ago

Our use case is the same as @otakustay, so I think it would also be very beneficial to add the eslint-style extends feature. If anybody is looking for a workaround, you can just use a .huskyrc.js file and import the file from your node_modules:

// .huskyrc.js
module.exports = require('node_modules/my-private-config-pkg/husky');
// node_modules/my-private-config-pkg/husky.json
{
  "hooks": { ... }
}

If you want to "extend" the original configuration then you can merge it with another object that overwrites the keys you want to override.

m1gu3l commented 4 years ago

husky.sh

hookIsDefined () {
  grep -qs $hookName \
    package.json \
    .huskyrc \
    .huskyrc.json \
    .huskyrc.yaml \
    .huskyrc.yml \
    .huskyrc.js \
    husky.config.js
}

# Skip fast if hookName is not defined
if ! hookIsDefined; then
  debug "$hookName config not found, skipping hook"
  exit 0
fi

If hook name is not contained directly within one of acceptable config locations hook won't run at all...

gurpreetatwal commented 4 years ago

@m1gu3l I created new issue (#662) to track that regression in behavior

gugol2 commented 3 years ago

Our use case is the same as @otakustay, so I think it would also be very beneficial to add the eslint-style extends feature. If anybody is looking for a workaround, you can just use a .huskyrc.js file and import the file from your node_modules:

// .huskyrc.js
module.exports = require('node_modules/my-private-config-pkg/husky');
// node_modules/my-private-config-pkg/husky.json
{
  "hooks": { ... }
}

If you want to "extend" the original configuration then you can merge it with another object that overwrites the keys you want to override.

In my case what I got common is the .huskyrc file and I would like to somehow extend it in my project so I can do more things in the hooks that what is established in the common husky config... I guess .huskyrc has priority over the other husky config formats, right? so .huskyrc has always preference over .husky.js

Am I wrong?

typicode commented 3 years ago

Added a section to the docs explaining one way to share hooks with the new husky.

markcellus commented 3 years ago

Hmm do you mean this section? It shows how to create a shareable config but not sure if I understand how I'd use it in node project.

I think this could be better achieved by allowing the husky config file be its own module with a .js extension. That way, you can just import a shareable config (from another file via require()) into it which will be natively executable in a node JS environment. I believe that's what the request is here.

JounQin commented 3 years ago

The mentioned solution is terrible.

markcellus commented 2 years ago

@typicode any word on the comments above?

eliasjnior commented 2 years ago

Hmm do you mean this section? It shows how to create a shareable config but not sure if I understand how I'd use it in node project.

I think this could be better achieved by allowing the husky config file be its own module with a .js extension. That way, you can just import a shareable config (from another file via require()) into it which will be natively executable in a node JS environment. I believe that's what the request is here.

Am I crazy or "this section" doesn't exist?

markcellus commented 2 years ago

@eliasjnior nope, you're not crazy. It appears to have been removed.

eliasjnior commented 2 years ago

@eliasjnior nope, you're not crazy. It appears to have been removed.

So this issue should be reopened. I was trying to standardize some projects like I do with ESLint rules, using { extends: "@organization/project" }, but looks like it won't be possible to do the same with Husky :/