bug #40917 [Config][DependencyInjection] Uniformize trailing slash handling (dunglas)
This PR was squashed before being merged into the 4.4 branch.
Discussion
----------
[Config][DependencyInjection] Uniformize trailing slash handling
| Q | A
| ------------- | ---
| Branch? | 4.4
| Bug fix? | yes
| New feature? | no <!-- please update src/**/CHANGELOG.md files -->
| Deprecations? | no <!-- please update UPGRADE-*.md and src/**/CHANGELOG.md files -->
| Tickets | n/a
| License | MIT
| Doc PR | n/a
Currently, the handling of trailing slashes in file loaders exclusion rules is inconsistent, which can create hard to debug issues.
Example:
```yaml
services:
App\:
resource: '../src/'
exclude:
# This works
- '../src/FooBar/DependencyInjection/'
- '../src/FooBar/DependencyInjection'
- '../src/FooBar/DependencyInjection/*'
- '../src/*/DependencyInjection'
- '../src/*/DependencyInjection/*'
# This doesn't work
- '../src/*/DependencyInjection/'
```
This PR fixes this subtle issue.
Commits
-------
dc50aa3b55
[Config][DependencyInjection] Uniformize trailing slash handling
This commit is contained in:
commit
0e738ef170
@ -82,8 +82,8 @@ abstract class FileLoader extends Loader
|
|||||||
$excluded = [];
|
$excluded = [];
|
||||||
foreach ((array) $exclude as $pattern) {
|
foreach ((array) $exclude as $pattern) {
|
||||||
foreach ($this->glob($pattern, true, $_, false, true) as $path => $info) {
|
foreach ($this->glob($pattern, true, $_, false, true) as $path => $info) {
|
||||||
// normalize Windows slashes
|
// normalize Windows slashes and remove trailing slashes
|
||||||
$excluded[str_replace('\\', '/', $path)] = true;
|
$excluded[rtrim(str_replace('\\', '/', $path), '/')] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,6 +127,28 @@ class FileLoaderTest extends TestCase
|
|||||||
$this->assertCount(2, $loadedFiles);
|
$this->assertCount(2, $loadedFiles);
|
||||||
$this->assertNotContains('ExcludeFile.txt', $loadedFiles);
|
$this->assertNotContains('ExcludeFile.txt', $loadedFiles);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider excludeTrailingSlashConsistencyProvider
|
||||||
|
*/
|
||||||
|
public function testExcludeTrailingSlashConsistency(string $exclude)
|
||||||
|
{
|
||||||
|
$loader = new TestFileLoader(new FileLocator(__DIR__.'/../Fixtures'));
|
||||||
|
$loadedFiles = $loader->import('ExcludeTrailingSlash/*', null, false, null, $exclude);
|
||||||
|
$this->assertCount(2, $loadedFiles);
|
||||||
|
$this->assertNotContains('baz.txt', $loadedFiles);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function excludeTrailingSlashConsistencyProvider(): iterable
|
||||||
|
{
|
||||||
|
yield [__DIR__.'/../Fixtures/Exclude/ExcludeToo/'];
|
||||||
|
yield [__DIR__.'/../Fixtures/Exclude/ExcludeToo'];
|
||||||
|
yield [__DIR__.'/../Fixtures/Exclude/ExcludeToo/*'];
|
||||||
|
yield [__DIR__.'/../Fixtures/*/ExcludeToo'];
|
||||||
|
yield [__DIR__.'/../Fixtures/*/ExcludeToo/'];
|
||||||
|
yield [__DIR__.'/../Fixtures/Exclude/ExcludeToo/*'];
|
||||||
|
yield [__DIR__.'/../Fixtures/Exclude/ExcludeToo/AnotheExcludedFile.txt'];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class TestFileLoader extends FileLoader
|
class TestFileLoader extends FileLoader
|
||||||
|
@ -177,6 +177,7 @@ class GlobResourceTest extends TestCase
|
|||||||
|
|
||||||
$expected = [
|
$expected = [
|
||||||
$dir.'/Exclude/ExcludeToo/AnotheExcludedFile.txt',
|
$dir.'/Exclude/ExcludeToo/AnotheExcludedFile.txt',
|
||||||
|
$dir.'/ExcludeTrailingSlash/exclude/baz.txt',
|
||||||
$dir.'/foo.xml',
|
$dir.'/foo.xml',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -166,8 +166,8 @@ abstract class FileLoader extends BaseFileLoader
|
|||||||
$excludePrefix = $resource->getPrefix();
|
$excludePrefix = $resource->getPrefix();
|
||||||
}
|
}
|
||||||
|
|
||||||
// normalize Windows slashes
|
// normalize Windows slashes and remove trailing slashes
|
||||||
$excludePaths[str_replace('\\', '/', $path)] = true;
|
$excludePaths[rtrim(str_replace('\\', '/', $path), '/')] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -239,6 +239,35 @@ class FileLoaderTest extends TestCase
|
|||||||
'yaml/*'
|
'yaml/*'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider excludeTrailingSlashConsistencyProvider
|
||||||
|
*/
|
||||||
|
public function testExcludeTrailingSlashConsistency(string $exclude)
|
||||||
|
{
|
||||||
|
$container = new ContainerBuilder();
|
||||||
|
$loader = new TestFileLoader($container, new FileLocator(self::$fixturesPath.'/Fixtures'));
|
||||||
|
$loader->registerClasses(
|
||||||
|
new Definition(),
|
||||||
|
'Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\\',
|
||||||
|
'Prototype/*',
|
||||||
|
$exclude
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertTrue($container->has(Foo::class));
|
||||||
|
$this->assertFalse($container->has(DeeperBaz::class));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function excludeTrailingSlashConsistencyProvider(): iterable
|
||||||
|
{
|
||||||
|
yield ['Prototype/OtherDir/AnotherSub/'];
|
||||||
|
yield ['Prototype/OtherDir/AnotherSub'];
|
||||||
|
yield ['Prototype/OtherDir/AnotherSub/*'];
|
||||||
|
yield ['Prototype/*/AnotherSub'];
|
||||||
|
yield ['Prototype/*/AnotherSub/'];
|
||||||
|
yield ['Prototype/*/AnotherSub/*'];
|
||||||
|
yield ['Prototype/OtherDir/AnotherSub/DeeperBaz.php'];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class TestFileLoader extends FileLoader
|
class TestFileLoader extends FileLoader
|
||||||
|
Reference in New Issue
Block a user