Closed travi closed 3 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.
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
:
commitmsg
is simply commitlint -e
, which tells commitlint to look for its config in the project (allows us to vary the config per project as needed)precommit
is basically just npm t
, but we've inconsistently started ensuring that the working directory isn't dirty beyond the staged files with if [ -n \"$(git ls-files --other --exclude-standard --directory)\" ] || [ -n \"$(git diff --exit-code)\" ]; then echo \"--- Current branch is not clean ---\" \n exit 1; fi && npm test
(i plan to pull this into an npm cli package to reduce the noise, but you get the idea)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:
npm t
before a push. we havent done this yet because of concern of the time involved in running the whole verification script multiple times in a row when committing and then pushing, but we are considering it. (it would be awesome if husky added smarts to the "dumb" hooks fired by git to prevent running a script on push, for example, if it ran the same script for the last hook and nothing has changed since, but obviously far out of scope of the request for a shareable config)npm it
(maybe nvm use
as well) upon a pull, but there is no pull hook. our attempts so far have been to use postcheckout
as well as postrewrite
in order to cover normal pulls as well as pull w/ rebase. we've backed away from postrewrite
because it also fires for cases like an interactive rebase where no pull happened and seemed to be mostly redundant with postcheckout
. postcheckout
fires when checking out branches w/o pulls as well. sometimes different branches have different dependencies, so its helpful, but other cases like creating a new branch don't benefit from that. i really wish there simply was a pull hook...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 :)
+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.
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.
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());
any chance this will make the cut for v1.0?
Any update on this?
Would you like some help with this issue?
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.
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...
@m1gu3l I created new issue (#662) to track that regression in behavior
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 yournode_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?
Added a section to the docs explaining one way to share hooks with the new husky.
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.
The mentioned solution is terrible.
@typicode any word on the comments above?
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 viarequire()
) 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?
@eliasjnior nope, you're not crazy. It appears to have been removed.
@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 :/
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).