Repository navigation
Loosen packageManager field to support any package on npm #354
Description
Activity
Maybe, with a caveat. Corepack isn't intended to be a package manager. As a result, any tool it installs must not have any dependency.
We might lose the ability to catch typos since today those are caught with
Usage Error: Unsupported package manager specification.If we do this, I believe "generic" packages should be targeted with a dedicated syntax. Something like:
{ "packageManager": "pkg:cnpm@x.y.z" }Otherwise there'll be a problem with Yarn, which currently retrieves the package from one of two different sources depending on the version (even if we switched Yarn Modern to npm releases, it'd still come from two different packages; we don't want to publish modern releases on the
yarnpackage so as not to break any current user).This would also let us catch typos on the most popular options.
Maybe, with a caveat. Corepack isn't intended to be a package manager. As a result, any tool it installs must not have any dependency.
Oh thats good to know. Looks like bun has 0 deps but cnpm has 11. Definitely need to document that caveat if we add this behavior. I'm almost wondering if
packageManagershould accept a url to make it even more generic.Otherwise there'll be a problem with Yarn, which currently retrieves the package from one of two different sources depending on the version
My suggestion is to not change the behavior of Yarn/pnpm/npm as it is today. Only to open the door to other package managers. Basically, check
config.json, and fallback to fetching from the registry if there is no match.Maybe we could accept either a bare specifier – in which case Corepack checks the
config.jsonto download the right archive – or a URL. I think the URL should address the issue at hand (anyone can use their package manager, or even easily fork an existing package manager) without forcing them to store it on any specific repository. It also makes it clearer that dependencies won't be downloaded. Not sure how Corepack would know what name to use for the binary though 🤔Not sure how Corepack would know what name to use for the binary though
Since the url is going to point to a file download, how about using the
Content-Dispositionheader?For example,
buncould be:Content-Disposition: attachment; filename="bun"Would this work with caching? I guess the url should have the version number in it and corepack could cache by url string?
Since the
packageManagerfield is only read when a shim is called, how would Corepack know that a specific shim needs to be installed in the PATH in the first place? For instance, what would makebunglobally available so thatbun installwould read thepackageManagerfield and installbunfrom the url configured there?Reacted by StevenSince the
packageManagerfield is only read when a shim is called, how would Corepack know that a specific shim needs to be installed in the PATH in the first place? For instance, what would makebunglobally available so thatbun installwould read thepackageManagerfield and installbunfrom the url configured there?The way I imagine that would be that those folks would do
corepack enable bun, and that would create the jumper script. That doesn't seem to be very different from what we have now.Actually we could have both the "binary name" and the URL:
{ "packageManager": "aduh95-special-pm@http://example.com/archive.tgz#sha224.xxxxxxxxxxx" }If someone tries to run
corepack yarn install, Corepack would be able to throw an error, and if you runcorepack aduh95-special-pm install, it would "just work" – or if you have anaduh95-special-pmbinary in your path installed by Corepack.That got me thinking, should we support the following:
{ "packageManager": "pnpm@http://example.com/archive.tgz#sha224.xxxxxxxxxxx" }And I think by default Corepack should refuse to do so, so folks by default would run official binaries of package managers that are in
config.json, but we should have an env variable to allow to use unofficial ones.I like this idea. We could do something like this:
$ pkgmgr Command not found: pkgmgr $ corepack enable pkgmgr $ pkgmgr Usage Error: This command can only be used within a project configured to use pkgmgr; check https://... for more details. $ corepack use pkgmgr We're going to create a local project using the following package manager: Name: pkgmgr Version: 3.0.0 Website url: https://pkgmgr.com Source url: https://registry.npmjs.com/pkgmgr/-/pkgmgr-3.0.0.tgz Is this what you intend? [Y/n] $ pkgmgr Project installedWorth noting that, at that time, none of the Corepack commands are "interactive", meaning you type the command, Corepack will execute it without requiring any additional step from the user. The suggested workflow breaks this, which may or may not be worth it.
We might find the following to be more fitted:$ corepack use pkgmgr Usage Error: Invalid package manager specification in CLI arguments. Consider adding the `--from-npm` flag if you meant to use the npm package `pkgmgr` as your package manager $ corepack use pkgmgr --from-npm $ cat package.json { "packageManager": "pkgmgr@https://registry.npmjs.com/pkgmgr/-/pkgmgr-3.0.0.tgz#sha1.xxxxxxxx" } $ pkgmgr Project installed
Reacted by Maël Nison and StevenI liked the what @arcanis had in #354 (comment) because it makes it clear what is going to be installed, where from, and the user needs to confirm that they want it installed.
Could we consider changing the behavior of Corepack to loosen the definition of the
packageManagerfield?That way you could define any npm package name in the
packageManagerfield and Corepack would fetch from the npm registry if its not found in the hardcoded known package manager list.Examples
Pros
packageManagerfield feels a lot more likedependenciesCons
Usage Error: Unsupported package manager specification.Usage Error: This project is configured to useI think number 1 is okay but number 2 sounds problematic. Perhaps number 2 still requires a PR to Corepack.
Related