-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #111 from php-etl/feature/custom-action
Integration of custom actions
- Loading branch information
Showing
23 changed files
with
818 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Kiboko\Component\Satellite\Action\Custom\Builder; | ||
|
||
use Kiboko\Component\Satellite\Action\SFTP\Builder\ActionBuilderInterface; | ||
use PhpParser\Node; | ||
|
||
final class Action implements ActionBuilderInterface | ||
{ | ||
private ?Node\Expr $logger = null; | ||
private ?Node\Expr $state = null; | ||
|
||
public function __construct(private readonly Node\Expr $service, private readonly string $containerNamespace) | ||
{ | ||
} | ||
|
||
public function withLogger(Node\Expr $logger): self | ||
{ | ||
$this->logger = $logger; | ||
|
||
return $this; | ||
} | ||
|
||
public function withState(Node\Expr $state): self | ||
{ | ||
$this->state = $state; | ||
|
||
return $this; | ||
} | ||
|
||
public function getNode(): Node | ||
{ | ||
return new Node\Expr\MethodCall( | ||
var: new Node\Expr\New_( | ||
class: new Node\Name\FullyQualified($this->containerNamespace) | ||
), | ||
name: new Node\Identifier('get'), | ||
args: [ | ||
new Node\Arg( | ||
$this->service | ||
), | ||
] | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Kiboko\Component\Satellite\Action\Custom; | ||
|
||
use Kiboko\Component\Satellite\DependencyInjection\Configuration\ServicesConfiguration; | ||
use Kiboko\Contract\Configurator\ActionConfigurationInterface; | ||
use Symfony\Component\Config\Definition\Builder\TreeBuilder; | ||
|
||
use function Kiboko\Component\SatelliteToolbox\Configuration\asExpression; | ||
use function Kiboko\Component\SatelliteToolbox\Configuration\isExpression; | ||
|
||
final class Configuration implements ActionConfigurationInterface | ||
{ | ||
public function getConfigTreeBuilder(): TreeBuilder | ||
{ | ||
$builder = new TreeBuilder('custom'); | ||
/* @phpstan-ignore-next-line */ | ||
$builder->getRootNode() | ||
->children() | ||
->arrayNode('expression_language') | ||
->scalarPrototype()->end() | ||
->end() | ||
->append((new ServicesConfiguration())->getConfigTreeBuilder()->getRootNode()) | ||
->scalarNode('use') | ||
->isRequired() | ||
->end() | ||
->arrayNode('parameters') | ||
->useAttributeAsKey('keyparam') | ||
->scalarPrototype() | ||
->cannotBeEmpty() | ||
->validate() | ||
->ifTrue(isExpression()) | ||
->then(asExpression()) | ||
->end() | ||
->end() | ||
->end() | ||
->end() | ||
; | ||
|
||
return $builder; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Kiboko\Component\Satellite\Action\Custom\Factory; | ||
|
||
use Kiboko\Component\Packaging; | ||
use Kiboko\Component\Satellite\Action\Custom; | ||
use Kiboko\Component\Satellite\Action\Custom\Configuration; | ||
use Kiboko\Component\Satellite\DependencyInjection\SatelliteDependencyInjection; | ||
use Kiboko\Component\Satellite\ExpressionLanguage as Satellite; | ||
use Kiboko\Contract\Configurator; | ||
use Symfony\Component\Config\Definition\ConfigurationInterface; | ||
use Symfony\Component\Config\Definition\Exception as Symfony; | ||
use Symfony\Component\Config\Definition\Processor; | ||
use Symfony\Component\DependencyInjection\Dumper\PhpDumper; | ||
use Symfony\Component\ExpressionLanguage\ExpressionLanguage; | ||
use Symfony\Component\String\ByteString; | ||
|
||
use function Kiboko\Component\SatelliteToolbox\Configuration\compileValueWhenExpression; | ||
|
||
class Action implements Configurator\FactoryInterface | ||
{ | ||
private readonly Processor $processor; | ||
private readonly ConfigurationInterface $configuration; | ||
|
||
public function __construct( | ||
private readonly ExpressionLanguage $interpreter = new Satellite\ExpressionLanguage(), | ||
private readonly array $providers = [], | ||
) { | ||
$this->processor = new Processor(); | ||
$this->configuration = new Configuration(); | ||
} | ||
|
||
public function configuration(): ConfigurationInterface | ||
{ | ||
return $this->configuration; | ||
} | ||
|
||
/** | ||
* @throws Configurator\ConfigurationExceptionInterface | ||
*/ | ||
public function normalize(array $config): array | ||
{ | ||
try { | ||
return $this->processor->processConfiguration($this->configuration, $config); | ||
} catch (Symfony\InvalidTypeException|Symfony\InvalidConfigurationException $exception) { | ||
throw new Configurator\InvalidConfigurationException($exception->getMessage(), 0, $exception); | ||
} | ||
} | ||
|
||
public function validate(array $config): bool | ||
{ | ||
try { | ||
$this->processor->processConfiguration($this->configuration, $config); | ||
|
||
return true; | ||
} catch (Symfony\InvalidTypeException|Symfony\InvalidConfigurationException) { | ||
return false; | ||
} | ||
} | ||
|
||
/** | ||
* @throws Configurator\ConfigurationExceptionInterface | ||
*/ | ||
public function compile(array $config): Repository\Action | ||
{ | ||
$containerName = sprintf('ProjectServiceContainer%s', ByteString::fromRandom(8)->toString()); | ||
|
||
$builder = new Custom\Builder\Action( | ||
compileValueWhenExpression($this->interpreter, $config['use']), | ||
sprintf('GyroscopsGenerated\\%s', $containerName), | ||
); | ||
|
||
$container = (new SatelliteDependencyInjection(...$this->providers))($config); | ||
|
||
$repository = new Repository\Action($builder); | ||
|
||
$dumper = new PhpDumper($container); | ||
$repository->addFiles( | ||
new Packaging\File( | ||
sprintf('%s.php', $containerName), | ||
new Packaging\Asset\InMemory( | ||
$dumper->dump(['class' => $containerName, 'namespace' => 'GyroscopsGenerated']) | ||
) | ||
), | ||
); | ||
|
||
return $repository; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Kiboko\Component\Satellite\Action\Custom\Factory\Repository; | ||
|
||
use Kiboko\Component\Satellite\Action\Custom; | ||
use Kiboko\Contract\Configurator; | ||
|
||
final class Action implements Configurator\RepositoryInterface | ||
{ | ||
use RepositoryTrait; | ||
|
||
public function __construct(private readonly Custom\Builder\Action $builder) | ||
{ | ||
$this->files = []; | ||
$this->packages = []; | ||
} | ||
|
||
public function getBuilder(): Custom\Builder\Action | ||
{ | ||
return $this->builder; | ||
} | ||
|
||
public function merge(Configurator\RepositoryInterface $friend): self | ||
{ | ||
array_push($this->files, ...$friend->getFiles()); | ||
array_push($this->packages, ...$friend->getPackages()); | ||
|
||
return $this; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Kiboko\Component\Satellite\Action\Custom\Factory\Repository; | ||
|
||
use Kiboko\Contract\Configurator; | ||
use Kiboko\Contract\Packaging; | ||
|
||
trait RepositoryTrait | ||
{ | ||
/** @var array<Packaging\FileInterface|Packaging\DirectoryInterface> */ | ||
private array $files; | ||
/** @var string[] */ | ||
private array $packages; | ||
|
||
public function addFiles(Packaging\FileInterface|Packaging\DirectoryInterface ...$files): Configurator\RepositoryInterface | ||
{ | ||
array_push($this->files, ...$files); | ||
|
||
return $this; | ||
} | ||
|
||
/** @return iterable<Packaging\FileInterface|Packaging\DirectoryInterface> */ | ||
public function getFiles(): iterable | ||
{ | ||
return $this->files; | ||
} | ||
|
||
public function addPackages(string ...$packages): Configurator\RepositoryInterface | ||
{ | ||
array_push($this->packages, ...$packages); | ||
|
||
return $this; | ||
} | ||
|
||
/** @return iterable<string> */ | ||
public function getPackages(): iterable | ||
{ | ||
return $this->packages; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Kiboko\Component\Satellite\Action\Custom; | ||
|
||
use Kiboko\Component\Satellite\Action\Custom; | ||
use Kiboko\Component\Satellite\ExpressionLanguage as Satellite; | ||
use Kiboko\Contract\Configurator; | ||
use Symfony\Component\Config\Definition\Exception as Symfony; | ||
use Symfony\Component\Config\Definition\Processor; | ||
use Symfony\Component\ExpressionLanguage\ExpressionLanguage; | ||
|
||
#[Configurator\Action( | ||
name: 'custom', | ||
)] | ||
final readonly class Service implements Configurator\ActionInterface | ||
{ | ||
private Processor $processor; | ||
private Configurator\ActionConfigurationInterface $configuration; | ||
|
||
public function __construct( | ||
private ExpressionLanguage $interpreter = new Satellite\ExpressionLanguage() | ||
) { | ||
$this->processor = new Processor(); | ||
$this->configuration = new Custom\Configuration(); | ||
} | ||
|
||
public function interpreter(): ExpressionLanguage | ||
{ | ||
return $this->interpreter; | ||
} | ||
|
||
public function configuration(): Configurator\ActionConfigurationInterface | ||
{ | ||
return $this->configuration; | ||
} | ||
|
||
/** | ||
* @throws Configurator\ConfigurationExceptionInterface | ||
*/ | ||
public function normalize(array $config): array | ||
{ | ||
try { | ||
return $this->processor->processConfiguration($this->configuration, $config); | ||
} catch (Symfony\InvalidTypeException|Symfony\InvalidConfigurationException $exception) { | ||
throw new Configurator\InvalidConfigurationException($exception->getMessage(), 0, $exception); | ||
} | ||
} | ||
|
||
public function validate(array $config): bool | ||
{ | ||
try { | ||
$this->processor->processConfiguration($this->configuration, $config); | ||
|
||
return true; | ||
} catch (Symfony\InvalidTypeException|Symfony\InvalidConfigurationException) { | ||
return false; | ||
} | ||
} | ||
|
||
/** | ||
* @throws Configurator\ConfigurationExceptionInterface | ||
*/ | ||
public function compile(array $config): Configurator\RepositoryInterface | ||
{ | ||
$interpreter = clone $this->interpreter; | ||
|
||
if (\array_key_exists('expression_language', $config) | ||
&& \is_array($config['expression_language']) | ||
&& \count($config['expression_language']) | ||
) { | ||
foreach ($config['expression_language'] as $provider) { | ||
$interpreter->registerProvider(new $provider()); | ||
} | ||
} | ||
|
||
$actionFactory = new Custom\Factory\Action($this->interpreter); | ||
|
||
return $actionFactory->compile($config); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.