Skip to content

Commit

Permalink
Merge pull request #402 from bearsunday/compile_injector
Browse files Browse the repository at this point in the history
Compile Injector
  • Loading branch information
koriym committed Oct 17, 2022
2 parents 3ac8625 + ec1696f commit 8ba04a7
Show file tree
Hide file tree
Showing 7 changed files with 84 additions and 12 deletions.
4 changes: 2 additions & 2 deletions composer.json
Expand Up @@ -21,7 +21,7 @@
"bear/sunday": "^1.6",
"monolog/monolog": "^1.25 || ^2.0",
"ray/aop": "^2.10",
"ray/di": "^2.13",
"ray/di": "^2.14.5",
"ray/object-visual-grapher": "^1.0",
"psr/log": "^1.1 || ^2.0 || ^3.0",
"doctrine/cache": "^1.10 || ^2.0",
Expand All @@ -31,7 +31,7 @@
"symfony/cache": "^5.3",
"psr/cache": "^1.0",
"koriym/attributes": "^1.0",
"ray/compiler": "^1.7"
"ray/compiler": "^1.9.1"
},
"require-dev": {
"phpunit/phpunit": "^9.5.10",
Expand Down
1 change: 1 addition & 0 deletions phpunit.xml.dist
Expand Up @@ -10,6 +10,7 @@
<testsuites>
<testsuite name="core">
<directory>tests/</directory>
<exclude>tests/Fake</exclude>
<exclude>tests/Context/**/</exclude>
<exclude>tests/Provide/**/</exclude>
</testsuite>
Expand Down
5 changes: 3 additions & 2 deletions src/Injector/PackageInjector.php
Expand Up @@ -5,10 +5,11 @@
namespace BEAR\Package\Injector;

use BEAR\AppMeta\AbstractAppMeta;
use BEAR\Package\LazyModule;
use BEAR\Package\Module;
use BEAR\Package\Module\ScriptinjectorModule;
use BEAR\Sunday\Extension\Application\AppInterface;
use Ray\Compiler\Annotation\Compile;
use Ray\Compiler\CompileInjector;
use Ray\Compiler\ScriptInjector;
use Ray\Di\AbstractModule;
use Ray\Di\Injector as RayInjector;
Expand Down Expand Up @@ -73,7 +74,7 @@ public static function factory(AbstractAppMeta $meta, string $context, ?Abstract
$isProd = $injector->getInstance('', Compile::class);
assert(is_bool($isProd));
if ($isProd) {
$injector = new ScriptInjector($scriptDir, static fn () => new ScriptinjectorModule($scriptDir, $module));
$injector = new CompileInjector($scriptDir, new LazyModule($meta, $context, $scriptDir));
}

$injector->getInstance(AppInterface::class);
Expand Down
38 changes: 38 additions & 0 deletions src/LazyModule.php
@@ -0,0 +1,38 @@
<?php

declare(strict_types=1);

namespace BEAR\Package;

use BEAR\AppMeta\AbstractAppMeta;
use BEAR\Package\Module\ResourceObjectModule;
use BEAR\Package\Module\ScriptinjectorModule;
use Ray\Compiler\LazyModuleInterface;
use Ray\Di\AbstractModule;

class LazyModule implements LazyModuleInterface
{
/** @var AbstractAppMeta */
private $appMeta;

/** @var string */
private $context;

/** @var string */
private $scriptDir;

public function __construct(AbstractAppMeta $appMeta, string $context, string $scriptDir)
{
$this->appMeta = $appMeta;
$this->context = $context;
$this->scriptDir = $scriptDir;
}

public function __invoke(): AbstractModule
{
$module = new ScriptinjectorModule($this->scriptDir, (new Module())($this->appMeta, $this->context));
$module->install(new ResourceObjectModule($this->appMeta->getResourceListGenerator()));

return $module;
}
}
36 changes: 36 additions & 0 deletions src/Module/ResourceObjectModule.php
@@ -0,0 +1,36 @@
<?php

declare(strict_types=1);

namespace BEAR\Package\Module;

use BEAR\Package\Provide\Error\NullPage;
use Generator;
use Ray\Di\AbstractModule;

/**
* Bind all resource object
*/
class ResourceObjectModule extends AbstractModule
{
/** @var Generator<array{0: class-string, 1: string}> */
private $resourceObjects;

/**
* @param Generator<array{0: class-string, 1: string}> $resourceObjects
*/
public function __construct(Generator $resourceObjects)
{
$this->resourceObjects = $resourceObjects;
parent::__construct();
}

protected function configure(): void
{
foreach ($this->resourceObjects as [$class]) {
$this->bind($class);
}

$this->bind(NullPage::class);
}
}
8 changes: 1 addition & 7 deletions tests/CompilerTest.php
Expand Up @@ -6,7 +6,6 @@

use BEAR\Package\Exception\InvalidContextException;
use PHPUnit\Framework\TestCase;
use Ray\Compiler\ScriptInjector;
use RuntimeException;

use function error_log;
Expand All @@ -17,40 +16,35 @@ class CompilerTest extends TestCase
public function setUp(): void
{
$this->setOutputCallback(static function (string $msg) {
/** @noinspection ForgottenDebugOutputInspection */
error_log($msg);
});
}

public function testInvoke(): void
{
$compiledFile1 = __DIR__ . '/Fake/fake-app/var/tmp/prod-cli-app/di/FakeVendor_HelloWorld_Resource_Page_Index-.php';
$compiledFile2 = __DIR__ . '/Fake/fake-app/var/tmp/prod-cli-app/di' . ScriptInjector::MODULE;
$compiledFile3 = __DIR__ . '/Fake/fake-app/var/tmp/prod-cli-app/di/FakeVendor_HelloWorld_FakeFoo-.php';
@unlink($compiledFile1);
@unlink($compiledFile2);
@unlink($compiledFile3);
$compiler = new Compiler('FakeVendor\HelloWorld', 'prod-cli-app', __DIR__ . '/Fake/fake-app', false);
$status = $compiler->compile();
$this->assertSame(0, $status);
$compiler->dumpAutoload();
$this->assertFileExists($compiledFile1);
$this->assertFileExists($compiledFile2);
$this->assertFileExists($compiledFile3);
}

public function testInvokeAgain(): void
{
$compiledFile1 = __DIR__ . '/Fake/fake-app/var/tmp/prod-cli-app/di/FakeVendor_HelloWorld_Resource_Page_Index-.php';
$compiledFile2 = __DIR__ . '/Fake/fake-app/var/tmp/prod-cli-app/di' . ScriptInjector::MODULE;
$compiledFile3 = __DIR__ . '/Fake/fake-app/var/tmp/prod-cli-app/di/FakeVendor_HelloWorld_FakeFoo-.php';
@unlink($compiledFile1);
@unlink($compiledFile2);
@unlink($compiledFile3);
$compiler = new Compiler('FakeVendor\HelloWorld', 'prod-cli-app', __DIR__ . '/Fake/fake-app', false);
$compiler->compile();
$compiler->dumpAutoload();
$this->assertFileExists($compiledFile1);
$this->assertFileDoesNotExist($compiledFile2); // because cached
$this->assertFileExists($compiledFile3);
}

Expand Down
4 changes: 3 additions & 1 deletion tests/Fake/boot.php
Expand Up @@ -3,6 +3,7 @@
declare(strict_types=1);

use BEAR\Package\Bootstrap;
use BEAR\Package\Injector;
use BEAR\Resource\ResourceObject;
use BEAR\Sunday\Extension\Application\AppInterface;

Expand All @@ -11,6 +12,7 @@
run:
$packageDir = dirname(__DIR__, 2);
require $packageDir . '/vendor/autoload.php';
$app = (new Bootstrap)->getApp('FakeVendor\HelloWorld', 'hal-app', $packageDir . '/tests/Fake/fake-app', '');
$injector = Injector::getInstance('FakeVendor\HelloWorld', 'hal-app', $packageDir . '/tests/Fake/fake-app');
$app = $injector->getInstance(AppInterface::class);
$ro = $app->resource->newInstance('/');
exit((int) ! ($app instanceof AppInterface && $ro instanceof ResourceObject));

0 comments on commit 8ba04a7

Please sign in to comment.