Skip to content

Commit 517afa9

Browse files
authored
Fix Composer autoloading (#59)
Add the missing parts to ensure the scoped code that still be autoloaded via Composer. Closes #46
1 parent a2e26c7 commit 517afa9

File tree

14 files changed

+580
-109
lines changed

14 files changed

+580
-109
lines changed

Makefile

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ PHPUNIT=vendor/bin/phpunit
33
PHPSCOPER=bin/php-scoper.phar
44

55
.DEFAULT_GOAL := help
6-
.PHONY: build test tu tc e2e
6+
.PHONY: build test tu tc e2e tb
77

88

99
help:
@@ -58,6 +58,12 @@ e2e: scoper
5858
php build/set004/bin/greet.phar > build/output
5959
diff fixtures/set004/expected-output build/output
6060

61+
php -d zend.enable_gc=0 $(PHPSCOPER) add-prefix fixtures/set005 -o build/set005 -f
62+
composer -d=build/set005 dump-autoload
63+
php -d zend.enable_gc=0 $(BOX) build -c build/set005/box.json.dist
64+
php build/set005/bin/greet.phar > build/output
65+
diff fixtures/set005/expected-output build/output
66+
6167
tb: ## Run Blackfire profiling
6268
tb: vendor
6369
rm -rf build

fixtures/set005/bin/greet.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
require_once __DIR__.'/../vendor/autoload.php';
6+
7+
use Assert\Assertion;
8+
use Set005\Greeter;
9+
10+
Assertion::true(true);
11+
echo (new Greeter())->greet().PHP_EOL;

fixtures/set005/box.json.dist

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"output": "build/set005/bin/greet.phar",
3+
"main": "bin/greet.php",
4+
"base-path": "build/set005",
5+
"directories": [
6+
"src",
7+
"vendor"
8+
],
9+
"compression": "GZ",
10+
"compactors": [
11+
"Herrera\\Box\\Compactor\\Json",
12+
"Herrera\\Box\\Compactor\\Php"
13+
],
14+
"stub": true
15+
}

fixtures/set005/composer.json

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"bin": [
3+
"bin/greet"
4+
],
5+
"autoload": {
6+
"psr-4": {
7+
"Set005\\": "src/"
8+
}
9+
},
10+
"require": {
11+
"beberlei/assert": "^2.7"
12+
}
13+
}

fixtures/set005/composer.lock

Lines changed: 73 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

fixtures/set005/expected-output

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Hello world!

fixtures/set005/src/Greeter.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 Set005;
6+
7+
class Greeter
8+
{
9+
public function greet(): string
10+
{
11+
return 'Hello world!';
12+
}
13+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
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+
namespace Humbug\PhpScoper\Scoper\Composer;
16+
17+
/**
18+
* @internal
19+
*/
20+
final class AutoloadPrefixer
21+
{
22+
/**
23+
* @param array $content Decoded JSON
24+
* @param string $prefix
25+
*
26+
* @return array Prefixed decoded JSON
27+
*/
28+
public static function prefixPackageAutoloads(array $content, string $prefix): array
29+
{
30+
if (isset($content['autoload'])) {
31+
$content['autoload'] = self::prefixAutoloads($content['autoload'], $prefix);
32+
}
33+
34+
if (isset($content['autoload-dev'])) {
35+
$content['autoload-dev'] = self::prefixAutoloads($content['autoload-dev'], $prefix);
36+
}
37+
38+
return $content;
39+
}
40+
41+
private static function prefixAutoloads(array $autoload, string $prefix): array
42+
{
43+
if (isset($autoload['psr-4'])) {
44+
$autoload['psr-4'] = self::prefixAutoload($autoload['psr-4'], $prefix);
45+
}
46+
47+
return $autoload;
48+
}
49+
50+
private static function prefixAutoload(array $autoload, string $prefix): array
51+
{
52+
$loader = [];
53+
54+
foreach ($autoload as $namespace => $paths) {
55+
$loader[sprintf('%s\\%s', $prefix, $namespace)] = $paths;
56+
}
57+
58+
return $loader;
59+
}
60+
}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
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+
namespace Humbug\PhpScoper\Scoper\Composer;
16+
17+
use Humbug\PhpScoper\Scoper;
18+
use LogicException;
19+
20+
final class InstalledPackagesScoper implements Scoper
21+
{
22+
/**
23+
* @var string
24+
*/
25+
private static $filePattern;
26+
27+
private $decoratedScoper;
28+
29+
public function __construct(Scoper $decoratedScoper)
30+
{
31+
if (null === self::$filePattern) {
32+
self::$filePattern = str_replace(
33+
'/',
34+
DIRECTORY_SEPARATOR,
35+
'~composer/installed\.json~'
36+
);
37+
}
38+
39+
$this->decoratedScoper = $decoratedScoper;
40+
}
41+
42+
/**
43+
* Scopes PHP and JSON files related to Composer.
44+
*
45+
* {@inheritdoc}
46+
*/
47+
public function scope(string $filePath, string $prefix): string
48+
{
49+
if (null === self::$filePattern) {
50+
throw new LogicException('Cannot be used without being initialised first.');
51+
}
52+
53+
if (1 !== preg_match(self::$filePattern, $filePath)) {
54+
return $this->decoratedScoper->scope($filePath, $prefix);
55+
}
56+
57+
$decodedJson = json_decode(
58+
file_get_contents($filePath),
59+
true
60+
);
61+
62+
$decodedJson = $this->prefixLockPackages($decodedJson, $prefix);
63+
64+
return json_encode(
65+
$decodedJson,
66+
JSON_PRETTY_PRINT
67+
);
68+
}
69+
70+
private function prefixLockPackages(array $packages, string $prefix): array
71+
{
72+
foreach ($packages as $index => $package) {
73+
$packages[$index] = AutoloadPrefixer::prefixPackageAutoloads($package, $prefix);
74+
}
75+
76+
return $packages;
77+
}
78+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
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+
namespace Humbug\PhpScoper\Scoper\Composer;
16+
17+
use Humbug\PhpScoper\Scoper;
18+
19+
final class JsonFileScoper implements Scoper
20+
{
21+
private $decoratedScoper;
22+
23+
public function __construct(Scoper $decoratedScoper)
24+
{
25+
$this->decoratedScoper = $decoratedScoper;
26+
}
27+
28+
/**
29+
* Scopes PHP and JSON files related to Composer.
30+
*
31+
* {@inheritdoc}
32+
*/
33+
public function scope(string $filePath, string $prefix): string
34+
{
35+
if (1 !== preg_match('/composer\.json$/', $filePath)) {
36+
return $this->decoratedScoper->scope($filePath, $prefix);
37+
}
38+
39+
$decodedJson = json_decode(
40+
file_get_contents($filePath),
41+
true
42+
);
43+
44+
$decodedJson = AutoloadPrefixer::prefixPackageAutoloads($decodedJson, $prefix);
45+
46+
return json_encode(
47+
$decodedJson,
48+
JSON_PRETTY_PRINT
49+
);
50+
}
51+
}

0 commit comments

Comments
 (0)