Patching global Node tools

How to monkey patch a broken global Node package, if you have to.

I really enjoy publishing my Node packages through semantic-release service. Now I don't have to update the package version, rebuild, tag, run npm publish, etc. Most importantly, I don't have to think anymore what kind of change it is: breaking (major number increment), new API feature (minor number increment) or a bug fix (patch increment). The semantic-release inspects the commit messages to figure out if a new version needs to be published. A commit message validator like commitizen or pre-git will do the trick.

To start the process, install the CLI tool and go

npm install --global semantic-release-cli

Then inside any package folder run the setup

semantic-release-cli setup

Most of the times, the tool will start by asking you if the repo is private or public

$ semantic-release-cli setup
git url https:[email protected]:bahmutov/lazy-ass.git
? Is the GitHub repository private? (y/N)

But for some of my public repos hosted on GitHub the question was different

Are you using GitHub Enterprise? (Y/n)

The semantic release setup then failed. Finally, I found where in the version 1.3.2 the problem happened.

dist/lib/repository.js
1
var parsedUrl = parseGhUrl(rurl);

For some reason a valid repository url from my package.json was converted incorrectly

1
2
3
4
5
6
{
"repository": {
"type": "git",
"url": "[email protected]:bahmutov/lazy-ass.git"
}
}

The rurl variable had value https:[email protected]:bahmutov/lazy-ass.git and the parser returned an undefined value. The parser is a 3rd party module parse-github-repo-url

1
var parseGhUrl = require('parse-github-repo-url');

The module is tiny - single function parsing GitHub urls (including tar links). The project is clean, with good unit tests covering different edge cases. But the code and unit tests did not handle urls like `[email protected]:...`

NPM and GitHub have made fixing problems like these very quick. I forked the repo and patched the functionality. The pull request is still hanging there.

Work around

With the little utility module broken, what is my alternative at the moment? I want to get `[email protected]` to work - I just need to run it once per repository. Can I use my own patched parsing repo instead of the broken one?

Turns out it is very simple to do. Here is how to patch the CLI tool installed as a global module by NPM

jump into the global module using npm explore -g command

1
2
3
4
$ npm explore -g semantic-release-cli

Exploring /Users/kensho/.nvm/versions/node/v0.12.7/lib/node_modules/semantic-release-cli
Type 'exit' or ^D when finished

The dependency parse-github-repo-url is there inside the node_modules

install my patched module right from GitHub

1
$ npm install https://github.com/bahmutov/parse-github-repo-url.git

finish by going back from the CLI folder using exit command

Now I can use the setup command and everything is parsed correctly. Except, now it was the semantic release code that started failing because it does not know how to parse [email protected] urls :)

Error: Invalid URI "https:[email protected]:bahmutov/lazy-ass.git"

As a solution I went back and removed using url from the package.json, instead using the one from the .git/config - it seems to work reliably.