From 0ce97e5fe990fee90c25bb1c450e13c59fcff3d7 Mon Sep 17 00:00:00 2001 From: Jonah Snider Date: Sun, 3 Oct 2021 22:11:45 -0700 Subject: [PATCH 1/4] docs: rename pmm -> Corepack --- DESIGN.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/DESIGN.md b/DESIGN.md index 2e5f65d8a..2cab3bb25 100644 --- a/DESIGN.md +++ b/DESIGN.md @@ -16,29 +16,29 @@ Discussion thread: https://github.com/nodejs/node/issues/15244 2. Node would be distributed slightly differently: - - Pmm would be included by Node out of the box. + - Corepack would be included by Node out of the box. - - The full npm package wouldn't be included out of the box anymore (this might be an incremental move, with first a major version shipping pmm + npm, and the next one discarding npm). + - The full npm package wouldn't be included out of the box anymore (this might be an incremental move, with first a major version shipping Corepack + npm, and the next one discarding npm). - - **However**, the Node distribution would include jump binaries for all three main package managers (`yarn`, `npm`, and `pnpm`) that would simply delegate to `pmm `. Pmm would then handle the install logic by following the logic described in later sections. + - **However**, the Node distribution would include jump binaries for all three main package managers (`yarn`, `npm`, and `pnpm`) that would simply delegate to `corepack `. Corepack would then handle the install logic by following the logic described in later sections. - - Pmm could potentially be distributed as a Node subcommand rather than a standalone binary. In this case, commands in this document (such as `pmm install `) would be replaced by `node --pmm install ` (or any other variant). + - Corepack could potentially be distributed as a Node subcommand rather than a standalone binary. In this case, commands in this document (such as `corepack install `) would be replaced by `node --corepack install ` (or any other variant). 3. Regular users would keep using the `yarn` / `npm` / `pnpm` global binaries just like they are used to. The one difference is that the package manager implementations would be lazily downloaded, without having to be manually installed (because the global jumpers would be included in the Node distribution, cf previous point). - - Projects that don't list the `engines.pm` field would allow any package manager, and Pmm would install them based on predefined versions. Those versions will be frozen in time within Pmm itself to "known good values". For example, the default npm version could be 6.14.5, and the default Yarn one 1.22.4. Users that would want to upgrade to higher versions would just have to update the `engines.pm` field (cf next section). + - Projects that don't list the `engines.pm` field would allow any package manager, and Corepack would install them based on predefined versions. Those versions will be frozen in time within Corepack itself to "known good values". For example, the default npm version could be 6.14.5, and the default Yarn one 1.22.4. Users that would want to upgrade to higher versions would just have to update the `engines.pm` field (cf next section). 4. Project authors would most of the time only have to care about the binaries as well, but they would be able to upgrade package manager versions simply by changing the versions set in the `engines.pm` field. - - Pmm could reasonably provide some kind of basic CLI interface to select a version to upgrade to in a few keystrokes (similar to what `emsdk` does for the [emscripten toolchain](https://github.com/emscripten-core/emsdk#how-do-i-check-for-updates-to-the-emscripten-sdk), or what [nvm](https://github.com/nvm-sh/nvm) does for Node releases). + - Corepack could reasonably provide some kind of basic CLI interface to select a version to upgrade to in a few keystrokes (similar to what `emsdk` does for the [emscripten toolchain](https://github.com/emscripten-core/emsdk#how-do-i-check-for-updates-to-the-emscripten-sdk), or what [nvm](https://github.com/nvm-sh/nvm) does for Node releases). 5. Docker users would follow a similar workflow to other users; the default image would run network queries to install the right package manager for the project being installed. - - However, users with strong offline requirements would be able to run the `pmm install ` command when preparing their images. It would ensure that the requested package manager is made available for later use. + - However, users with strong offline requirements would be able to run the `corepack install ` command when preparing their images. It would ensure that the requested package manager is made available for later use. - - Network access could be disabled entirely by setting `PMM_ENABLE_NETWORK=0` in the environmen - Pmm would then only use the package managers that got installed by prior `pmm install` calls. + - Network access could be disabled entirely by setting `COREPACK_ENABLE_NETWORK=0` in the environmen - Corepack would then only use the package managers that got installed by prior `corepack install` calls. -6. Package manager maintainers would submit a PR to the Node repository each time they wish for a new version to be made available through Pmm (can be easily automated using a GitHub Action on each of our repositories). Merging the PR would instantly make the new version available to Node users (once they upgrade). +6. Package manager maintainers would submit a PR to the Node repository each time they wish for a new version to be made available through Corepack (can be easily automated using a GitHub Action on each of our repositories). Merging the PR would instantly make the new version available to Node users (once they upgrade). ## How does it work? @@ -70,8 +70,8 @@ Nothing would change in the context of this particular proposal. Npm would keep While npm is favored by the majority of the ecosystem, a significant portion decided to use different tools. Their use cases deserve to be heard rather than be discarded simply because a slightly higher percentage of users happens not to directly benefit from it. Additionally, keeping powers balanced is important - even more so given that npm is a corporate entity with little oversight. -From the npm perspective, a project such as Pmm would also have its benefits: projects regularly break when upgrading from one Node version to another because of npm being upgraded as well. By pinning the package manager version, they would ensure that their users only upgrade when they are ready to, decreasing accidental frustration. +From the npm perspective, a project such as Corepack would also have its benefits: projects regularly break when upgrading from one Node version to another because of npm being upgraded as well. By pinning the package manager version, they would ensure that their users only upgrade when they are ready to, decreasing accidental frustration. ## Known issues -- The `pnpx` and `npx` binaries can only be called from within pnpm and npm projects, respectively. This is because otherwise we cannot infer the package manager version from the local manifest, as it would list another package manager instead. Fixing that is possible if we include "global installs" features inside pmm (so that we would fallback to the global `npx` in those circumstances). It seemed out of scope for the initial prototype, but we certainly can discuss it in an issue. +- The `pnpx` and `npx` binaries can only be called from within pnpm and npm projects, respectively. This is because otherwise we cannot infer the package manager version from the local manifest, as it would list another package manager instead. Fixing that is possible if we include "global installs" features inside corepack (so that we would fallback to the global `npx` in those circumstances). It seemed out of scope for the initial prototype, but we certainly can discuss it in an issue. From a36d79cf5e0cde4d3e1b42fcdd56140242edb590 Mon Sep 17 00:00:00 2001 From: Jonah Snider Date: Sun, 3 Oct 2021 22:12:26 -0700 Subject: [PATCH 2/4] build: use nodejs/corepack repo instead of arcanis/pmm --- docker/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/Dockerfile b/docker/Dockerfile index 02f7ff27f..13872e7ed 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -11,6 +11,6 @@ RUN rm -rf /opt/node/lib /opt/node/bin/npm /opt/node/bin/npx ENV PATH="/opt/node/bin:$PATH" RUN which node && node --version -RUN wget https://github.com/arcanis/pmm/archive/master.tar.gz -O - | tar -xz --strip-components=1 -C /opt/corepack && cd /opt/corepack && node ./.yarn/releases/yarn-*.js build +RUN wget https://github.com/nodejs/corepack/archive/master.tar.gz -O - | tar -xz --strip-components=1 -C /opt/corepack && cd /opt/corepack && node ./.yarn/releases/yarn-*.js build ENV PATH="/opt/corepack/shims:$PATH" From 85955ea7cc3c035c688a884b0cc99d481ce263e4 Mon Sep 17 00:00:00 2001 From: Jonah Snider Date: Sun, 3 Oct 2021 22:15:05 -0700 Subject: [PATCH 3/4] refactor: rename TS source pmm -> Corepack --- sources/Engine.ts | 10 +++++----- sources/{pmmUtils.ts => corepackUtils.ts} | 0 sources/main.ts | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) rename sources/{pmmUtils.ts => corepackUtils.ts} (100%) diff --git a/sources/Engine.ts b/sources/Engine.ts index f1e5f4c54..83dd1e3f9 100644 --- a/sources/Engine.ts +++ b/sources/Engine.ts @@ -6,7 +6,7 @@ import semver from 'semver'; import defaultConfig from '../config.json'; import * as folderUtils from './folderUtils'; -import * as pmmUtils from './pmmUtils'; +import * as corepackUtils from './corepackUtils'; import * as semverUtils from './semverUtils'; import {SupportedPackageManagers, SupportedPackageManagerSet} from './types'; import {Config, Descriptor, Locator} from './types'; @@ -111,7 +111,7 @@ export class Engine { if (typeof range === `undefined`) throw new Error(`Assertion failed: Specified resolution (${locator.reference}) isn't supported by any of ${ranges.join(`, `)}`); - const installedLocation = await pmmUtils.installVersion(folderUtils.getInstallFolder(), locator, { + const installedLocation = await corepackUtils.installVersion(folderUtils.getInstallFolder(), locator, { spec: definition.ranges[range], }); @@ -135,7 +135,7 @@ export class Engine { const ranges = Object.keys(definition.ranges); const tagRange = ranges[ranges.length - 1]; - const tags = await pmmUtils.fetchAvailableTags(definition.ranges[tagRange].registry); + const tags = await corepackUtils.fetchAvailableTags(definition.ranges[tagRange].registry); if (!Object.prototype.hasOwnProperty.call(tags, descriptor.range)) throw new UsageError(`Tag not found (${descriptor.range})`); @@ -147,7 +147,7 @@ export class Engine { // If a compatible version is already installed, no need to query one // from the remote listings - const cachedVersion = await pmmUtils.findInstalledVersion(folderUtils.getInstallFolder(), finalDescriptor); + const cachedVersion = await corepackUtils.findInstalledVersion(folderUtils.getInstallFolder(), finalDescriptor); if (cachedVersion !== null && useCache) return {name: finalDescriptor.name, reference: cachedVersion}; @@ -156,7 +156,7 @@ export class Engine { }); const tagResolutions = await Promise.all(candidateRangeDefinitions.map(async range => { - return [range, await pmmUtils.fetchAvailableVersions(definition.ranges[range].registry)] as const; + return [range, await corepackUtils.fetchAvailableVersions(definition.ranges[range].registry)] as const; })); // If a version is available under multiple strategies (for example if diff --git a/sources/pmmUtils.ts b/sources/corepackUtils.ts similarity index 100% rename from sources/pmmUtils.ts rename to sources/corepackUtils.ts diff --git a/sources/main.ts b/sources/main.ts index ed32c8c5a..655c21669 100644 --- a/sources/main.ts +++ b/sources/main.ts @@ -6,7 +6,7 @@ import {EnableCommand} from './command import {HydrateCommand} from './commands/Hydrate'; import {PrepareCommand} from './commands/Prepare'; import * as miscUtils from './miscUtils'; -import * as pmmUtils from './pmmUtils'; +import * as corepackUtils from './corepackUtils'; import * as specUtils from './specUtils'; import {Locator, SupportedPackageManagers, Descriptor} from './types'; @@ -82,7 +82,7 @@ async function executePackageManagerRequest({packageManager, binaryName, binaryV throw new UsageError(`Failed to successfully resolve '${descriptor.range}' to a valid ${descriptor.name} release`); const installSpec = await context.engine.ensurePackageManager(resolved); - const exitCode = await pmmUtils.runVersion(installSpec, resolved, binaryName, args, context); + const exitCode = await corepackUtils.runVersion(installSpec, resolved, binaryName, args, context); return exitCode; } From 02ecc721551faeee3715218cfe934b4f79a52caf Mon Sep 17 00:00:00 2001 From: Jonah Snider Date: Sun, 3 Oct 2021 22:23:40 -0700 Subject: [PATCH 4/4] docs: fix spelling error --- DESIGN.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DESIGN.md b/DESIGN.md index 2cab3bb25..813397038 100644 --- a/DESIGN.md +++ b/DESIGN.md @@ -36,7 +36,7 @@ Discussion thread: https://github.com/nodejs/node/issues/15244 - However, users with strong offline requirements would be able to run the `corepack install ` command when preparing their images. It would ensure that the requested package manager is made available for later use. - - Network access could be disabled entirely by setting `COREPACK_ENABLE_NETWORK=0` in the environmen - Corepack would then only use the package managers that got installed by prior `corepack install` calls. + - Network access could be disabled entirely by setting `COREPACK_ENABLE_NETWORK=0` in the environment - Corepack would then only use the package managers that got installed by prior `corepack install` calls. 6. Package manager maintainers would submit a PR to the Node repository each time they wish for a new version to be made available through Corepack (can be easily automated using a GitHub Action on each of our repositories). Merging the PR would instantly make the new version available to Node users (once they upgrade).