Skip to content
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

feature/MD/XL-8682 repository generator #16

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
4164bd9
add repository generator
mderis Aug 31, 2024
5a02a77
add `HasTest` trait
mderis Aug 31, 2024
fc6005b
add logic to `Repository Generator` class
mderis Aug 31, 2024
a66d7ba
style: apply automated php-cs-fixer changes
mderis Aug 31, 2024
105ac5c
add `Model Generator`
mderis Sep 1, 2024
c967d40
fix: hint when asking for test
mderis Sep 1, 2024
1abaf2d
style: apply automated php-cs-fixer changes
mderis Sep 1, 2024
f39a782
add `Request Generator`
mderis Sep 1, 2024
c29b4d4
add `HasTest` trait
mderis Sep 1, 2024
376a76c
add logic to `Request Generator` class
mderis Sep 1, 2024
a26b8ec
style: apply automated php-cs-fixer changes
mderis Sep 1, 2024
3eac648
add `Transformer Generator`
mderis Sep 2, 2024
c8fc874
add logic to `Transformer Generator` class
mderis Sep 2, 2024
b4bee8e
style: apply automated php-cs-fixer changes
mderis Sep 2, 2024
4e53649
add `Policy Generator` class
mderis Sep 2, 2024
1db421a
add a package to be able to read the php class file: `nikic/php-parser`
mderis Sep 3, 2024
d6d035d
add ability to replace a file
mderis Sep 3, 2024
2b14af7
add logic to `Policy Generator` class
mderis Sep 3, 2024
02c9671
style: apply automated php-cs-fixer changes
mderis Sep 3, 2024
f752c7d
add `Route Generator` class
mderis Sep 4, 2024
67d6a3d
fix an import
mderis Sep 4, 2024
ad00915
improve `SuggestionHelper` trait
mderis Sep 4, 2024
a224f92
add `WEB` testcase
mderis Sep 4, 2024
d28ba5a
add logic to `Route Generator` class
mderis Sep 4, 2024
ab98a5d
style: apply automated php-cs-fixer changes
mderis Sep 4, 2024
8f3735c
add `Endpoint Generator` class
mderis Sep 4, 2024
c5e5d9f
add a comment
mderis Sep 8, 2024
807cf7e
add logic to `Endpoint Generator` class
mderis Sep 8, 2024
ce10fce
add `Exception Generator` class
mderis Sep 8, 2024
d304c56
add logic to `Exception Generator` class
mderis Sep 8, 2024
1746b07
add `Notification Generator` class
mderis Sep 8, 2024
5eb37e5
add logic to `Notification Generator` class
mderis Sep 8, 2024
40f5cc3
style: apply automated php-cs-fixer changes
mderis Sep 8, 2024
384bcfd
add `Job Generator` class
mderis Sep 8, 2024
55e42d6
add logic to `Job Generator` class
mderis Sep 8, 2024
1285d0a
add `Event Listener Generator` class
mderis Sep 11, 2024
0b4d9f7
add logic to `Event Listener Generator` class
mderis Sep 11, 2024
9868a7a
modify some variables
mderis Sep 11, 2024
4954144
Merge branch 'feature/MD/XL-9088-job-generator' into feature/MD/XL-90…
mderis Sep 11, 2024
03ea696
add `Criteria Generator` class
mderis Sep 11, 2024
868d18b
fix an import
mderis Sep 11, 2024
8818c86
add logic to `Criteria Generator` class
mderis Sep 11, 2024
8d6f2f2
style: apply automated php-cs-fixer changes
mderis Sep 11, 2024
3e30a40
fix composer syntax
mderis Sep 11, 2024
d8eaa92
Merge branch 'feature/MD/XL-8671-criteria-generator' of https://githu…
mderis Sep 11, 2024
0b6d4b7
fix: update composer.lock
yalsicor Sep 15, 2024
ac43954
fix: update composer.lock
yalsicor Sep 15, 2024
f58a405
Merge pull request #27 from openforests-git/feature/MD/XL-8671-criter…
yalsicor Sep 17, 2024
1fbd007
Merge pull request #26 from openforests-git/feature/MD/XL-9086-event-…
yalsicor Sep 17, 2024
3ebfe0b
Merge pull request #25 from openforests-git/feature/MD/XL-9088-job-ge…
yalsicor Sep 17, 2024
25df365
Merge pull request #24 from openforests-git/feature/MD/XL-9091-notifi…
yalsicor Sep 17, 2024
1464300
Merge pull request #23 from openforests-git/feature/MD/XL-9087-except…
yalsicor Sep 17, 2024
eb25c79
Merge pull request #22 from openforests-git/feature/MD/XL-8685-endpoi…
yalsicor Sep 17, 2024
098d893
Merge pull request #21 from openforests-git/feature/MD/XL-8674-route-…
yalsicor Sep 17, 2024
17d6b51
Merge pull request #20 from openforests-git/feature/MD/XL-8683-policy…
yalsicor Sep 17, 2024
d62aba6
Merge pull request #19 from openforests-git/feature/MD/XL-8678-transf…
yalsicor Sep 17, 2024
1fd60b7
Merge pull request #18 from openforests-git/feature/MD/XL-8675-reques…
yalsicor Sep 17, 2024
099c582
Merge pull request #17 from openforests-git/feature/MD/XL-8681-model-…
yalsicor Sep 17, 2024
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 composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@
"laravel/framework": "^10.0",
"laravel/passport": "^11.0.0",
"nette/php-generator": "^4.1",
"ext-gettext": "*"
"ext-gettext": "*",
"nikic/php-parser": "^4.19"
},
"require-dev": {
"fakerphp/faker": "^1.19.1",
Expand Down
1,767 changes: 938 additions & 829 deletions composer.lock

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions src/Generator/Commands/ControllerGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ protected function askCustomInputs(): void
param: 'stub',
label: 'Select the controller type:',
options: [
// add generic
'list' => 'List',
'find' => 'Find',
'create' => 'Create',
Expand Down
104 changes: 104 additions & 0 deletions src/Generator/Commands/CriteriaGenerator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
<?php

namespace Apiato\Core\Generator\Commands;

use Apiato\Core\Generator\FileGeneratorCommand;
use Apiato\Core\Generator\Traits\HasTestTrait;

class CriteriaGenerator extends FileGeneratorCommand
{
use HasTestTrait;

public static function getCommandName(): string
{
return 'apiato:make:criteria';
}

public static function getCommandDescription(): string
{
return 'Create a Criteria file for a Container';
}

public static function getFileType(): string
{
return 'criteria';
}

protected static function getCustomCommandArguments(): array
{
return [
];
}

public function askCustomInputs(): void
{
}

protected function getFilePath(): string
{
return "$this->sectionName/$this->containerName/Data/Criterias/$this->fileName.php";
}

protected function getFileContent(): string
{
$file = new \Nette\PhpGenerator\PhpFile();
$namespace = $file->addNamespace('App\Containers\\' . $this->sectionName . '\\' . $this->containerName . '\Data\Criterias');

// imports
$parentCriteriaFullPath = 'App\Ship\Parents\Criterias\Criteria';
$namespace->addUse($parentCriteriaFullPath, 'ParentCriteria');
$repositoryInterface = 'Prettus\Repository\Contracts\RepositoryInterface';
$namespace->addUse($repositoryInterface);

// class
$class = $file->addNamespace($namespace)
->addClass($this->fileName)
->setExtends($parentCriteriaFullPath);

// apply method
$applyMethod = $class->addMethod('apply')
->setPublic()
->setReturnType('mixed')
->setBody('return $model;');
$applyMethod->addParameter('model');
$applyMethod->addParameter('repository')->setType($repositoryInterface);

// return the file
return $file;
}

protected function getTestPath(): string
{
return $this->sectionName . '/' . $this->containerName . '/Tests/Unit/Data/Criterias/' . $this->fileName . 'Test.php';
}

protected function getTestContent(): string
{
$file = new \Nette\PhpGenerator\PhpFile();
$namespace = $file->addNamespace('App\Containers\\' . $this->sectionName . '\\' . $this->containerName . '\Tests\Unit\Data\Criterias');

// imports
$parentUnitTestCaseFullPath = "App\Containers\AppSection\\$this->containerName\Tests\UnitTestCase";
$namespace->addUse($parentUnitTestCaseFullPath);
$criteriaFullPath = 'App\Containers\\' . $this->sectionName . '\\' . $this->containerName . '\Data\Criterias\\' . $this->fileName;
$namespace->addUse($criteriaFullPath);

// class
$class = $file->addNamespace($namespace)
->addClass($this->fileName . 'Test')
->setFinal()
->setExtends($parentUnitTestCaseFullPath);

$testMethod = $class->addMethod('testCriteria')->setPublic();
$testMethod->addBody("
\$criteria = app($this->fileName::class);

// Remove the following lines and add your logic and assertions
\$this->assertInstanceOf($this->fileName::class, \$criteria);
");
$testMethod->setReturnType('void');

// return the file
return $file;
}
}
119 changes: 119 additions & 0 deletions src/Generator/Commands/EndpointGenerator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
<?php

namespace Apiato\Core\Generator\Commands;

use Apiato\Core\Generator\CompositeGeneratorCommand;
use Symfony\Component\Console\Input\InputOption;

class EndpointGenerator extends CompositeGeneratorCommand
{
protected string $feature;
protected string $model;
protected string $ui;
protected string $stub;

public static function getCommandName(): string
{
return 'apiato:make:endpoint';
}

public static function getCommandDescription(): string
{
return 'Create an Endpoint for a Container';
}

protected static function getCustomCommandArguments(): array
{
return [
['feature', null, InputOption::VALUE_OPTIONAL, 'The feature name of the endpoint. (E.g. CreateUser, LinkPostToBlog, DeleteAllPosts, ...)'],
['model', null, InputOption::VALUE_OPTIONAL, 'The model this endpoint is for.'],
['ui', null, InputOption::VALUE_OPTIONAL, 'The UI of the endpoint. (API, WEB)'],
['stub', null, InputOption::VALUE_OPTIONAL, 'The stub file to load for this endpoint.'],
];
}

protected function askCustomInputs(): void
{
$this->feature = $this->checkParameterOrAskText(
param: 'feature',
label: 'Enter the feature name:',
hint: 'E.g. CreateUser, LinkPostToBlog, DeleteAllPosts, ...',
);
$this->model = $this->checkParameterOrAskTextSuggested(
param: 'model',
label: 'Enter the name of the Model:',
default: $this->containerName,
suggestions: $this->getModelsList(
section: $this->sectionName,
container: $this->containerName,
removeModelPostFix: true,
),
);
$this->ui = $this->checkParameterOrSelect(
param: 'ui',
label: 'Select the UI of the endpoint:',
options: ['API', 'WEB'],
default: 'API',
);
$this->stub = $this->checkParameterOrSelect(
param: 'stub',
label: 'Select the endpoint type:',
options: [
'generic' => 'Generic',
'list' => 'List',
'find' => 'Find',
'create' => 'Create',
'update' => 'Update',
'delete' => 'Delete',
],
default: 'find',
hint: 'Different types of endpoints have different default behaviors.',
);
}

protected function runGeneratorCommands(): void
{
$featureCamelCase = lcfirst($this->feature);
$featurePascalCase = ucfirst($this->feature);

$this->runGeneratorCommand(RouteGenerator::class, [
'--section' => $this->sectionName,
'--container' => $this->containerName,
'--file' => $featurePascalCase,
'--ui' => $this->ui,
'--controller' => $featurePascalCase . 'Controller',
'--test' => $this->test,
]);
$this->runGeneratorCommand(ActionGenerator::class, [
'--section' => $this->sectionName,
'--container' => $this->containerName,
'--file' => $featurePascalCase . 'Action',
'--model' => $this->model,
'--stub' => $this->stub,
'--ui' => $this->ui,
'--test' => $this->test,
]);
$this->runGeneratorCommand(ControllerGenerator::class, [
'--section' => $this->sectionName,
'--container' => $this->containerName,
'--file' => $featurePascalCase . 'Controller',
'--stub' => $this->stub,
'--test' => $this->test,
]);
$this->runGeneratorCommand(RequestGenerator::class, [
'--section' => $this->sectionName,
'--container' => $this->containerName,
'--file' => $featurePascalCase . 'Request',
'--model' => $this->model,
'--stub' => $this->stub,
'--test' => $this->test,
]);
$this->runGeneratorCommand(PolicyGenerator::class, [
'--section' => $this->sectionName,
'--container' => $this->containerName,
'--file' => $this->model . 'Policy',
'--method' => $featureCamelCase,
'--test' => $this->test,
]);
}
}
70 changes: 70 additions & 0 deletions src/Generator/Commands/EventListenerGenerator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<?php

namespace Apiato\Core\Generator\Commands;

use Apiato\Core\Generator\FileGeneratorCommand;

// TODO: Make this command receive the event name as an argument
// when `EventGenerator` is implemented
class EventListenerGenerator extends FileGeneratorCommand
{
public static function getCommandName(): string
{
return 'apiato:make:listener';
}

public static function getCommandDescription(): string
{
return 'Create an Event Listener for a Container';
}

public static function getFileType(): string
{
return 'listener';
}

protected static function getCustomCommandArguments(): array
{
return [
];
}

protected function askCustomInputs(): void
{
}

protected function getFilePath(): string
{
return "$this->sectionName/$this->containerName/Listeners/$this->fileName.php";
}

protected function getFileContent(): string
{
$file = new \Nette\PhpGenerator\PhpFile();
$namespace = $file->addNamespace('App\Containers\\' . $this->sectionName . '\\' . $this->containerName . '\Listeners');

// imports
$parentJobFullPath = 'App\Ship\Parents\Listeners\Listener';
$namespace->addUse($parentJobFullPath, 'ParentListener');
$shouldQueueFullPath = 'Illuminate\Contracts\Queue\ShouldQueue';
$namespace->addUse($shouldQueueFullPath);

// class
$class = $file->addNamespace($namespace)
->addClass($this->fileName)
->setExtends($parentJobFullPath)
->addImplement($shouldQueueFullPath);

// constructor method
$constructorMethod = $class->addMethod('__construct')
->setPublic();

// handle method
$handleMethod = $class->addMethod('handle')
->setPublic()
->setReturnType('void')
->addParameter('event');

return $file;
}
}
67 changes: 67 additions & 0 deletions src/Generator/Commands/ExceptionGenerator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?php

namespace Apiato\Core\Generator\Commands;

use Apiato\Core\Generator\FileGeneratorCommand;
use Symfony\Component\HttpFoundation\Response;

class ExceptionGenerator extends FileGeneratorCommand
{
public static function getCommandName(): string
{
return 'apiato:make:exception';
}

public static function getCommandDescription(): string
{
return 'Create an Exception for a Container';
}

public static function getFileType(): string
{
return 'exception';
}

protected static function getCustomCommandArguments(): array
{
return [
];
}

protected function askCustomInputs(): void
{
}

protected function getFilePath(): string
{
return "$this->sectionName/$this->containerName/Exceptions/$this->fileName.php";
}

protected function getFileContent(): string
{
$file = new \Nette\PhpGenerator\PhpFile();
$namespace = $file->addNamespace('App\Containers\\' . $this->sectionName . '\\' . $this->containerName . '\Exceptions');

// imports
$parentExceptionFullPath = 'App\Ship\Parents\Exceptions\Exception';
$namespace->addUse($parentExceptionFullPath, 'ParentException');
$responseFullPath = 'Symfony\Component\HttpFoundation\Response';
$namespace->addUse($responseFullPath);

// class
$class = $file->addNamespace($namespace)
->addClass($this->fileName)
->setExtends($parentExceptionFullPath);

// properties
$class->addProperty('code')
->setVisibility('protected')
->setValue(Response::HTTP_BAD_REQUEST); // TODO: find a way to initialize it with `Response::HTTP_BAD_REQUEST` not 400

$class->addProperty('message')
->setVisibility('protected')
->setValue('Exception Default Message.');

return $file;
}
}
Loading
Loading