Skip to content

Commit 5d6c97f

Browse files
authored
Fix the namespace whitelisting autoloading (#223)
1 parent 21bd501 commit 5d6c97f

18 files changed

+374
-12
lines changed

Makefile

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ tm: vendor/bin/phpunit
5151

5252
.PHONY: e2e
5353
e2e: ## Run end-to-end tests
54-
e2e: e2e_004 e2e_005 e2e_011 e2e_013 e2e_014 e2e_015 e2e_016 e2e_017 e2e_018 e2e_019 e2e_020 e2e_021
54+
e2e: e2e_004 e2e_005 e2e_011 e2e_013 e2e_014 e2e_015 e2e_016 e2e_017 e2e_018 e2e_019 e2e_020 e2e_021 e2e_022 e2e_023
5555

5656
PHPSCOPER=bin/php-scoper.phar
5757

@@ -162,6 +162,26 @@ e2e_021: bin/php-scoper.phar fixtures/set021-composer/vendor clover.xml
162162

163163
diff build/set021-composer/expected-output build/set021-composer/output
164164

165+
.PHONY: e2e_022
166+
e2e_022: ## Run end-to-end tests for the fixture set 022: whitelist the project code with namespace whitelisting
167+
e2e_022: bin/php-scoper.phar fixtures/set022/vendor
168+
$(PHPNOGC) $(BOX) compile --working-dir fixtures/set022
169+
cp -R fixtures/set022/tests/ build/set022/tests/
170+
171+
php build/set022/bin/greet.phar > build/set022/output
172+
173+
diff fixtures/set022/expected-output build/set022/output
174+
175+
.PHONY: e2e_023
176+
e2e_023: ## Run end-to-end tests for the fixture set 023: Whitelisting a whole third-party component with namespace whitelisting
177+
e2e_023: bin/php-scoper.phar fixtures/set023/vendor
178+
$(PHPNOGC) $(PHPSCOPER) add-prefix --working-dir=fixtures/set023 --output-dir=../../build/set023 --force --no-interaction --stop-on-failure
179+
composer --working-dir=build/set023 dump-autoload
180+
181+
php build/set023/main.php > build/set023/output
182+
diff fixtures/set023/expected-output build/set023/output
183+
184+
165185
.PHONY: tb
166186
BLACKFIRE=blackfire
167187
tb: ## Run Blackfire profiling
@@ -233,6 +253,14 @@ fixtures/set021-composer/vendor: fixtures/set021-composer/composer.lock
233253
composer --working-dir=fixtures/set021-composer install
234254
touch $@
235255

256+
fixtures/set022/vendor: fixtures/set022/composer.json
257+
composer --working-dir=fixtures/set022 update
258+
touch $@
259+
260+
fixtures/set023/vendor: fixtures/set023/composer.lock
261+
composer --working-dir=fixtures/set023 install
262+
touch $@
263+
236264
composer.lock: composer.json
237265
@echo composer.lock is not up to date.
238266

@@ -263,6 +291,9 @@ fixtures/set020-infection/composer.lock: fixtures/set020-infection/composer.json
263291
fixtures/set021-composer/composer.lock: fixtures/set021-composer/composer.json
264292
@echo fixtures/set021-composer/composer.lock is not up to date.
265293

294+
fixtures/set023/composer.lock: fixtures/set023/composer.json
295+
@echo fixtures/set023/composer.lock is not up to date.
296+
266297
bin/php-scoper.phar: bin/php-scoper src vendor scoper.inc.php box.json
267298
$(BOX) compile
268299
touch $@

fixtures/set022/bin/greet.php

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
$autoload = __DIR__.'/../vendor/scoper-autoload.php';
6+
7+
if (false === file_exists($autoload)) {
8+
$autoload = __DIR__.'/../vendor/autoload.php';
9+
}
10+
11+
require_once $autoload;
12+
13+
use Set022\DirectionaryLocator;
14+
use Set022\Greeter;
15+
use Set022\Dictionary;
16+
17+
$dir = Phar::running(false);
18+
19+
if ('' === $dir) {
20+
// Running outside of a PHAR
21+
$dir = __DIR__.DIRECTORY_SEPARATOR.'bin';
22+
}
23+
24+
$testDir = dirname($dir).'/../tests';
25+
26+
$dictionaries = DirectionaryLocator::locateDictionaries($testDir);
27+
28+
$words = array_reduce(
29+
$dictionaries,
30+
function (array $words, Dictionary $dictionary): array {
31+
$words = array_merge($words, $dictionary->provideWords());
32+
33+
return $words;
34+
},
35+
[]
36+
);
37+
38+
$greeter = new Greeter($words);
39+
40+
foreach ($greeter->greet() as $greeting) {
41+
echo $greeting.PHP_EOL;
42+
}

fixtures/set022/box.json.dist

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"output": "../../build/set022/bin/greet.phar",
3+
"compactors": ["KevinGH\\Box\\Compactor\\PhpScoper"]
4+
}

fixtures/set022/composer.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"bin": [
3+
"bin/greet.php"
4+
],
5+
"autoload": {
6+
"psr-4": {
7+
"Set022\\": "src/"
8+
}
9+
},
10+
"autoload-dev": {
11+
"psr-4": {
12+
"Set022\\": "tests/"
13+
}
14+
}
15+
}

fixtures/set022/expected-output

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Hello world!
2+
Hi world!
3+
Salut world!
4+
Bonjour world!

fixtures/set022/scoper.inc.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* This file is part of the humbug/php-scoper package.
7+
*
8+
* Copyright (c) 2017 Théo FIDRY <[email protected]>,
9+
* Pádraic Brady <[email protected]>
10+
*
11+
* For the full copyright and license information, please view the LICENSE
12+
* file that was distributed with this source code.
13+
*/
14+
15+
return [
16+
'whitelist' => [
17+
'Set022\*',
18+
],
19+
];

fixtures/set022/src/Dictionary.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Set022;
6+
7+
interface Dictionary
8+
{
9+
/**
10+
* @return string[]
11+
*/
12+
public function provideWords(): array;
13+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Set022;
6+
7+
use ReflectionClass;
8+
9+
final class DirectionaryLocator
10+
{
11+
/**
12+
* @param string $dir
13+
*
14+
* @return Dictionary[]
15+
*/
16+
public static function locateDictionaries(string $dir): array
17+
{
18+
$dictionaryFiles = array_values(
19+
array_filter(
20+
array_map(
21+
function (string $filePath) use ($dir) {
22+
return realpath($dir.DIRECTORY_SEPARATOR.$filePath);
23+
},
24+
array_filter(
25+
scandir($dir),
26+
function (string $file): bool {
27+
return 1 === preg_match('/.*Dictionary\.php$/', $file);
28+
}
29+
)
30+
),
31+
function ($filePath): bool {
32+
return false !== $filePath;
33+
34+
}
35+
)
36+
);
37+
38+
$classes = get_declared_classes();
39+
40+
foreach ($dictionaryFiles as $dictionaryFile) {
41+
include $dictionaryFile;
42+
}
43+
44+
$newClasses = array_diff(get_declared_classes(), $classes);
45+
46+
return array_reduce(
47+
$newClasses,
48+
function (array $dictionaries, string $className): array {
49+
$class = new ReflectionClass($className);
50+
51+
if (false === $class->isAbstract() && $class->implementsInterface(Dictionary::class)) {
52+
$dictionaries[] = $class->newInstanceWithoutConstructor();
53+
}
54+
55+
return $dictionaries;
56+
},
57+
[]
58+
);
59+
}
60+
61+
private function __construct()
62+
{
63+
64+
}
65+
}

fixtures/set022/src/Greeter.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Set022;
6+
7+
use Generator;
8+
9+
class Greeter
10+
{
11+
private $words;
12+
13+
/**
14+
* @param string[] $words
15+
*/
16+
public function __construct(array $words)
17+
{
18+
$this->words = $words;
19+
}
20+
21+
/**
22+
* @return Generator|string
23+
*/
24+
public function greet()
25+
{
26+
foreach ($this->words as $word) {
27+
yield $word.' world!';
28+
}
29+
}
30+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Set022;
6+
7+
final class SalutationDictionary implements Dictionary
8+
{
9+
/**
10+
* @inheritdoc
11+
*/
12+
public function provideWords(): array
13+
{
14+
return [
15+
'Hello',
16+
'Hi',
17+
'Salut',
18+
'Bonjour',
19+
];
20+
}
21+
}

0 commit comments

Comments
 (0)