Skip to content

Conversation

@sanmai
Copy link
Contributor

@sanmai sanmai commented Jul 17, 2025

Fixes #12478 in 2.8

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:

# 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.

…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
@sanmai sanmai changed the base branch from main to 2.8 July 17, 2025 10:40
@sanmai sanmai marked this pull request as ready for review July 17, 2025 10:41
@Seldaek Seldaek added this to the 2.8 milestone Aug 21, 2025
@Seldaek
Copy link
Member

Seldaek commented Aug 21, 2025

Thanks!

@Seldaek Seldaek merged commit e95d72a into composer:2.8 Aug 21, 2025
20 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.

Absolute symlinks cause warnings for PSR-4 scanning

2 participants