Skip to content

Commit 844c07e

Browse files
Refactor of DocBlock fuctionality (#8)
* Refactor for ide-helper * Allows #[Ignore] on methods * Adds a collect() helper to DTOs
1 parent 009d81d commit 844c07e

21 files changed

+1598
-439
lines changed

.github/workflows/build.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ jobs:
1818
- name: Setup PHP
1919
uses: shivammathur/setup-php@v2
2020
with:
21-
php-version: '8.2'
21+
php-version: '8.3'
2222
extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite, bcmath, soap, intl, gd, exif, iconv
2323

2424
- name: Cache Composer dependencies
@@ -44,7 +44,7 @@ jobs:
4444
- name: Setup PHP
4545
uses: shivammathur/setup-php@v2
4646
with:
47-
php-version: '8.2'
47+
php-version: '8.3'
4848
extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite, bcmath, soap, intl, gd, exif, iconv
4949

5050
- name: Cache Composer dependencies
@@ -70,7 +70,7 @@ jobs:
7070
- name: Setup PHP
7171
uses: shivammathur/setup-php@v2
7272
with:
73-
php-version: '8.2'
73+
php-version: '8.3'
7474
extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite, bcmath, soap, intl, gd, exif, iconv
7575

7676
- name: Cache Composer dependencies
@@ -96,7 +96,7 @@ jobs:
9696
- name: Setup PHP
9797
uses: shivammathur/setup-php@v2
9898
with:
99-
php-version: '8.2'
99+
php-version: '8.3'
100100
extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite, bcmath, soap, intl, gd, exif, iconv, xdebug
101101
coverage: xdebug
102102

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
},
2626
"autoload-dev": {
2727
"psr-4": {
28+
"App\\": "vendor/orchestra/testbench-core/laravel/app",
2829
"LumoSolutions\\Actionable\\Tests\\": "tests/"
2930
}
3031
},
@@ -37,7 +38,7 @@
3738
"format": "vendor/bin/pint"
3839
},
3940
"require": {
40-
"php": ">=8.2"
41+
"php": ">=8.3"
4142
},
4243
"require-dev": {
4344
"larastan/larastan": "^2.9||^3.0",
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
<?php
2+
3+
namespace LumoSolutions\Actionable\Actions\Console;
4+
5+
use Exception;
6+
use Illuminate\Support\Facades\File;
7+
use LumoSolutions\Actionable\Actions\Generation\GenerateDocBlocks;
8+
use LumoSolutions\Actionable\Actions\Generation\UpdateClassDocBlock;
9+
use LumoSolutions\Actionable\Dtos\Generation\DocBlockGenDto;
10+
use LumoSolutions\Actionable\Dtos\Generation\DocBlockUpdateDto;
11+
use LumoSolutions\Actionable\Support\ClassAnalyser;
12+
use LumoSolutions\Actionable\Support\DocBlockHelper;
13+
use LumoSolutions\Actionable\Traits\IsRunnable;
14+
15+
class UpdateActionDocBlocks
16+
{
17+
use IsRunnable;
18+
19+
public function __construct(
20+
protected ClassAnalyser $classAnalyser
21+
) {}
22+
23+
public function handle(string $namespace = '\\App', bool $dryRun = false): array
24+
{
25+
$namespace = ltrim($namespace, '\\');
26+
$classes = $this->findClassesInNamespace($namespace);
27+
$results = [];
28+
29+
foreach ($classes as $className) {
30+
try {
31+
$diff = $this->processClass($className, $dryRun);
32+
33+
if (! empty($diff)) {
34+
$results[$className] = $diff;
35+
}
36+
} catch (Exception $e) {
37+
continue;
38+
}
39+
}
40+
41+
return $results;
42+
}
43+
44+
public function findClassesInNamespace(string $namespace): array
45+
{
46+
$classes = [];
47+
$namespacePath = str_replace('\\', '/', $namespace);
48+
49+
$searchPaths = [];
50+
if (str_starts_with($namespace, 'App')) {
51+
$relativePath = str_replace('App', '', $namespacePath);
52+
$relativePath = ltrim($relativePath, '/');
53+
$searchPaths[] = app_path($relativePath);
54+
}
55+
56+
$searchPaths[] = base_path('src/'.$namespacePath);
57+
$searchPaths[] = base_path($namespacePath);
58+
59+
foreach ($searchPaths as $path) {
60+
if (! is_dir($path)) {
61+
continue;
62+
}
63+
64+
$files = File::allFiles($path);
65+
foreach ($files as $file) {
66+
if ($file->getExtension() !== 'php') {
67+
continue;
68+
}
69+
70+
$relativePath = $file->getRelativePathname();
71+
$relativePath = str_replace(['/', '.php'], ['\\', ''], $relativePath);
72+
$classes[] = $namespace.$relativePath;
73+
}
74+
}
75+
76+
return array_unique($classes);
77+
}
78+
79+
public function processClass(string $className, bool $dryRun): array|bool
80+
{
81+
// Analyze the class
82+
$data = rescue(
83+
fn () => $this->classAnalyser->analyse($className),
84+
fn ($e) => null,
85+
false
86+
);
87+
88+
if ($data == null) {
89+
return false;
90+
}
91+
92+
$actionableTraits = collect($data->traits)
93+
->filter(fn ($trait) => $trait->namespace === 'LumoSolutions\\Actionable\\Traits');
94+
95+
if ($actionableTraits->isEmpty()) {
96+
return $dryRun ? [] : false;
97+
}
98+
99+
$currentDocBlocks = ! empty($data->docBlock)
100+
? DocBlockHelper::extract($data->docBlock)
101+
: [];
102+
103+
$newBlocks = GenerateDocBlocks::run(
104+
new DocBlockGenDto(
105+
isRunnable: (bool) $actionableTraits->firstWhere('name', 'IsRunnable'),
106+
isDispatchable: (bool) $actionableTraits->firstWhere('name', 'IsDispatchable'),
107+
handle: collect($data->methods)->firstWhere('name', 'handle'),
108+
docBlocks: $currentDocBlocks,
109+
usings: $data->includes ?? []
110+
)
111+
);
112+
113+
return UpdateClassDocBlock::run(
114+
new DocBlockUpdateDto(
115+
filePath: $data->filePath,
116+
className: $data->className,
117+
currentDocBlocks: $currentDocBlocks,
118+
newDocBlocks: $newBlocks
119+
),
120+
$dryRun
121+
);
122+
}
123+
}
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
<?php
2+
3+
namespace LumoSolutions\Actionable\Actions\Generation;
4+
5+
use Exception;
6+
use LumoSolutions\Actionable\Dtos\Generation\DocBlockGenDto;
7+
use LumoSolutions\Actionable\Support\DocBlockHelper;
8+
use LumoSolutions\Actionable\Support\DocBlockProcessor;
9+
use LumoSolutions\Actionable\Traits\IsRunnable;
10+
11+
class GenerateDocBlocks
12+
{
13+
use IsRunnable;
14+
15+
private const string METHOD_RUN = 'run';
16+
17+
private const string METHOD_DISPATCH = 'dispatch';
18+
19+
private const string METHOD_DISPATCH_ON = 'dispatchOn';
20+
21+
/**
22+
* @throws Exception
23+
*/
24+
public function handle(DocBlockGenDto $dto): array
25+
{
26+
$processor = new DocBlockProcessor($dto->docBlocks);
27+
28+
$processor->removeMethodsIf(self::METHOD_RUN, ! $dto->isRunnable || ! $dto->handle);
29+
$processor->removeMethodsIf(self::METHOD_DISPATCH, ! $dto->isDispatchable || ! $dto->handle);
30+
$processor->removeMethodsIf(self::METHOD_DISPATCH_ON, ! $dto->isDispatchable || ! $dto->handle);
31+
32+
if ($dto->handle) {
33+
if ($dto->isRunnable) {
34+
$processor->addOrReplaceMethod(self::METHOD_RUN, $this->buildRunMethod($dto));
35+
}
36+
37+
if ($dto->isDispatchable) {
38+
$processor->addOrReplaceMethod(self::METHOD_DISPATCH, $this->buildDispatchMethod($dto));
39+
$processor->addOrReplaceMethod(self::METHOD_DISPATCH_ON, $this->buildDispatchOnMethod($dto));
40+
}
41+
}
42+
43+
return $processor->getDocBlocks();
44+
}
45+
46+
protected function buildRunMethod(DocBlockGenDto $dto): ?string
47+
{
48+
return DocBlockHelper::buildMethodLine(
49+
'static',
50+
DocBlockHelper::formatReturnType(
51+
$dto->handle->returnTypes,
52+
$dto->usings
53+
),
54+
self::METHOD_RUN,
55+
DocBlockHelper::formatParameters(
56+
$dto->handle->parameters,
57+
$dto->usings
58+
)
59+
);
60+
}
61+
62+
protected function buildDispatchMethod(DocBlockGenDto $dto): ?string
63+
{
64+
return DocBlockHelper::buildMethodLine(
65+
'static',
66+
'void',
67+
self::METHOD_DISPATCH,
68+
DocBlockHelper::formatParameters(
69+
$dto->handle->parameters,
70+
$dto->usings
71+
)
72+
);
73+
}
74+
75+
protected function buildDispatchOnMethod(DocBlockGenDto $dto): ?string
76+
{
77+
$parameters = DocBlockHelper::formatParameters($dto->handle->parameters, $dto->usings);
78+
$queueParameter = 'string $queue';
79+
80+
return DocBlockHelper::buildMethodLine(
81+
'static',
82+
'void',
83+
self::METHOD_DISPATCH_ON,
84+
$parameters
85+
? $queueParameter.', '.$parameters
86+
: $queueParameter
87+
);
88+
}
89+
}

0 commit comments

Comments
 (0)