Skip to content

Commit 35c664c

Browse files
committed
WIP
Signed-off-by: alexmerlin <alex.merlin.1985@gmail.com>
1 parent a074315 commit 35c664c

34 files changed

Lines changed: 265 additions & 180 deletions

README.md

Lines changed: 88 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -15,55 +15,104 @@ Dotkernel library for programmatically generating structured code files.
1515
Run the following command in your terminal:
1616

1717
```shell
18-
compose require-dev dotkernel/dot-maker
18+
composer require-dev dotkernel/dot-maker
1919
```
2020

2121
## Setup
2222

23-
TODO: document stub publishing and (optional) config creation
23+
Once installed, `dot-maker` is ready for usage, no need for extra configurations.
24+
25+
### (Optional) Add `dot-maker` to composer.json
26+
27+
Open `composer.json` and locate the `scripts` section.
28+
If it does not exist, create it at the document's root level.
29+
30+
Register a new script by appending `"alias": "dot-maker"` to the `scripts` section, where **alias** can be any string you want; like, for example **make**.
31+
32+
```json
33+
{
34+
"scripts": {
35+
"make": "dot-maker"
36+
}
37+
}
38+
```
2439

2540
## Usage
2641

42+
Invoke `dot-maker` by executing:
43+
44+
- the bin file in your vendor directory, located at `./vendor/bin/dot-maker <component>`
45+
- the (optional) Composer script created at [Setup](#setup): `composer make <component>`
46+
47+
where `<component>` is one of the following strings:
48+
49+
- `collection`: Creates a resource Collection (API only)
50+
- `command`: Creates a CLI Command
51+
- `entity`: Creates a Doctrine Entity and the matching Repository
52+
- `form`: Creates a Laminas Form and the matching InputFilter
53+
- `handler`: Creates the specified request Handlers (and additional files, based on the project type)
54+
- `input-filter`: Creates an InputFilter
55+
- `middleware`: Creates a Middleware
56+
- `module`: Creates an entire Module
57+
- `repository`: Creates a Doctrine Repository and the matching Entity
58+
- `service`: Creates a Service and the matching ServiceInterface
59+
60+
### Create Collection
61+
62+
```shell
63+
./vendor/bin/dot-maker collection
64+
```
65+
66+
### Create Command
67+
68+
```shell
69+
./vendor/bin/dot-maker command
70+
```
71+
72+
### Create Entity + Repository
73+
74+
```shell
75+
./vendor/bin/dot-maker entity
76+
```
77+
78+
### Create Form
79+
80+
```shell
81+
./vendor/bin/dot-maker form
82+
```
83+
84+
### Create Handler
85+
86+
```shell
87+
./vendor/bin/dot-maker handler
88+
```
89+
90+
### Create InputFilter
91+
92+
```shell
93+
./vendor/bin/dot-maker input-filter
94+
```
95+
96+
### Create Middleware
97+
98+
```shell
99+
./vendor/bin/dot-maker middleware
100+
```
101+
27102
### Create Module
28103

29104
```shell
30105
./vendor/bin/dot-maker module
31106
```
32107

33-
TODO: add documentation for all commands that create types defined in src/Type/TypeEnum.php
34-
35-
Dependency tree:
36-
37-
- Module
38-
- *
39-
- Collection (API only)
40-
- Command
41-
- Service
42-
- ConfigProvider
43-
- Handler
44-
- Service
45-
- Entity
46-
- Entity
47-
- Repository
48-
- Form
49-
- InputFilter
50-
- Input
51-
- Handler
52-
- Form
53-
- Service
54-
- config
55-
- Input (just the directory?)
56-
- InputFilter
57-
- InputFilter
58-
- Middleware
59-
- Service
60-
- Repository
61-
- Entity
62-
- RoutesDelegator
63-
- Handler
64-
- Service
65-
- Repository
66-
- config
67-
- ServiceInterface
68-
- Service
69-
- test (?)
108+
### Create Repository + Entity
109+
110+
```shell
111+
./vendor/bin/dot-maker repository
112+
```
113+
114+
### Create Service + ServiceInterface
115+
116+
```shell
117+
./vendor/bin/dot-maker service
118+
```

phpcs.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,10 @@
1717

1818
<!-- Include all rules from the Laminas Coding Standard -->
1919
<rule ref="LaminasCodingStandard"/>
20+
<rule ref="Generic.Files.LineLength.TooLong">
21+
<exclude-pattern>src/Component/Import.php</exclude-pattern>
22+
</rule>
23+
<rule ref="Generic.Formatting.MultipleStatementAlignment.Incorrect">
24+
<exclude-pattern>src/Component/Import.php</exclude-pattern>
25+
</rule>
2026
</ruleset>

src/Component/Import.php

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010

1111
class Import
1212
{
13-
// phpcs:disable Generic.Files.LineLength.TooLong
1413
public const DATETIMEIMMUTABLE = 'DateTimeImmutable';
1514
public const DOCTRINE_ORM_MAPPING = 'Doctrine\\ORM\\Mapping';
1615
public const DOCTRINE_ORM_MAPPING_DRIVER_ATTRIBUTEDRIVER = 'Doctrine\\ORM\\Mapping\\Driver\\AttributeDriver';
@@ -69,7 +68,6 @@ class Import
6968
public const SYMFONY_COMPONENT_CONSOLE_OUTPUT_OUTPUTINTERFACE = 'Symfony\\Component\\Console\\Output\\OutputInterface';
7069
public const SYMFONY_COMPONENT_CONSOLE_STYLE_SYMFONYSTYLE = 'Symfony\\Component\\Console\\Style\\SymfonyStyle';
7170
public const THROWABLE = 'Throwable';
72-
// phpcs:enable Generic.Files.LineLength.TooLong
7371

7472
public function __construct(
7573
private ContextInterface $context,

src/FileSystem.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -400,7 +400,9 @@ public function routesDelegator(string $name = 'RoutesDelegator'): File
400400

401401
public function service(string $name): File
402402
{
403-
$name = preg_replace('/Service$/', '', $name);
403+
if ($name !== 'Service') {
404+
$name = preg_replace('/Service$/', '', $name);
405+
}
404406

405407
return new File(
406408
new Directory('Service', sprintf('%s/src/%s/src', $this->rootDir, $this->moduleName)),
@@ -411,7 +413,10 @@ public function service(string $name): File
411413

412414
public function serviceInterface(string $name): File
413415
{
414-
$name = preg_replace('/ServiceInterface$/', '', $name);
416+
$name = preg_replace('/Interface$/', '', $name);
417+
if ($name !== 'Service') {
418+
$name = preg_replace('/Service$/', '', $name);
419+
}
415420

416421
return new File(
417422
new Directory('Service', sprintf('%s/src/%s/src', $this->rootDir, $this->moduleName)),

src/IO/Output.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,29 +21,29 @@ public static function error(string $message, bool $exit = false): void
2121
{
2222
$message = ColorEnum::colorize($message, ColorEnum::ForegroundBrightRed);
2323

24-
fwrite(STDERR, $message . PHP_EOL);
24+
fwrite(STDERR, '' . $message . PHP_EOL);
2525
$exit && exit(self::FAILURE);
2626
}
2727

2828
public static function info(string $message, bool $exit = false): void
2929
{
3030
$message = ColorEnum::colorize($message, ColorEnum::ForegroundBrightBlue);
3131

32-
fwrite(STDOUT, $message . PHP_EOL);
32+
fwrite(STDOUT, 'ℹ️ ' . $message . PHP_EOL);
3333
$exit && exit(self::SUCCESS);
3434
}
3535

3636
public static function success(string $message, bool $exit = false): void
3737
{
3838
$message = ColorEnum::colorize($message, ColorEnum::ForegroundBrightGreen);
3939

40-
fwrite(STDOUT, $message . PHP_EOL);
40+
fwrite(STDOUT, '' . $message . PHP_EOL);
4141
$exit && exit(self::SUCCESS);
4242
}
4343

4444
public static function write(string $message, bool $exit = false): void
4545
{
46-
fwrite(STDOUT, $message . PHP_EOL);
46+
fwrite(STDOUT, $message);
4747
$exit && exit(self::SUCCESS);
4848
}
4949

src/Maker.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ public function __invoke(array $arguments): int
5151
$instance = new ($component)($fileSystem, $context, $config);
5252
assert($instance instanceof TypeInterface);
5353

54+
Output::info(sprintf('Detected project type: %s', $context->getProjectType()));
55+
5456
if (! $instance->isModule()) {
5557
$instance->setModule((new Module($fileSystem, $context, $config))->initExisting());
5658
} else {

src/Type/Collection.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ class Collection extends AbstractType implements FileInterface
2222
public function __invoke(): void
2323
{
2424
if (! $this->context->isApi()) {
25+
Output::error('Collections can be created only in an API');
2526
return;
2627
}
2728

src/Type/Command.php

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ public function create(string $name): File
6565

6666
$content = $this->render(
6767
$command->getComponent(),
68-
$this->fileSystem->serviceInterface($this->fileSystem->getModuleName())->getComponent(),
68+
$this->fileSystem->serviceInterface($this->fileSystem->getModuleName()),
6969
);
7070

7171
$command->create($content);
@@ -75,7 +75,7 @@ public function create(string $name): File
7575
return $command;
7676
}
7777

78-
public function render(Component $command, Component $serviceInterface): string
78+
public function render(Component $command, File $serviceInterface): string
7979
{
8080
$defaultName = $this->getDefaultName($command);
8181

@@ -86,8 +86,6 @@ public function render(Component $command, Component $serviceInterface): string
8686
->useClass(Import::SYMFONY_COMPONENT_CONSOLE_INPUT_INPUTINTERFACE)
8787
->useClass(Import::SYMFONY_COMPONENT_CONSOLE_OUTPUT_OUTPUTINTERFACE)
8888
->useClass(Import::SYMFONY_COMPONENT_CONSOLE_STYLE_SYMFONYSTYLE)
89-
->useClass(Import::DOT_DEPENDENCYINJECTION_ATTRIBUTE_INJECT)
90-
->useClass($serviceInterface->getFqcn())
9189
->addInject(
9290
(new Inject('AsCommand'))
9391
->addArgument(self::wrap($defaultName), 'name')
@@ -101,11 +99,18 @@ public function render(Component $command, Component $serviceInterface): string
10199
);
102100

103101
$constructor = (new Constructor())
104-
->setBody(' parent::__construct(self::$defaultName);')
105-
->addInject(
106-
(new Inject())->addArgument($serviceInterface->getClassString())
107-
)
108-
->addPromotedPropertyFromComponent($serviceInterface);
102+
->setBody(' parent::__construct(self::$defaultName);');
103+
if ($serviceInterface->exists()) {
104+
$class
105+
->useClass(Import::DOT_DEPENDENCYINJECTION_ATTRIBUTE_INJECT)
106+
->useClass($serviceInterface->getComponent()->getFqcn());
107+
108+
$constructor
109+
->addInject(
110+
(new Inject())->addArgument($serviceInterface->getComponent()->getClassString())
111+
)
112+
->addPromotedPropertyFromComponent($serviceInterface->getComponent());
113+
}
109114
$class->addMethod($constructor);
110115

111116
$configure = (new Method('configure'))

0 commit comments

Comments
 (0)