Skip to content

Fix project root resolution when vendor is a symlinked directory (git worktree support)#1752

Open
ceilidhboy wants to merge 7 commits into
pestphp:4.xfrom
ceilidhboy:feature/worktree-symlinked-vendor
Open

Fix project root resolution when vendor is a symlinked directory (git worktree support)#1752
ceilidhboy wants to merge 7 commits into
pestphp:4.xfrom
ceilidhboy:feature/worktree-symlinked-vendor

Conversation

@ceilidhboy

@ceilidhboy ceilidhboy commented Jul 12, 2026

Copy link
Copy Markdown

What:

  • Bug Fix
  • New Feature

Description:

When running Pest from a git worktree where vendor/ is a symlink to another worktree (e.g. to avoid the overhead of duplicating dependencies), the project root path was incorrectly resolved to the parent of the resolved vendor directory rather than the worktree root.

The root cause is that PHP's __DIR__ and __FILE__ resolve through symlinks. Since bin/pest lives inside the vendor/ directory, if vendor/ is a symlink then __DIR__ follows it, causing dirname(__DIR__, 4) to point at the wrong worktree's root. The same issue affected bin/worker.php for parallel test execution.

The fix checks whether the current working directory has a vendor symlink that resolves to the same location as the autoloader's vendor parent. If so, the CWD is used as the project root.

Related:

For detailed background on the worktree + symlinked vendor use case, see the wiki page on my fork.

Applies the same symlinked-vendor detection logic from bin/pest to
bin/worker.php, but extracted into a single reusable function instead
of duplicating the inline check at two call sites.
When the worktree detection corrects the root path for symlinked
vendor directories, also set ['APP_BASE_PATH'] so that
Laravel's inferBasePath() picks up the correct worktree path
instead of falling back to the autoloader path (which points
to the symlinked origin worktree). This eliminates the need
for a per-worktree APP_BASE_PATH override in phpunit.xml.
The same block of code for resolving the project root path when vendor
is a symlinked directory (git worktree support) existed in both
bin/pest (inline) and bin/worker.php (as a local function). Extracted
it to a dedicated internal class so there is one definition shared by
both entry points.
Covers four scenarios for worktree root resolution:
- Normal project (no symlink)
- Worktree with matching vendor symlink
- Worktree with vendor symlink pointing elsewhere
- Worktree with real vendor directory (not a symlink)

Also verifies the ['APP_BASE_PATH'] side effect.
@ceilidhboy
ceilidhboy marked this pull request as ready for review July 12, 2026 09:03
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.

1 participant