Skip to content

Commit

Permalink
Merge pull request #17 from gacela-project/feature/create-command-arg…
Browse files Browse the repository at this point in the history
…uments-parser

Decouple the "maker templates" from the domain
  • Loading branch information
Chemaclass authored Apr 17, 2021
2 parents 13c299d + e415339 commit 146b942
Show file tree
Hide file tree
Showing 17 changed files with 192 additions and 109 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@
/.idea/
/.vscode/
/vendor/
/TestModule/
.phpunit.*
.php_cs.cache
.php_cs.cache
35 changes: 35 additions & 0 deletions src/CodeGenerator/CodeGeneratorConfig.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

declare(strict_types=1);

namespace Gacela\CodeGenerator;

use Gacela\Framework\AbstractConfig;

final class CodeGeneratorConfig extends AbstractConfig
{
public function getFacadeMakerTemplate(): string
{
return $this->getCommandTemplateContent('facade-maker.txt');
}

public function getFactoryMakerTemplate(): string
{
return $this->getCommandTemplateContent('factory-maker.txt');
}

public function getConfigMakerTemplate(): string
{
return $this->getCommandTemplateContent('config-maker.txt');
}

public function getDependencyProviderMakerTemplate(): string
{
return $this->getCommandTemplateContent('dependency-provider-maker.txt');
}

private function getCommandTemplateContent(string $filename): string
{
return file_get_contents(__DIR__ . '/Infrastructure/Template/Command/' . $filename);
}
}
14 changes: 4 additions & 10 deletions src/CodeGenerator/CodeGeneratorFacade.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,17 +48,11 @@ final class CodeGeneratorFacade extends AbstractFacade
*/
public function runCommand(string $commandName, array $arguments = []): void
{
[$rootNamespace, $targetDirectory] = array_pad($arguments, 2, null);
$commandArguments = $this->getFactory()
->createCommandArgumentsParser()
->parse($arguments);

if ($rootNamespace === null) {
throw new InvalidArgumentException('Expected 1st argument to be root-namespace of the project');
}

if ($targetDirectory === null) {
throw new InvalidArgumentException('Expected 2nd argument to be target-directory inside the project');
}

$this->createMaker($commandName)->make($rootNamespace, $targetDirectory);
$this->createMaker($commandName)->make($commandArguments);
}

private function createMaker(string $commandName): MakerInterface
Expand Down
21 changes: 17 additions & 4 deletions src/CodeGenerator/CodeGeneratorFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,14 @@
use Gacela\CodeGenerator\Domain\Command\FacadeMaker;
use Gacela\CodeGenerator\Domain\Command\FactoryMaker;
use Gacela\CodeGenerator\Domain\Command\ModuleMaker;
use Gacela\CodeGenerator\Domain\Io\CommandArgumentsParser;
use Gacela\CodeGenerator\Domain\Io\MakerIoInterface;
use Gacela\CodeGenerator\Infrastructure\Io\SystemMakerIo;
use Gacela\Framework\AbstractFactory;

/**
* @method CodeGeneratorConfig getConfig()
*/
final class CodeGeneratorFactory extends AbstractFactory
{
public function createModuleMaker(): ModuleMaker
Expand All @@ -31,33 +35,42 @@ public function createModuleMaker(): ModuleMaker
public function createFacadeMaker(): FacadeMaker
{
return new FacadeMaker(
$this->createGeneratorIo()
$this->createGeneratorIo(),
$this->getConfig()->getFacadeMakerTemplate()
);
}

public function createFactoryMaker(): FactoryMaker
{
return new FactoryMaker(
$this->createGeneratorIo()
$this->createGeneratorIo(),
$this->getConfig()->getFactoryMakerTemplate()
);
}

public function createConfigMaker(): ConfigMaker
{
return new ConfigMaker(
$this->createGeneratorIo()
$this->createGeneratorIo(),
$this->getConfig()->getConfigMakerTemplate()
);
}

public function createDependencyProviderMaker(): DependencyProviderMaker
{
return new DependencyProviderMaker(
$this->createGeneratorIo()
$this->createGeneratorIo(),
$this->getConfig()->getDependencyProviderMakerTemplate()
);
}

private function createGeneratorIo(): MakerIoInterface
{
return new SystemMakerIo();
}

public function createCommandArgumentsParser(): CommandArgumentsParser
{
return new CommandArgumentsParser();
}
}
25 changes: 17 additions & 8 deletions src/CodeGenerator/Domain/Command/AbstractMaker.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,30 +5,39 @@
namespace Gacela\CodeGenerator\Domain\Command;

use Gacela\CodeGenerator\Domain\Io\MakerIoInterface;
use Gacela\CodeGenerator\Domain\ReadModel\CommandArguments;

abstract class AbstractMaker implements MakerInterface
{
private MakerIoInterface $io;
private string $template;

public function __construct(MakerIoInterface $io)
public function __construct(MakerIoInterface $io, string $template)
{
$this->template = $template;
$this->io = $io;
}

public function make(string $rootNamespace, string $targetDirectory): void
public function make(CommandArguments $commandArguments): void
{
$pieces = explode('/', $targetDirectory);
$pieces = explode('/', $commandArguments->targetDirectory());
$moduleName = end($pieces);

$this->io->createDirectory($targetDirectory);
$this->io->createDirectory($commandArguments->targetDirectory());

$path = sprintf('%s/%s.php', $targetDirectory, $this->className());
$this->io->filePutContents($path, $this->generateFileContent("$rootNamespace\\$moduleName"));
$path = sprintf('%s/%s.php', $commandArguments->targetDirectory(), $this->className());
$this->io->filePutContents($path, $this->generateFileContent("{$commandArguments->rootNamespace()}\\$moduleName"));

$this->io->writeln("> Path '$path' created successfully");
}

abstract protected function generateFileContent(string $namespace): string;

abstract protected function className(): string;

private function generateFileContent(string $namespace): string
{
$search = ['$NAMESPACE$', '$CLASS_NAME$'];
$replace = [$namespace, $this->className()];

return str_replace($search, $replace, $this->template);
}
}
18 changes: 0 additions & 18 deletions src/CodeGenerator/Domain/Command/ConfigMaker.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,6 @@

final class ConfigMaker extends AbstractMaker
{
protected function generateFileContent(string $namespace): string
{
return <<<TEXT
<?php
declare(strict_types=1);
namespace {$namespace};
use Gacela\Framework\AbstractConfig;
final class {$this->className()} extends AbstractConfig
{
}
TEXT;
}

protected function className(): string
{
return 'Config';
Expand Down
22 changes: 0 additions & 22 deletions src/CodeGenerator/Domain/Command/DependencyProviderMaker.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,6 @@

final class DependencyProviderMaker extends AbstractMaker
{
protected function generateFileContent(string $namespace): string
{
return <<<TEXT
<?php
declare(strict_types=1);
namespace {$namespace};
use Gacela\Framework\AbstractDependencyProvider;
use Gacela\Framework\Container\Container;
final class {$this->className()} extends AbstractDependencyProvider
{
public function provideModuleDependencies(Container \$container): void
{
}
}
TEXT;
}

protected function className(): string
{
return 'DependencyProvider';
Expand Down
21 changes: 0 additions & 21 deletions src/CodeGenerator/Domain/Command/FacadeMaker.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,6 @@

final class FacadeMaker extends AbstractMaker
{
protected function generateFileContent(string $namespace): string
{
return <<<TEXT
<?php
declare(strict_types=1);
namespace {$namespace};
use Gacela\Framework\AbstractFacade;
/**
* @method Factory getFactory()
*/
final class {$this->className()} extends AbstractFacade
{
}
TEXT;
}

protected function className(): string
{
return 'Facade';
Expand Down
21 changes: 0 additions & 21 deletions src/CodeGenerator/Domain/Command/FactoryMaker.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,6 @@

final class FactoryMaker extends AbstractMaker
{
protected function generateFileContent(string $namespace): string
{
return <<<TEXT
<?php
declare(strict_types=1);
namespace {$namespace};
use Gacela\Framework\AbstractFactory;
/**
* @method Config getConfig()
*/
final class {$this->className()} extends AbstractFactory
{
}
TEXT;
}

protected function className(): string
{
return 'Factory';
Expand Down
4 changes: 3 additions & 1 deletion src/CodeGenerator/Domain/Command/MakerInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@

namespace Gacela\CodeGenerator\Domain\Command;

use Gacela\CodeGenerator\Domain\ReadModel\CommandArguments;

interface MakerInterface
{
public function make(string $rootNamespace, string $targetDirectory): void;
public function make(CommandArguments $commandArguments): void;
}
7 changes: 4 additions & 3 deletions src/CodeGenerator/Domain/Command/ModuleMaker.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace Gacela\CodeGenerator\Domain\Command;

use Gacela\CodeGenerator\Domain\Io\MakerIoInterface;
use Gacela\CodeGenerator\Domain\ReadModel\CommandArguments;

final class ModuleMaker implements MakerInterface
{
Expand All @@ -22,13 +23,13 @@ public function __construct(MakerIoInterface $io, array $generators)
$this->generators = $generators;
}

public function make(string $rootNamespace, string $targetDirectory): void
public function make(CommandArguments $commandArguments): void
{
foreach ($this->generators as $generator) {
$generator->make($rootNamespace, $targetDirectory);
$generator->make($commandArguments);
}

$pieces = explode('/', $targetDirectory);
$pieces = explode('/', $commandArguments->targetDirectory());
$moduleName = end($pieces);
$this->io->writeln("Module $moduleName created successfully");
}
Expand Down
29 changes: 29 additions & 0 deletions src/CodeGenerator/Domain/Io/CommandArgumentsParser.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

declare(strict_types=1);

namespace Gacela\CodeGenerator\Domain\Io;

use Gacela\CodeGenerator\Domain\ReadModel\CommandArguments;
use InvalidArgumentException;

final class CommandArgumentsParser
{
/**
* @throws InvalidArgumentException
*/
public function parse(array $arguments): CommandArguments
{
[$rootNamespace, $targetDirectory] = array_pad($arguments, 2, null);

if ($rootNamespace === null) {
throw new InvalidArgumentException('Expected 1st argument to be root-namespace of the project');
}

if ($targetDirectory === null) {
throw new InvalidArgumentException('Expected 2nd argument to be target-directory inside the project');
}

return new CommandArguments($rootNamespace, $targetDirectory);
}
}
27 changes: 27 additions & 0 deletions src/CodeGenerator/Domain/ReadModel/CommandArguments.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

declare(strict_types=1);

namespace Gacela\CodeGenerator\Domain\ReadModel;

final class CommandArguments
{
private string $rootNamespace;
private string $targetDirectory;

public function __construct(string $rootNamespace, string $targetDirectory)
{
$this->rootNamespace = $rootNamespace;
$this->targetDirectory = $targetDirectory;
}

public function rootNamespace(): string
{
return $this->rootNamespace;
}

public function targetDirectory(): string
{
return $this->targetDirectory;
}
}
11 changes: 11 additions & 0 deletions src/CodeGenerator/Infrastructure/Template/Command/config-maker.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

declare(strict_types=1);

namespace $NAMESPACE$;

use Gacela\Framework\AbstractConfig;

final class $CLASS_NAME$ extends AbstractConfig
{
}
Loading

0 comments on commit 146b942

Please sign in to comment.