Skip to content

generate a SchemaCompiledEvent when Type files are generated #730

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Aug 21, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion UPGRADE-1.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ public function __construct(
?string $cacheDir,
array $configs,
+ TypeBuilder $typeBuilder
+ EventDispatcherInterface $eventDispatcher
bool $useClassMap = true,
- callable $configProcessor = null,
?string $baseCacheDir = null,
Expand Down Expand Up @@ -84,4 +85,4 @@ class Argument implements ArgumentInterface
+ }
}
```
If you use your own class for resolver arguments, then it should have a `__get` method as well.
If you use your own class for resolver arguments, then it should have a `__get` method as well.
88 changes: 88 additions & 0 deletions docs/events/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -186,3 +186,91 @@ class TypeDecorator
}
}
```

Schema Compiled
----------------

*Event:* `Overblog\GraphQLBundle\Event\SchemaCompiledEvent`

Used to be notified when the schema has been newly compiled.

Example:

```php
<?php declare(strict_types=1);

namespace App\Infra\GraphQL\CacheWarmer;

use GraphQL\Utils\SchemaPrinter;
use Overblog\GraphQLBundle\Event\SchemaCompiledEvent;
use Overblog\GraphQLBundle\Request\Executor as RequestExecutor;
use Overblog\GraphQLBundle\Request\ParserInterface;
use Symfony\Component\Console\Event\ConsoleCommandEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\RequestEvent;

class GraphQLSchemaDumperSubscriber implements EventSubscriberInterface
{
private RequestExecutor $requestExecutor;

private string $projectDir;

private bool $schemaWasRecompiled = false;

public function __construct(RequestExecutor $requestExecutor, string $projectDir)
{
$this->requestExecutor = $requestExecutor;
$this->projectDir = $projectDir;
}

public function onSchemaCompiled(): void
{
$this->schemaWasRecompiled = true;
}

public function dumpSchema(): void
{
if (!$this->schemaWasRecompiled) {
return;
}

file_put_contents(
"{$this->projectDir}/schema.graphql",
SchemaPrinter::doPrint($this->requestExecutor->getSchema()),
) or die("failed to save {$this->projectDir}/schema.graphql");

$result = $this->requestExecutor
->execute(null, [
ParserInterface::PARAM_QUERY => <<<GQL
query {
__schema {
types {
kind
name
possibleTypes {
name
}
}
}
}
GQL,
ParserInterface::PARAM_VARIABLES => [],
])
->toArray();

file_put_contents(
"{$this->projectDir}/schema-fragments.json",
\json_encode($result, \JSON_PRETTY_PRINT),
) or die("failed to save {$this->projectDir}/schema-fragments.json");
}

public static function getSubscribedEvents()
{
return [
SchemaCompiledEvent::class => "onSchemaCompiled",
RequestEvent::class => "dumpSchema",
ConsoleCommandEvent::class => "dumpSchema",
];
}
}
```
11 changes: 11 additions & 0 deletions src/Event/SchemaCompiledEvent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

declare(strict_types=1);

namespace Overblog\GraphQLBundle\Event;

use Symfony\Contracts\EventDispatcher\Event;

final class SchemaCompiledEvent extends Event
{
}
7 changes: 7 additions & 0 deletions src/Generator/TypeGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@

use Composer\Autoload\ClassLoader;
use Overblog\GraphQLBundle\Config\Processor;
use Overblog\GraphQLBundle\Event\SchemaCompiledEvent;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
use function array_merge;
use function file_exists;
use function file_put_contents;
Expand All @@ -33,12 +35,14 @@ class TypeGenerator
private ?string $baseCacheDir;
private string $classNamespace;
private TypeBuilder $typeBuilder;
private EventDispatcherInterface $eventDispatcher;

public function __construct(
string $classNamespace,
?string $cacheDir,
array $configs,
TypeBuilder $typeBuilder,
EventDispatcherInterface $eventDispatcher,
bool $useClassMap = true,
?string $baseCacheDir = null,
?int $cacheDirMask = null
Expand All @@ -48,6 +52,7 @@ public function __construct(
$this->useClassMap = $useClassMap;
$this->baseCacheDir = $baseCacheDir;
$this->typeBuilder = $typeBuilder;
$this->eventDispatcher = $eventDispatcher;
$this->classNamespace = $classNamespace;

if (null === $cacheDirMask) {
Expand Down Expand Up @@ -120,6 +125,8 @@ public function compile(int $mode): array
$this->loadClasses(true);
}

$this->eventDispatcher->dispatch(new SchemaCompiledEvent());

return $classes;
}

Expand Down
1 change: 1 addition & 0 deletions src/Resources/config/services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ services:
- "%overblog_graphql.cache_dir%"
- "%overblog_graphql_types.config%"
- '@Overblog\GraphQLBundle\Generator\TypeBuilder'
- '@Symfony\Contracts\EventDispatcher\EventDispatcherInterface'
- "%overblog_graphql.use_classloader_listener%"
- "%kernel.cache_dir%"
- "%overblog_graphql.cache_dir_permissions%"
Expand Down
15 changes: 14 additions & 1 deletion tests/Generator/TypeGeneratorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
namespace Overblog\GraphQLBundle\Tests\Generator;

use Generator;
use Overblog\GraphQLBundle\Event\SchemaCompiledEvent;
use Overblog\GraphQLBundle\Generator\TypeBuilder;
use PHPUnit\Framework\TestCase;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;

class TypeGeneratorTest extends TestCase
{
Expand All @@ -20,14 +22,25 @@ class TypeGeneratorTest extends TestCase
public function testCacheDirPermissions($expectedMask, $cacheDir, $cacheDirMask): void
{
$typeBuilder = $this->createMock(TypeBuilder::class);
$eventDispatcher = $this->createMock(EventDispatcherInterface::class);

$mask = (new TypeGenerator(
'App', $cacheDir, [], $typeBuilder, true, null, $cacheDirMask
'App', $cacheDir, [], $typeBuilder, $eventDispatcher, true, null, $cacheDirMask
))->getCacheDirMask();

$this->assertSame($expectedMask, $mask);
}

public function testCompiledEvent(): void
{
$typeBuilder = $this->createMock(TypeBuilder::class);
$eventDispatcher = $this->getMockBuilder(EventDispatcherInterface::class)->getMock();

$eventDispatcher->expects($this->once())->method('dispatch')->with($this->equalTo(new SchemaCompiledEvent()));

(new TypeGenerator('App', null, [], $typeBuilder, $eventDispatcher))->compile(TypeGenerator::MODE_DRY_RUN);
}

public function getPermissionsProvider(): Generator
{
// default permission when using default cache dir
Expand Down