ghooks-org/ghooks

Consider deprecating in favor of husky?

kentcdodds opened this issue · 41 comments

Hey friends! So I recently found another similar module called husky. I've tried it on a few of my projects and really like it. Here are a few reasons I think it'd be great to deprecate ghooks and put our efforts behind husky:

  1. It's good to merge projects/choose a "winner" when that can reasonably be done and focus efforts
  2. They support git GUIs #40
  3. Config is slightly simpler

Thoughts? 💭

I'm personally going to stop working on ghooks in favor of husky. Removing myself from the list of collaborators and unwatching. Let's merge efforts.

Not sure it's possible to do something like this with husky though:

https://gist.github.com/okonet/9706ec3b7f29e05109f3744fbc1fc91e

Thanks for bringing this up. I had to do a little research, but I found that husky will store the parameters in an environment variable called GIT_PARAMS which you can access in your script 👍

Honestly, it's not quite as nice IMO, but it's not a terrible solution, and there aren't a lot of use cases you need those args so I'm good with it.

Sorry, I've never got back to this one… <insert lame excuse here 😊>

Yeah, I'm definitely in favour of sticking with a "winner". Actually, I'm looking for someone to maintain this project. By maintain I mean to support those who have to stay on ghooks (for whatever reason) until they move out. I'm going to spare some time to tidy this repo up and update the readme to mention that…

As far as passing the parameters to the script, perhaps this is the opportunity to collaborate and makeapullrequest.com to husky. 😄

I'm going to spare some time to tidy this repo up and update the readme to mention that…

Sounds great!

As for looking for another maintainer, I don't know what more help people need. Luckily a migration from ghooks to husky is pretty simple and straightforward (with the exception of the parameters thing, which most people aren't using).

@kentcdodds @gtramontina please add deprecation warning in readme so newcomers know that husky is more supported and maintained solution

Good idea @thecotne. Fancy making a PR?

There should be a notice on how to move to husky, as in how to uninstall the ghooks git hooks before installing husky

True, would you like to make a pull request?

I don't know what the right solution is. Deleting all your git hooks seems dangerous (unless you know what you're doing), asking the rest of my team to do that is also tedious.

Anyone using ghooks or husky will be managing all of their git hooks via the tool and will most likely not have any custom git hooks. So we could probably simply say:

To migrate from ghooks to husky, delete all of your git hooks first by deleting the .git/hooks directory (if you have any custom hooks, you should preserve those by deleting all other hooks individually). Then uninstall ghooks and install husky.

We could take it a step further and add a postuninstall hook to ghooks that deletes all of the hooks that are generated by ghooks. That'd make the process and instructions easier. But I'm afraid I can't commit any more time to this package.

Also, I'm going to go ahead and close this because the deprecation warning is good enough for me.

@kentcdodds would you be ok with a PR to add that text to the readme or is that overkill on the deprecation notice?

I'd be fine with that, but I'm no longer able to merge pull requests.

@gtramontina do you have an opinion on this?

Hey hey… sorry about the silence. Yeah, absolutely! I'm also noticing a few references to this issue. I'll get @kentcdodds' message, which looks just fine, and reference one of @st3v3nhun's commits as an example. Thank you all!

Just wanted to make an observation to those considering switching (which is what led me here) - husky does not seem to play well with Windows since it works by generating shell scripts; indeed there's an open issue.

Anything that depends on a shell environment is going to be tricky to make work reliably on windows. There's no guarantee a windows user even has git bash installed at all.

Oh, now that's a concern... I was under the impression husky worked cross-platform... 🤔 perhaps we should help make that happen.

I looked at the source briefly, and while it's pretty straightforward, it would kinda be a rewrite... the whole thing works by using shell scripts. :/ in that sense ghooks might already be in a better place??

I have no dog in the game either way (I use ghooks now, but it's so simple to implement that changing to something else is not a big deal). And I also don't know what the problems with ghooks are that led to the deprecation.. or if just generally this was conceding to their greater stars and momentum :)

But from the xplat perspective, ghooks seems like a better implementation, bugs notwithstanding. Not quite sure I understand the GUI support issue you mentioned at the top here though, which seems to be one of the points towards migrating to husky. We have people using ghooks with webstorm & VSCode and it works, But seems related (e.g. scripting vs. node).

That was one of the reasons why I initially started ghooks with node scripts (cross-platform)…

I just got back from a short off-the-grid time off and am now swamped with work again… I'd be happy to add/transfer ownership to anyone interested in maintaining this project. I'd suggest getting in touch with @typicode. Joining forces with husky would, perhaps, be better for everyone…

@gtramontina @kentcdodds First ❤️ for linking to husky.

@jamietre Actually, most of the time, when you install Git on Windows it comes with shell support. That's at least the case with Git installer, Git Desktop and probably most IDEs that comes with Git.

I'm not aware of all the tools and may be wrong, but I would say the common use cases are covered on Windows.

That said, I would be interested in knowing if there are popular Windows tools that comes without Git bash. This way husky could maybe better handle them (there's this issue).

Another advantage of the shell, is that if you're relying on nvm it's easier to work with it and GUI apps on OS X and Linux.

But as always, pick what you're more confortable with :)

@typicode Thanks for jumping in! I think everyone wants the same thing which is a single good solution that works for all users. So if it was just me I was worried it would be really simple! But even within my organization we have to support a lot of different configs - so I can't just pick something that works for me.

For background - I'm one of the few, the proud (?)... the Windows node developers. I wouldn't say it's by choice, but there it is. I have spent a lot of time over the last few years dealing with Windows incompatibilities, and also in trying to create a good command line environment for Windows. So I have a lot of experience with the nuances of the environment, and particularly with compatibility issues, since I use software frequently that has rarely been used by other Windows users. My company is primarily a Windows shop, but we host node applications on Linux, have a handful of devs using Linux, and some using the Windows bash, a number which is slowly increasing. (That in itself is a fascinating thing, since it mostly works like Linux, except you still have a Windows file system behind it).

So - the primary sticking point comes here, when you install Git for Windows:

image

While it does actually install the git bash with git, (and it would be hard to not have one), unless you select that third option with the big red warning, the unix shell tools are only available from a git bash. You'd be surprised how often this is the case. While I personally can't live without the unix tools, half the time when I pop onto someone's computer here, and they're in a CMD shell, I type ls, and I get "command not found."

So anyway if you are only working from a command line, and you only ever work within the git bash, then, maybe no problem. But that doesn't cover lots of other possibilities in windows.

  • When you launch git from a GUI app, it starts a new shell using the default Windows shell, which will almost always be CMD - and have no bash support
  • The git bash doesn't support linux binaries like zsh, so if you're interested in something that isn't awful and supports even basic command line editing, you probably use don't use the git bash, but use TCC, or maybe even PowerShell.
  • The git bash is actually less compatible in a windows environment with Node applications/modules than the CMD shell. This is because of packages with OS-specific dependencies that may not build correctly unless you're in a real windows CMD shell. While 99% of the time node/npm works fine in git bash, it doesn't always.
  • You could even be using CygWin which is a whole other thing, and while techically unsupported by node, many people still use it
  • I personally use MSYS2 rather than the git bash commands, which isn't a huge deal but the versions of the utilities are slightly different.

Even if you have unix utility command support in a default shell, compatibility problems come up. Some things just aren't supported:

  • using & to spawn a new process
  • filenames - Windows file paths have spaces a lot, and use a backslash to separate path segments. This requires a lot of careful handling to work correctly when generating scripts.
  • while most common commands are ported in the git bash, many bash script constructs just aren't available (like if/fi}. It's not actually a bash shell. It just has some of the common utilities compiled in windows.
  • There are some Windows CLI utilities that have the same name as some bash utilities (which is why that big red warning exists in the first place) so there are quite legitimate reasons for your scripting environment to not by default have these utilities available -- since it can break CMD scripts.

At the end of the day these issues are significant, and while perhaps it's possible to write something using shell scripting that can work most of the time for most people, it will never work for everyone in configurations that are entirely common.

So rather than fighting against all these configuration differences, it seems a lot easier to just not use the shell unless you have no other choice. Code like this:

'  [ -f package.json ] && cat package.json | grep -q "\\"$1\\"\\s*:"',

can be pretty easily written entirely in node and be 100% compatible with any windows, linux or mac user. If the goal is to create software that "just works" for everyone then the best way is to not depend on the user's environment. Obviously we still have to use git itself, but ideally this would be the only thing you run from outside node.

I don't know too much about the mac GUI issue and nvm that has been referenced here, but already in the code I can see that's only applicable to non-windows users. So if that is something that works well for those environments then no reason just not to have it be a different code path for them. But wherever it's possible do file system stuff within node - it's going to be a lot easier to support all environments that way rather than using bash command line utilities.

Well.. I didn't mean to just drop the mic after that post... was really just trying to be as comprehensive as possible about why it's so difficult to use shell scripts and be compatible with windows! :)

@typicode we have a pretty big investment in standardized commit hooks since we use git with large teams of varying abilities, and I'd be very happy to be contribute to the solution as long as it's agreeable. I'd definitely prefer to use something that's not officially deprecated and has broader community support. I can write the code to do this with node instead of shell scripts if you're OK with the architectural change.

Well.. I didn't mean to just drop the mic after that post...

No worries :) just wanted to take time to better understand this case. So thanks for the details.

Actually, even in CMD, shell scripts started with Git will work:

C:\Users\typicode\git-test>ls # will of course fail
# .git/hooks/pre-commit
# #!/bin/sh
# ls
C:\Users\typicode\git-test>git commit -am test # will correctly output ls

And so this works in IDE too, as Git will run hook scripts and they won't be run directly in CMD. I've tested it with Visual Studio Code which comes with Git built-in.

Also AFAICT from Windows related issues, hook scripts are always run. When they failed on Windows it was because of small differences like path that needed to be normalized.

I would suggest trying husky with some of your work configuration. It's easy to remove if it doesn't work for you or some of your team.

npm install husky # add --save-dev if you want to make it available to your team
npm remove husky # will remove hooks that husky installed

Existing hooks won't be touched.

mac GUI issue and nvm

This affects people that have installed Node using only nvm on OS X or Linux.

With nvm, PATH is only modified in the terminal, so when you start a GUI app it will get a different PATH and won't be able to find Node.

In this configuration, if hook scripts are written using Node it won't work. With a shell script it's easy to load nvm and node.

Also I think running a shell script is slightly faster than loading Node.

node instead of shell script

On OS X and Linux, I prefer to keep shell for the previous reason.

On Windows not against it and it may be a good idea, but I would like to have at least a failing scenario on this platform (install tool X, run command Y, ...) before creating a specific hook script.

Hope it clarifies things and that I didn't miss the point.

This is interesting. So it seems possible my central concern may be, er, "alternate facts" because what I didn't consider is that the scripts are always launched by git, rather than from a node process which will spawn a new default command processor via the OS. I might still argue that parsing package.json is trivial enough to do with node that it still is sensible, generally speaking, but if we're already in a bash script then maybe it's pointless.

I still have a bit of a nagging feeling but maybe it's not a big deal (at least not for us). There are certainly scenarios that could potentially be incompatible. For example, if you are using a git client other than Git for Windows, e.g. git package for msys2. But frankly this is edge-casey enough that it's probably not worth a major philosophy change to support.

I'll give husky a try in a few different configs to be sure I'm not overlooking anything else here. But assuming I can't blow it up at a fundamental level, if the open windows issue is simply a path parsing problem then consider my concerns allayed.

git package for msys2

If it can help, it seems it works too typicode/husky#70 but I've not tried it myself.

The scenario I can imagine is that you're running git in an environment where it can't find the shell. I don't know how git integrates with the shell when it invokes it on commits (but obviously it's not through windows -- or it wouldn't work anywhere), but I was able to make it fail when using msys2 with a cmd shell like this:

install MSYS2
install git: pacman -S git
launch a CMD shell
remove git for windows from your path (if it's also installed)

Commit hooks are ignored. Strangely it seems to work fine with TCC/LE? I don't really know why this would behave differently in TCC vs CMD

I am really not worried about this. I actually am almost that edge case... I use MSYS2 for bash commands on windows, and TCC/LE for my shell (which is not bash but CMD replacement). I do this because I like the MSYS2 package manager and the availability of all the tools that don't come with Git for Windows, and TCC/LE is far better than the git & msys2 bash shells for usability. But at the end of the day I have a hard time imagining someone being enough of a hacker that they want to use MSYS2, and using MSYS2 git, and using it on CMD instead of a shell replacement.

I am satisfied that the fundamental problem I feared (scripts not working because default windows command shell isn't bash) doesn't exist... and I suspect that anyone who was trying to work in the contrived scenario I created would have other problems anyway.

uglow commented

I've tried upgrading a ghook commit-msg hook to husky, and I'm finding that the commit message isn't passed to the Node script as it was when using ghooks.

This works using ghooks:

"config": {
    "commitizen": {
      "path": "node_modules/cz-customizable"
    },
    "cz-customizable": {
      "config": "config/release/commitMessageConfig.js"
    },
    "ghooks": {
      "commit-msg": "node ./node_modules/cz-customizable-ghooks/lib/index.js $2",
    }
  },

Note the $2 parameter which is the path to the file containing the commit message.

When using husky, no additional arguments seem to be being passed to the script, so it fails. So at the moment, husky is NOT a like-for-like replacement (or enhanced version) of ghooks.

CC @typicode.

hi @uglow,

You should be able to find additional arguments in GIT_PARAMS environment variable.

Hmm, just stumbled upon this news today. I have used husky in the past and went with ghooks because I felt it was better designed. The biggest flaw for me with husky is that it put the scripts inside of the scripts block. That makes it conflicts with how NPM automatically runs pre and post versions of that command as well. That being such an integral part of how husky works though, I doubt it can be fixed. I wouldn't mind taking over this project.

@gtramontina

@duclet I'd be more than happy to move this repo into an organization and add you as contributor. Let me know!

I imagine that @typicode may entertain the idea of allowing config in a similar way that ghooks had if it means there's more effort behind husky rather than split-effort between two tools. Has anyone asked?

@gtramontina, that would be great.

@kentcdodds, there are two open tickets relating to this matter that doesn't seem like it is going anywhere anytime soon.

I think there is room in the world for more than one project with similar goals. Competition is the catalyst of innovation right?

@duclet In addition to your design concerns, even if possible to do with the shell, I still think that it's just common sense to use Node to do file system stuff rather than bash commands. I'm glad you are keeping this alive. Officially canceling plans to migrate.

Hi,

Just replied here typicode/husky#99
feedback about usage and conflicts is welcome

I still have concerns but I did make a recommendation in that ticket which I can live with. We'll see how it goes but if not, I would still like to take over this project if possible. Thanks.

@duclet I waited 20 days for a husky maintainer to acknowledge my concerns and nada. I've decided to return to using ghooks library with justification: typicode/husky#133

@gtramontina Please offer to transfer ownership of this repo and the module. I really don't need a script called precommit/prepush to run my script called lint. Don't make me do stuff.

@duclet please lmk if you'd like an invite to the ghooks-org @gtramontina set up so we can revive this puppy.

Alright…

I've just moved ghooks to its own org ghooks-orgghooks was already taken – and invited those who expressed interest in keeping ghooks alive to be part of it. cc/ @jhabdas @duclet @ta2edchimp

I still have to figure out npm ownership transfer. Tips and hints are welcome! npm owner add <user> <pkg> does the trick, so I've added @jhabdas as owner for now.

Hope this helps the community! 🍻

(had this message sitting here when my battery died)

By the way, I got the logo from https://www.viget.com/articles/two-ways-to-share-git-hooks-with-your-team -- we should probably add an attribution somewhere (or come up with a new one – anyone with design skills? 😄)

@gtramontina It's not super usual for git projects to do this yet, but it might be fun to set up a donation request form to a bitcoin account and hope to score some coin for your efforts.