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

[rush] Fix rush pnpm patch commit #3791

Open
wants to merge 6 commits into
base: main
Choose a base branch
from

Conversation

chengcyber
Copy link
Contributor

@chengcyber chengcyber commented Nov 29, 2022

Summary

As @elliot-nelson pointed out at #3554 (comment), rush-pnpm patch-commit fails when running it from the root of monorepo, this PR makes rush-pnpm patch-commit works from the repo root folder.

Details

The reason rush-pnpm patch-commit fails is because pnpm patch-commit internally calls a logic which tries to read package.json file under procss.cwd(). While the actual top-level package.json in Rush.js monorepo is common/temp/package.json. So when ${cwd}/package.json doesn't exists and -C or --dir CLI parameter is not specified, Rush internally specifies --dir common/temp parameter for rush-pnpm patch-commit

How it was tested

Tested it with this repo: https://github.com/chengcyber/rush-pnpm-patch-demo

// patch-commit internally calls installation under cwd instead of the common/temp folder
// It throws missing package.json error, so in this case, we need to set the dir to the common/temp folder here
if (pnpmArgs.indexOf('--dir') < 0 && pnpmArgs.indexOf('-C') < 0) {
if (!FileSystem.exists(`${process.cwd()}/package.json`)) {
Copy link
Member

Choose a reason for hiding this comment

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

Unsure if this check is necessary. There are many Rush projects that have a package.json file at the root of the repo, generally to provide npm scripts at the root level. Additionally, Rush always uses the common/temp folder for the install directory for PNPM

Copy link
Member

Choose a reason for hiding this comment

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

Probably the most expected behavior would be to always pass this when we're doing an operation that expects to be run in the simulated workspace root.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The tricky part is the the installation just expects a "package.json" file under the working directory. After that, the lockfile directory are used to correctly install deps for all packages... where lockfile directory is set to "common/temp" before.

Copy link
Member

Choose a reason for hiding this comment

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

If there is a package.json at the repo root, how does pnpm find the common/temp lockfile without the --dir/-C parameter?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

In pnpm, there are two "dir" settings, 1. dir 2. lockfileDir. lockfileDir are used to specify where is the pnpm-lock.yaml, which is common/temp/pnpm-lock.yaml.

Related code:

    const workspaceFolder: string = rushConfiguration.commonTempFolder;
    const pnpmEnvironmentMap: EnvironmentMap = new EnvironmentMap(process.env);
    pnpmEnvironmentMap.set('NPM_CONFIG_WORKSPACE_DIR', workspaceFolder);

@@ -281,6 +281,14 @@ export class RushPnpmCommandLineParser {
);
throw new AlreadyReportedError();
}
// patch-commit internally calls installation under cwd instead of the common/temp folder
// It throws missing package.json error, so in this case, we need to set the dir to the common/temp folder here
if (pnpmArgs.indexOf('--dir') < 0 && pnpmArgs.indexOf('-C') < 0) {
Copy link
Member

Choose a reason for hiding this comment

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

Is -C just the short form for --dir?

Copy link
Member

Choose a reason for hiding this comment

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

Seems like we should error in this case and tell people not to pass --dir or -C if they're running patch-commit.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I suppose it doesn't harm people to pass -C if they want to do something very specific, but if it doesn't exist, we should add the flag to point at our temp folder.

The same logic applies to commands like "rush-pnpm why", which doesn't work right unless in temp folder.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Is -C just the short form for --dir?

Yes.

I suppose it doesn't harm people to pass -C if they want to do something very specific, but if it doesn't exist, we should add the flag to point at our temp folder.

Yes. The user story would be

  1. Run rush-pnpm patch-commit <path> under the repo root works ✅
  2. Run rush-pnpm patch-commit <path> under a project folder works ✅
  3. Run rush-pnpm patch-commit <path> --dir <specified_dir> works ✅

@iclanton iclanton added this to In Progress in Bug Triage Nov 30, 2022
@chengcyber
Copy link
Contributor Author

Updates: Feedback at #3554 (comment), when re-running rush-pnpm patch-commit <path> for the same dependency, the patches folder are not synced to "common/pnpm-patches" folder. I updated the code to handle this case as well in this PR.

libraries/rush-lib/src/cli/RushPnpmCommandLineParser.ts Outdated Show resolved Hide resolved
// patch-commit internally calls installation under cwd instead of the common/temp folder
// It throws missing package.json error, so in this case, we need to set the dir to the common/temp folder here
if (pnpmArgs.indexOf('--dir') < 0 && pnpmArgs.indexOf('-C') < 0) {
if (!FileSystem.exists(`${process.cwd()}/package.json`)) {
Copy link
Member

Choose a reason for hiding this comment

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

If there is a package.json at the repo root, how does pnpm find the common/temp lockfile without the --dir/-C parameter?

chengcyber and others added 2 commits December 5, 2022 08:27
Co-authored-by: Ian Clanton-Thuon <iclanton@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: In Progress
Bug Triage
  
In Progress
Development

Successfully merging this pull request may close these issues.

None yet

4 participants