Skip to content

feat: implement support for --cwd flag#32

Open
paul-soporan wants to merge 7 commits intomainfrom
paul/feat/--cwd
Open

feat: implement support for --cwd flag#32
paul-soporan wants to merge 7 commits intomainfrom
paul/feat/--cwd

Conversation

@paul-soporan
Copy link
Member

This PR implements support for Yarn's --cwd flag as the first argument, both as --cwd path and --cwd=path.

The flag is not allowed in any other position for reasons discussed back in the berry repo: yarnpkg/berry#5600 (comment).

I did not implement the fallback for create-react-app since it had a TODO: remove it and we can always add it back if people start complaining.

I also added a TODO for erroring when --cwd is specified in other positions, which requires clipanion to implement some kind of option inheritance for commands (maybe something like an inherit_options(BaseCommand) macro?)).

Reference: https://github.com/yarnpkg/berry/blob/8598d0735904b8e0dee1ead301eb8524e106ab24/packages/yarnpkg-cli/sources/lib.ts#L92-L115

cwd = Some(raw_path.path);
args.remove(0);
}

Copy link

Choose a reason for hiding this comment

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

Bug: Implicit Path Overrides Explicit --cwd

The implicit path detection logic runs after explicit --cwd flag parsing, allowing a positional path argument to override an explicitly provided --cwd value. For example, yarn --cwd /path1 /path2 command would incorrectly use /path2 instead of /path1. Explicit flags should take precedence over implicit arguments.

Locations (1)

Fix in CursorFix in Web

Copy link
Member Author

@paul-soporan paul-soporan Jul 15, 2025

Choose a reason for hiding this comment

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

It is actually correct (at least according to Yarn's behavior) that yarn --cwd /path1 /path2 command executes the command in /path2.

What does not currently work correctly is yarn --cwd ./a ./b which should execute in ./a/b.

Yarn gets that right because implicit path arguments are simply handled by clipanion, which also enables things like yarn workspace foo ./subfolder exec pwd to work.

I don't think I'll touch this until we look into making the implicit path argument handler a regular clipanion command instead (at least in some cases so that zpm-switch still retains the correct behavior).

Copy link
Member

Choose a reason for hiding this comment

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

Could we define the --cwd path as a command similar to this?

#[cli::command(proxy)]
struct MyCommand {
  #[cli::option("--cwd")]
  cwd: String,

  rest: Vec<String>,
}

Copy link
Member Author

@paul-soporan paul-soporan Jul 16, 2025

Choose a reason for hiding this comment

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

I don't think so - proxies on commands without any path segments or required positional arguments consume all arguments provided, including all options.

i.e. rest will also contain --cwd while cwd will be None.

Oh wait, I misread your comment. So you mean having a special command with a required --cwd option? That might work 🤔

Copy link
Member Author

@paul-soporan paul-soporan Jul 16, 2025

Choose a reason for hiding this comment

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

Made both --cwd and implicit cwd (yarn ./path ...) go through clipanion in the case of the zpm binary.

Edit: As a result, both are now supported in forwarded commands (e.g. yarn workspace foo ./subpath exec pwd).

However, for zpm-switch, I'm not sure the complexity is worth it.
Since we need to support both zpm-switch --cwd foo ... / zpm-switch ./foo ... and zpm-switch switch <selector> --cwd foo ... / zpm-switch switch ./foo ..., we'd need to have 4 different clipanion entries for this. 🤔

What do you think?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants