Fix PSR-4 warnings when using exclude-from-classmap with symlinked directories#12480
Merged
Seldaek merged 2 commits intocomposer:2.8from Aug 21, 2025
Merged
Fix PSR-4 warnings when using exclude-from-classmap with symlinked directories#12480Seldaek merged 2 commits intocomposer:2.8from
Seldaek merged 2 commits intocomposer:2.8from
Conversation
…rectories
### Description
This PR fixes an issue where Composer generates incorrect PSR-4 compliance warnings when using `exclude-from-classmap` patterns with directories that are symlinks.
### The Problem
When a PSR-4 autoload path is a symlink (either relative or absolute) and the project uses `exclude-from-classmap` patterns (e.g., `**/vendor/`), Composer incorrectly reports that classes in the excluded directories don't comply with PSR-4 standards.
Example warning:
```
Class Doctrine\Instantiator\InstantiatorInterface located in ./tools/vendor/doctrine/instantiator/src/Doctrine/Instantiator/InstantiatorInterface.php does not comply with psr-4 autoloading standard (rule: MyTools\ => ./tools). Skipping.
```
### Root Cause
The issue occurs because:
1. The `buildExclusionRegex` method was only matching exclude patterns against the real path of directories
2. When scanning symlinked directories, the patterns needed to match against both the symlink path and the resolved path
### The Solution
The fix updates `buildExclusionRegex` to also check exclude patterns against the normalized (non-realpath) version of the directory being scanned. This ensures that exclude patterns work correctly whether the directory is accessed via its symlink path or its real path.
### Testing
Added a new test case `testAbsoluteSymlinkWithPsr4DoesNotGenerateWarnings` that:
1. Creates a PSR-4 autoload rule pointing to an absolute symlink
2. Uses `exclude-from-classmap` to exclude vendor directories
3. Verifies that no PSR-4 compliance warnings are generated
All existing tests continue to pass.
### Reproducing the Issue
Before this fix:
```bash
# Create a test directory with a symlink (relative or absolute)
mkdir actual-tools
ln -s actual-tools tools
# OR with absolute path:
# ln -s /tmp/tools-composer-test tools
# Add to composer.json:
{
"autoload": {
"psr-4": {
"MyTools\\": "tools/"
},
"exclude-from-classmap": ["**/vendor/"]
}
}
# Run composer dump-autoload -o
# Results in PSR-4 warnings for files in tools/vendor/
```
After this fix: No warnings are generated for excluded paths.
Fixes composer#12478
Member
|
Thanks! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #12478 in 2.8
Description
This PR fixes an issue where Composer generates incorrect PSR-4 compliance warnings when using
exclude-from-classmappatterns with directories that are symlinks.The Problem
When a PSR-4 autoload path is a symlink (either relative or absolute) and the project uses
exclude-from-classmappatterns (e.g.,**/vendor/), Composer incorrectly reports that classes in the excluded directories don't comply with PSR-4 standards.Example warning:
Root Cause
The issue occurs because:
buildExclusionRegexmethod was only matching exclude patterns against the real path of directoriesThe Solution
The fix updates
buildExclusionRegexto also check exclude patterns against the normalized (non-realpath) version of the directory being scanned. This ensures that exclude patterns work correctly whether the directory is accessed via its symlink path or its real path.Testing
Added a new test case
testAbsoluteSymlinkWithPsr4DoesNotGenerateWarningsthat:exclude-from-classmapto exclude vendor directoriesAll existing tests continue to pass.
Reproducing the Issue
Before this fix:
After this fix: No warnings are generated for excluded paths.