Skip to content

Use detect-monorepo for workspace root and rush detection#175

Merged
0x80 merged 5 commits intomainfrom
thijs/0419-use-detect-monorepo
Apr 10, 2026
Merged

Use detect-monorepo for workspace root and rush detection#175
0x80 merged 5 commits intomainfrom
thijs/0419-use-detect-monorepo

Conversation

@0x80
Copy link
Copy Markdown
Owner

@0x80 0x80 commented Apr 10, 2026

Use detect-monorepo to auto-detect the workspace root, replacing the hardcoded workspaceRoot: "../.." default.

When workspaceRoot is not set explicitly (and targetPackagePath is not used), resolveWorkspacePaths now walks upward from the target package directory looking for pnpm-workspace.yaml, a package.json with a workspaces field, or rush.json. If detection fails and no workspaceRoot is configured, a clear error asks the user to set it explicitly.

The workspaceRoot config option remains supported as an override for cases where auto-detection fails (e.g. unusually deep nesting).

The existing isRushWorkspace helper is kept as a strict rush.json check at the passed-in directory. It is intentionally not replaced with detectMonorepo, because detectMonorepo walks upward and its rootDir can diverge from workspaceRootDir, which would break callers that compute lockfile importer ids or other paths relative to the same directory.

Docs and CLI help text updated to reflect the new auto-detect behavior.

Scope: packages (isolate-package)
Visibility: user-facing

0x80 added 2 commits April 10, 2026 17:16
Replace the manual is-rush-workspace helper and the hardcoded
"../.." workspaceRoot default with detect-monorepo. When
workspaceRoot is not set, the monorepo root is now auto-detected
by walking upward from the target package directory.
Copilot AI review requested due to automatic review settings April 10, 2026 15:17
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR replaces the repo’s manual monorepo/Rush detection and the hardcoded workspaceRoot: "../.." default with detect-monorepo, so the workspace root can be auto-detected by walking upward from the target package directory (unless explicitly overridden).

Changes:

  • Replace the is-rush-workspace helper with detectMonorepo(dir)?.kind === "rush" at Rush-specific branches.
  • Update resolveWorkspacePaths to auto-detect workspaceRootDir when workspaceRoot is omitted and targetPackagePath isn’t used, throwing a clearer error on failure.
  • Update CLI/docs to describe auto-detection, and adjust unit tests to mock detect-monorepo.

Reviewed changes

Copilot reviewed 17 out of 18 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/lib/utils/is-rush-workspace.ts Removes the old Rush detection helper.
src/lib/utils/index.ts Stops exporting the removed helper.
src/lib/registry/create-packages-registry.ts Uses detect-monorepo to branch for Rush workspaces when enumerating packages.
src/lib/patches/copy-patches.ts Uses detect-monorepo to select Rush vs non-Rush lockfile location for patch hash extraction.
src/lib/patches/copy-patches.test.ts Mocks detect-monorepo for patch-copy tests.
src/lib/package-manager/index.ts Uses detect-monorepo for Rush-aware package manager detection.
src/lib/manifest/helpers/adopt-pnpm-fields-from-root.ts Skips pnpm-field adoption for Rush via detect-monorepo.
src/lib/manifest/helpers/adopt-pnpm-fields-from-root.test.ts Updates mocks/assertions to use detect-monorepo.
src/lib/lockfile/helpers/generate-yarn-lockfile.ts Uses detect-monorepo to locate Rush Yarn lockfile.
src/lib/lockfile/helpers/generate-pnpm-lockfile.ts Uses detect-monorepo to locate Rush PNPM lockfile directory.
src/lib/lockfile/helpers/generate-pnpm-lockfile.test.ts Mocks detect-monorepo for PNPM lockfile generation tests.
src/lib/config.ts Makes workspaceRoot optional; adds auto-detection + error when missing.
src/isolate.ts Uses detect-monorepo to decide Rush-specific pnpm workspace generation behavior.
src/isolate-bin.ts Updates --workspace-root help text and examples for auto-detection.
pnpm-lock.yaml Locks the new detect-monorepo dependency.
package.json Adds detect-monorepo to dependencies.
docs/configuration.md Updates workspaceRoot docs to reflect auto-detection.
docs/api.md Updates config examples to no longer rely on workspaceRoot defaults.
Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported
Comments suppressed due to low confidence (4)

src/lib/registry/create-packages-registry.ts:80

  • detectMonorepo(workspaceRootDir) can return a Rush monorepo whose rootDir is above the provided directory. In that case this branch will still run, but rush.json is read from workspaceRootDir instead of the detected root, which can cause a runtime read error or incorrect project listing. Consider using the returned rootDir for the Rush-specific paths (or require detected.rootDir === workspaceRootDir before treating it as Rush).
  if (detectMonorepo(workspaceRootDir)?.kind === "rush") {
    const rushConfig = readTypedJsonSync<RushConfig>(
      path.join(workspaceRootDir, "rush.json"),
    );

src/lib/patches/copy-patches.ts:157

  • detectMonorepo(workspaceRootDir) may detect a Rush monorepo with rootDir different from the provided workspaceRootDir (since it walks upward). If that happens, lockfileDir will be computed relative to the wrong base directory. Consider basing Rush-specific paths on detectMonorepo(...).rootDir (or only treating it as Rush when the detected root matches workspaceRootDir).
  try {
    const { majorVersion } = usePackageManager();
    const useVersion9 = majorVersion >= 9;
    const isRush = detectMonorepo(workspaceRootDir)?.kind === "rush";

    const lockfileDir = isRush
      ? path.join(workspaceRootDir, "common/config/rush")
      : workspaceRootDir;

src/lib/package-manager/index.ts:30

  • detectMonorepo(workspaceRootDir) can return a Rush monorepo whose rootDir is above workspaceRootDir. In that scenario, common/config/rush will be looked up under the wrong directory. Consider using const detected = detectMonorepo(workspaceRootDir) and basing the Rush lockfile/metadata directory on detected.rootDir (or requiring detected.rootDir === workspaceRootDir).
export function detectPackageManager(workspaceRootDir: string): PackageManager {
  if (detectMonorepo(workspaceRootDir)?.kind === "rush") {
    packageManager = inferFromFiles(
      path.join(workspaceRootDir, "common/config/rush"),
    );
  } else {

src/lib/lockfile/helpers/generate-pnpm-lockfile.ts:72

  • isRush is derived from detectMonorepo(workspaceRootDir)?.kind, but the Rush lockfile directory is still constructed from workspaceRootDir. Because detectMonorepo walks upward, it can report Rush even when workspaceRootDir is a subdirectory; in that case the common/config/rush path will be wrong. Consider basing Rush paths on the detected rootDir (or requiring detected.rootDir === workspaceRootDir).
  try {
    const isRush = detectMonorepo(workspaceRootDir)?.kind === "rush";

    const lockfile = useVersion9
      ? await readWantedLockfile_v9(
          isRush
            ? path.join(workspaceRootDir, "common/config/rush")
            : workspaceRootDir,
          {
            ignoreIncompatible: false,
          },
        )
      : await readWantedLockfile_v8(
          isRush
            ? path.join(workspaceRootDir, "common/config/rush")
            : workspaceRootDir,
          {
            ignoreIncompatible: false,

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/lib/lockfile/helpers/generate-yarn-lockfile.ts Outdated
detectMonorepo walks upward, so its result may describe a monorepo
whose rootDir sits above the passed-in workspaceRootDir. Build all
Rush-specific paths from detected.rootDir instead of the input so
the paths resolve correctly even when called with a subdirectory.
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 8381fa0. Configure here.

Comment thread src/lib/lockfile/helpers/generate-pnpm-lockfile.ts Outdated
The previous commit switched Rush-specific paths to use
detected.rootDir from detectMonorepo, but detectMonorepo walks
upward, so its rootDir can diverge from the workspaceRootDir that
downstream code (notably lockfile importer id computation) is
keyed to. Restoring the strict rush.json check at the passed-in
directory keeps all Rush paths consistent with the rest of the
pipeline.

detect-monorepo remains used in resolveWorkspacePaths for
workspace root auto-detection.
Copilot AI review requested due to automatic review settings April 10, 2026 16:27
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 6 out of 7 changed files in this pull request and generated 2 comments.

Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/lib/config.ts Outdated
Comment thread src/lib/utils/is-rush-workspace.ts
Check for undefined instead of truthiness so an empty string
passed as workspaceRoot is treated as an explicit "same directory"
override rather than falling through to auto-detection.
@0x80 0x80 merged commit d30eec4 into main Apr 10, 2026
5 checks passed
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