Skip to content
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

javascript: Manage npm version with corepack #18748

Merged
merged 4 commits into from
Apr 18, 2023

Conversation

tobni
Copy link
Contributor

@tobni tobni commented Apr 15, 2023

Enables users to configure a wanted version of a package manager blessed by Corepack, either by:

  1. Setting a package manager version in the nodejs subsystem; or
  2. Placing a packageManager entry in their package.json, the feature of Corepack.

This is a prerequisite for pnpm and yarn support.

Fixes #18525.

Requires explicit setting of 8.5.5 to be backwards compatible
@@ -120,6 +120,22 @@ async def download_known_version(
download_file = DownloadFile(url, FileDigest(known_version.sha256, known_version.filesize))
return await Get(DownloadedExternalTool, ExternalToolRequest(download_file, exe))

package_managers = DictOption[str](
default={"npm": "8.5.5"},
Copy link
Contributor Author

@tobni tobni Apr 15, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would have preferred to set this to the empty dictionary, and let Corepacks own "knownGoodReleases.json" be in effect for npm by default.

Unfortunately that version (7.20.0) is not the same as the one that has been in use by pants so far (8.5.5), and downgrading a major version as a default might break stuff.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we can drop this default once corepack updates their default to 8.5.5 or later.

Comment on lines +314 to +316
directory_digest = await Get(Digest, CreateDigest([Directory("._corepack")]))
binary_digest = binaries.digest if binaries.digest else EMPTY_DIGEST
input_digest = await Get(Digest, MergeDigests((directory_digest, binary_digest)))
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is an (unlikely) situation here that could break things. If a user uses a bootstrapped nodejs that doesnt ship with corepack (no LTS versions of this dist exists https://nodejs.dev/en/about/releases/, corepack is part of v14 dist), the "corepack enable" invocation on line 324 will surely not behave nicely.

I'm reluctant to implement support for versions <14 as that is past maintenance, but maybe better error messaging is warranted than a filenotfound error from the engine?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea, that seems reasonable.

Comment on lines +357 to +359
binary_digest_with_shims = await add_corepack_shims_to_digest(
binaries, binary_shims, corepack_env_vars
)
Copy link
Contributor Author

@tobni tobni Apr 15, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Corepack shims has to be part of the same digest as the downloaded node binaries, otherwise the symlinks are incredibly incorrect when passed as separate immutable digests.

Comment on lines 552 to 554
pkg_manager_env = {
"__PACKAGE_MANAGER_VERSIONS": ",".join(versions)
} # Invalidates cached process in event of update
Copy link
Contributor Author

@tobni tobni Apr 15, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this abuse of append_only_caches? I noticed processes were not re-run after I changed the npm version (which triggers a rerun of prepare_default_package_managers). It is kinda bad if a user is attempting an upgrade and tests/builds still pass.

Copy link
Contributor Author

@tobni tobni Apr 16, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I've convinced myself that yes, this is very bad (and I think its the reason CI is failing). Because corepack mutates a goodKnownReleases.json file in this cache, the choice of version becomes "erratic". It doesnt matter if the consuming process is force to re-read, this is still (seemingly) racy.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tobni tobni force-pushed the add/manage-npm-version-with-corepack branch from d8065d6 to 866248f Compare April 15, 2023 19:10
tobni added 2 commits April 15, 2023 22:08
Corepack turned out to be stateful w.r.t version tracking
@cognifloyd cognifloyd added category:new feature backend: JavaScript JavaScript backend-related issues labels Apr 17, 2023
Copy link
Member

@stuhood stuhood left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! Thanks a lot.

Will merge later today.

@stuhood stuhood merged commit 7522356 into pantsbuild:main Apr 18, 2023
@tobni tobni deleted the add/manage-npm-version-with-corepack branch May 16, 2023 20:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend: JavaScript JavaScript backend-related issues category:new feature
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add support for corepack the node package manager manager
3 participants