-
Notifications
You must be signed in to change notification settings - Fork 221
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Download binary on npm postinstall hook #43
Download binary on npm postinstall hook #43
Conversation
/cc @HellSquirrel |
Thanks! I will test it in a few days |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@fleischie
I tested this solution and found some problems. See comments below
.npm/postinstall.js
Outdated
|
||
function downloadBinary(os, callback) { | ||
// construct single binary file path | ||
const binaryPath = join(process.cwd(), 'lefthook'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
process.cwd()
is our current working directory. Consider some examples
npm i @arkweid/lefhook
-- it will upload the binary to the project root
cd src && npm i @arkweid/lefhook
-- it will upload the binary to 'src'
We want the binary to be uploaded to ./node_modules/@arkweid/lefhook/...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, whoops. I guess that was just the leftover binaryPath
from my local tests. Will update immediately.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
process.cwd()
should also give us the base path of the project, as the main function calls process.chdir(process.env.INIT_CWD)
.
But if you want I can rewrite this, so that both the downloadBinary
function takes process.env.INIT_CWD
into consideration for the path, as well as call process.chdir(process.env.INIT_CWD)
inside installGitHooks
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have two problems:
process.env.INIT_CWD
refers to the current folder. (It could be a subfolder of the root folder.) So we need to look fornode_modules
recursively- Some older versions of
yarn
don't set this variable at all
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, you shouldn't search the folder node_modules
at all (e.g., name of "node_modules" folder can be changed). There is simple and steady solution: https://github.com/levenkov/lefthook/pull/1/files#diff-5fe0be6c71fdcee66beee780a898073fR167
- Download it in preinstall hook.
- preinstall hook executed in the package directory.
- It's always true, that if you placed downloaded binary in
./bin
in the preinstall hook, this binary after install stage will be in the right place (usually here:<project dir>/node_modules/@arkweid/lefthook/bin/...
).
I almost done the work, but was overwhelmed by the deadline :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was under the impression that the INIT_CWD
is set to the base path of the newly installed package (see https://github.com/yarnpkg/yarn/blob/cfb560e1b2e37ed5cfe5d2374a806ac3ae512c11/src/util/execute-lifecycle-script.js#L40 similar for npm
), hence INIT_CWD
for lefthook
would always be <project-dir>/node_modules/@Arkweid/lefthook
.
(Also the change was (according to GitHub) over a year ago, so I would assume most users have a current enough yarn
/npm
installation)
So tl;dr: As long as we don't process.chdir
or cd <somewhere> && ...
in the postinstall script, we should be able to assume we are in <project-dir>/node_modules/@Arkweid/lefthook
, no?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(Also the change was (according to GitHub) over a year ago, so I would assume most users have a current enough yarn/npm installation)
It's better to support as earlier as you can version of node. It's common place to support >=6.0.
INIT_CWD is working after 8.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I honestly don't know how to fix this INIT_CWD
issue. I tried to use the ./dir
approach (i.e. const path = process.env.INIT_CWD || path.resolve(".");
), but in my locally installation tests, this always resolved to the path the script resides in (i.e. <path>/lefthook/.npm
, instead of <path>/tmp
where I called npm install ../lefthook/.npm
from).
Maybe you can review the latest PR version and give me some pointers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@fleischie I'll see that in 1-2 days. Maybe I'll try to change the approach in your code to mine and suggest small patch. I don't claim to replace all your work, just this problem.
Here how you can load unzip and execute lefthook binary on mac
|
For Windows we should change the |
(I will have time (maybe today but definitely) on thursday to continue working on this PR. Sorry for the inconvenience. 🙇 ) |
Is it ready? |
I finished with the PR for now (as in "I tried to implement the feature while considering all raised concerns"). I think someone should (or maybe also wanted to) test the current state, as I do not know how to test the postinstallation hook from an actual |
I'm still going to test it :) I can get here in a week or two |
There is a simple way to test
|
Still there? :) |
Oh hey, yes. I actually overlooked the last message from Andrey, so I will check today/tomorrow on some systems whether it works ok, and then report back. ✌️ |
I did now test my PR on mac and Windows 7 VM: It does for mac (if I change the Edit: I will hence update the PR, and need to test on my Windows machine at home (if I find the time that is). |
I also rebased the PR on the latest
|
I'm not sure, but is it possible to point package.json's UPD: actually, that is what actually mentioned in #16 as second point |
Try to fetch the binary files on postinstall for each supoorted OS and if not CI. This should reduce the npm package size (as you only ever download one binary for your host system).
- Add function to dynamically return path of `lefthook` binary depending on `os`, package `version`, and architecture, - add extra redirection-download step for GitHub releases (as they are served from AWS, which is dynamically redirected on request), and - add more event-based file-handling (e.g. unlinking in 'close'-handler, calling the callback on 'end'-event, etc.).
If `process.env.INIT_CWD` is not set fall back to `resolve(".")` to try to emulate the behavior.
Exit early and notify user of issue, because currently there is only a windows 64bit version of lefthook.
- Remove pre-build binaries in `bin/` folder, - rename downloaded executable to `lefthook` (or `lefthook.exe` on windows), and - call the appropriate executable by name (and platform) in `index.js`.
Updated the PR again to fit snugly on the latest master. @yumauri I am uncertain whether |
Amendum: This PR works on the assumption, that binaries are always available for the most recent version as a gzipped package. That's why there is a commit aborting on 32bit Windows. I understand that this is an added burden on the maintainer, as there are more and more diverse packages to be produced. The other solution would be to handle the zips as well, but require an additional (potentially heavy) node zip-library, which I tried to avoid until now. Let me know what you think. |
Github actions are publicly available ;) Theoretically it is possible to make an action to build and upload binaries somewhere on every push |
You can test npm features by installing npm package from local file
Yeap, |
Please, please, please do NOT merge this. Not everybody is working in an environment where all machines have direct internet connectivity! I have customers in highly regulated environments where their working machines are isolated from the internet. Development is done with an internal package repository, acting as a proxy for upstream repositories. All package downloads come from this proxy. The current situation, with the binaries included in the lefthook package, allow these customers to work with lefthook correctly. If you change it to downloading during the postinstall, their setups will break and they have no way to work around it as you hardcode the download URL. Making the URL configurable also pushes a lot of chore onto the users as they have to copy the binaries, put them on an internal site and communicate the link. Quite error prone and not usage friendly. To wrap up: can you please leave it as it is? |
Yeap, I changed my mind. Let's close it. |
Well, not everyone has high-speed internet to download all the binaries at once! Your workflow seems specialized enough (running npm locally) that you need to manage the post-install issue yourself instead of preventing people from benefiting from this improvement. You can simply fork this package and create one package that has all the binaries included. Because of the huge size of the package, I will not use lefthook in any of my public repositories that rely on the open-source contribution of people from around the world that have different connection speeds. Looking at the number of dependants of lefthook and comparing it with Husky, shows the same thing. Only 2 packages depend on lefthook while 2000 depend on husky! https://www.npmjs.com/package/@arkweid/lefthook |
Seems @ringods's concern was neglected in #188:
I think this issue is more relevant than it appears. Many environments use a npm proxy in case npm goes down or becomes inaccessible (eg. CI deploys, China, etc). In the case where GitHub becomes unavailable, (which happens more than it should...), this will break npm install. If the npm registry is proxied, I think this can be easily addressed by publishing the binaries to npm instead of using hosting them via GitHub release. For example, playwright does this with their browser flavors (eg. playwright-chromium). |
As was discussed in issue #16 the
lefthook
npm package contains all the binaries, this postinstall hook downloads only the appropriate binary for the host OS (or in case of CI: none).Note: I submit my PR in accordance to #16 (comment).
Note 2: I did not run any go/ruby command as this PR mainly changes the postinstall script in the
.npm
directory. If this is still necessary I will update my PR, just let me know what is missing. ✌️