Honor the --cwd option - #154
Conversation
|
👋 @marcospassos
☝️ Lastly, the title for the commit will come from the pull request title. So please provide a descriptive title that summarizes the changes in 50 characters or less using the imperative mood. |
commit: |
There was a problem hiding this comment.
🟡 Changes recommended
The new --cwd validation can still surface misleading messages or raw filesystem exceptions for permission/IO errors, which should be handled consistently via InvalidOptionArgumentError.
Get a fresh assessment by requesting another Copilot review.
Pull request overview
This PR wires the global --cwd option into the CLI runtime by passing it through to Cli.fromDefaults() as directories.current, so commands run relative to the intended working directory instead of the launch directory.
Changes:
- Validates
--cwdresolves to an existing directory (rejects non-existent paths and non-directory paths). - Passes
--cwdinto the CLI configuration (directories.current) so project detection and filesystem operations honor it.
File summaries
| File | Description |
|---|---|
| src/infrastructure/application/cli/program.ts | Validates --cwd and forwards it into Cli.fromDefaults() via directories.current. |
Review details
- Files reviewed: 1/1 changed files
- Comments generated: 1
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| try { | ||
| return realpathSync(path); | ||
| directory = realpathSync(path); | ||
| } catch { | ||
| throw new InvalidOptionArgumentError('The path does not exist.'); | ||
| } |
--cwdwas declared and validated but never passed to the CLI, so every command still ran against the directory it was launched from.croct --cwd app init, for example, configured the launch directory instead ofapp: it wrotecroct.jsonthere, rannpm installthere, and edited that directory'spackage.json.run()now passes the option asdirectories.current, the starting directoryClialready supports. Without--cwdit still falls back to the process directory, so invocations without the flag behave as before.The option also rejects a path that exists but isn't a directory. That used to be harmless because the value was ignored; now it would fail later with a confusing file-system error. Resolution errors are reported by cause, so a path that isn't accessible or can't be resolved (a symlink loop, for example) no longer reads as missing.
Consequences
The value seeds the CLI's single working directory, so everything that already resolves against it now follows
--cwd, as if the CLI had been started there:croct.json, the package manager, the SDKs, the formatters, the import resolver and the local server.npm installandnuxi prepare, which take their working directory from the same object.--config, local templates (croct use ./template.json5) and every file-system operation resolve against--cwdrather than the launch directory.change-directorycan't leave--cwd, which becomes the root they're confined to.--cwdproject. A global install is unaffected.Unchanged:
croct open(deep links) still uses the real process directory, and the command it runs doesn't inherit--cwd. Nested runs have never forwarded global options.croct --cwd app init), because the program uses positional options.--cwdresolves against the launch directory, with symlinks resolved.Validation
Built the CLI and ran it against fresh copies of a Nuxt 4 app:
croct --cwd app init …, launched from the parent directorycroct.json,@croct/plug-nuxt, the module and the Storyblok plugin all landed inapp, and nothing was written to the launch directorycroct init …, launched inside a second copycroct --cwd /nonexistent/dir …The path does not exist.croct --cwd app/package.json …The path is not a directory.croct --cwd <directory without permission> …The path is not accessible.croct --cwd <symlink loop> …The path cannot be resolved.tsc, lint and the test suite pass.