Skip to content

Honor the --cwd option - #154

Merged
marcospassos merged 2 commits into
masterfrom
fix/cwd-option
Sep 11, 2026
Merged

marcospassos merged 2 commits into
masterfrom
fix/cwd-option

Conversation

@marcospassos

@marcospassos marcospassos commented Sep 11, 2026

Copy link
Copy Markdown
Member

--cwd was 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 of app: it wrote croct.json there, ran npm install there, and edited that directory's package.json.

run() now passes the option as directories.current, the starting directory Cli already supports. Without --cwd it 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:

  • Project detection, croct.json, the package manager, the SDKs, the formatters, the import resolver and the local server.
  • Spawned commands such as npm install and nuxi prepare, which take their working directory from the same object.
  • Relative paths: --config, local templates (croct use ./template.json5) and every file-system operation resolve against --cwd rather than the launch directory.
  • Templates: change-directory can't leave --cwd, which becomes the root they're confined to.
  • The auto-updater: a CLI installed locally is updated in the --cwd project. 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.
  • The option must still come before the command (croct --cwd app init), because the program uses positional options.
  • A relative --cwd resolves against the launch directory, with symlinks resolved.

Validation

Built the CLI and ran it against fresh copies of a Nuxt 4 app:

Invocation Result
croct --cwd app init …, launched from the parent directory Nuxt detected; croct.json, @croct/plug-nuxt, the module and the Storyblok plugin all landed in app, and nothing was written to the launch directory
croct init …, launched inside a second copy Identical result
croct --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.

@marcospassos marcospassos added the bug Something isn't working label Sep 11, 2026
@github-actions

Copy link
Copy Markdown

👋 @marcospassos
Thanks for your contribution!
The approval and merge process is almost fully automated 🧙
Here's how it works:

  1. You open a new pull request
  2. Automated tests check the code
  3. Maintainers review the code
  4. Once approved, the PR is ready to merge.

👉 Omit the extended description
Please remove the commit body before merging the pull request.
Instead, include the pull request number in the title to provide the full context
about the change.

☝️ 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.
Happy coding! 🎉

@pkg-pr-new

pkg-pr-new Bot commented Sep 11, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/croct@154

commit: 4bdc360

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 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 --cwd resolves to an existing directory (rejects non-existent paths and non-directory paths).
  • Passes --cwd into 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.

Comment on lines 26 to 30
try {
return realpathSync(path);
directory = realpathSync(path);
} catch {
throw new InvalidOptionArgumentError('The path does not exist.');
}
@marcospassos
marcospassos merged commit fbb016c into master Sep 11, 2026
7 checks passed
@marcospassos
marcospassos deleted the fix/cwd-option branch September 11, 2026 21:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants