Skip to content

Commit 646a538

Browse files
committed
refactor: migrate make:scaffold to AbstractGeneratorCommand
1 parent 872b249 commit 646a538

5 files changed

Lines changed: 208 additions & 177 deletions

File tree

‎phpstan.dist.neon‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ parameters:
3131
ignoreErrors:
3232
-
3333
identifier: missingType.generics
34+
-
35+
identifier: trait.unused
36+
path: system/CLI/GeneratorTrait.php
3437
checkMissingCallableSignature: true
3538
treatPhpDocTypesAsCertain: false
3639
strictRules:

‎system/Commands/Generators/ScaffoldGenerator.php‎

Lines changed: 98 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -13,117 +13,120 @@
1313

1414
namespace CodeIgniter\Commands\Generators;
1515

16-
use CodeIgniter\CLI\BaseCommand;
17-
use CodeIgniter\CLI\CLI;
18-
use CodeIgniter\CLI\GeneratorTrait;
19-
20-
/**
21-
* Generates a complete set of scaffold files.
22-
*/
23-
class ScaffoldGenerator extends BaseCommand
16+
use CodeIgniter\CLI\AbstractCommand;
17+
use CodeIgniter\CLI\Attributes\Command;
18+
use CodeIgniter\CLI\Input\Argument;
19+
use CodeIgniter\CLI\Input\Option;
20+
use CodeIgniter\CLI\PromptsForMissingInputInterface;
21+
22+
#[Command(name: 'make:scaffold', description: 'Generates a complete set of scaffold files.', group: 'Generators')]
23+
class ScaffoldGenerator extends AbstractCommand implements PromptsForMissingInputInterface
2424
{
25-
use GeneratorTrait;
25+
protected function configure(): void
26+
{
27+
$this
28+
->addArgument(new Argument(name: 'name', description: 'The class name.', required: true))
29+
->addOption(new Option(
30+
name: 'bare',
31+
shortcut: 'b',
32+
description: 'Pass "--bare" to the controller.',
33+
))
34+
->addOption(new Option(
35+
name: 'restful',
36+
description: 'Pass "--restful" to the controller.',
37+
acceptsValue: true,
38+
valueLabel: 'type',
39+
))
40+
->addOption(new Option(
41+
name: 'table',
42+
shortcut: 't',
43+
description: 'Pass "--table" to the model.',
44+
acceptsValue: true,
45+
valueLabel: 'name',
46+
))
47+
->addOption(new Option(
48+
name: 'dbgroup',
49+
shortcut: 'g',
50+
description: 'Pass "--dbgroup" to the model.',
51+
acceptsValue: true,
52+
valueLabel: 'group',
53+
))
54+
->addOption(new Option(
55+
name: 'return',
56+
description: 'Pass "--return" to the model.',
57+
acceptsValue: true,
58+
valueLabel: 'type',
59+
))
60+
->addOption(new Option(
61+
name: 'namespace',
62+
shortcut: 'n',
63+
description: 'Set the root namespace.',
64+
requiresValue: true,
65+
default: APP_NAMESPACE,
66+
))
67+
->addOption(new Option(
68+
name: 'suffix',
69+
shortcut: 's',
70+
description: 'Append the component suffix to each class name.',
71+
))
72+
->addOption(new Option(
73+
name: 'force',
74+
shortcut: 'f',
75+
description: 'Force overwrite existing files.',
76+
));
77+
}
2678

27-
/**
28-
* The Command's Group
29-
*
30-
* @var string
31-
*/
32-
protected $group = 'Generators';
79+
protected function getArgumentPromptLabels(): array
80+
{
81+
return ['name' => lang('CLI.generator.className.default')];
82+
}
3383

34-
/**
35-
* The Command's Name
36-
*
37-
* @var string
38-
*/
39-
protected $name = 'make:scaffold';
84+
protected function execute(array $arguments, array $options): int
85+
{
86+
$name = [$arguments['name']];
87+
$shared = ['namespace' => $options['namespace']];
4088

41-
/**
42-
* The Command's Description
43-
*
44-
* @var string
45-
*/
46-
protected $description = 'Generates a complete set of scaffold files.';
89+
if ($options['suffix'] === true) {
90+
$shared['suffix'] = null;
91+
}
4792

48-
/**
49-
* The Command's Usage
50-
*
51-
* @var string
52-
*/
53-
protected $usage = 'make:scaffold <name> [options]';
93+
$forced = $options['force'] === true ? $shared + ['force' => null] : $shared;
5494

55-
/**
56-
* The Command's Arguments
57-
*
58-
* @var array<string, string>
59-
*/
60-
protected $arguments = [
61-
'name' => 'The class name',
62-
];
95+
return $this->call('make:controller', $name, $this->getControllerOptions($options) + $forced)
96+
| $this->call('make:model', $name, $this->getModelOptions($options) + $forced)
97+
| $this->call('make:migration', $name, $shared)
98+
| $this->call('make:seeder', $name, $forced);
99+
}
63100

64101
/**
65-
* The Command's Options
102+
* @param array<string, mixed> $options
66103
*
67-
* @var array<string, string>
68-
*/
69-
protected $options = [
70-
'--bare' => 'Add the "--bare" option to controller component.',
71-
'--restful' => 'Add the "--restful" option to controller component.',
72-
'--table' => 'Add the "--table" option to the model component.',
73-
'--dbgroup' => 'Add the "--dbgroup" option to model component.',
74-
'--return' => 'Add the "--return" option to the model component.',
75-
'--namespace' => 'Set root namespace. Default: "APP_NAMESPACE".',
76-
'--suffix' => 'Append the component title to the class name.',
77-
'--force' => 'Force overwrite existing file.',
78-
];
79-
80-
/**
81-
* Actually execute a command.
104+
* @return array<string, string|null>
82105
*/
83-
public function run(array $params)
106+
private function getControllerOptions(array $options): array
84107
{
85-
$this->params = $params;
86-
87-
$options = [];
88-
89-
if ($this->getOption('namespace')) {
90-
$options['namespace'] = $this->getOption('namespace');
108+
if ($options['bare'] === true) {
109+
return ['bare' => null];
91110
}
92111

93-
if ($this->getOption('suffix')) {
94-
$options['suffix'] = null;
112+
if (! $this->hasUnboundOption('restful')) {
113+
return [];
95114
}
96115

97-
if ($this->getOption('force')) {
98-
$options['force'] = null;
99-
}
100-
101-
$controllerOpts = [];
102-
103-
if ($this->getOption('bare')) {
104-
$controllerOpts['bare'] = null;
105-
} elseif ($this->getOption('restful')) {
106-
$restful = $this->getOption('restful');
107-
108-
$controllerOpts['restful'] = is_string($restful) ? $restful : null;
109-
}
116+
return ['restful' => is_string($options['restful']) ? $options['restful'] : null];
117+
}
110118

111-
$modelOpts = array_filter([
112-
'table' => $this->getOption('table'),
113-
'dbgroup' => $this->getOption('dbgroup'),
114-
'return' => $this->getOption('return'),
119+
/**
120+
* @param array<string, mixed> $options
121+
*
122+
* @return array<string, string>
123+
*/
124+
private function getModelOptions(array $options): array
125+
{
126+
return array_filter([
127+
'table' => $options['table'],
128+
'dbgroup' => $options['dbgroup'],
129+
'return' => $options['return'],
115130
], is_string(...));
116-
117-
$class = $params[0] ?? CLI::getSegment(2);
118-
119-
// Call those commands!
120-
$exit1 = $this->call('make:controller', array_merge([$class], $controllerOpts, $options));
121-
$exit2 = $this->call('make:model', array_merge([$class], $modelOpts, $options));
122-
$exit3 = $this->call('make:migration', array_merge([$class], array_diff_key($options, ['force' => null])));
123-
$exit4 = $this->call('make:seeder', array_merge([$class], $options));
124-
125-
assert(is_int($exit1) && is_int($exit2) && is_int($exit3) && is_int($exit4));
126-
127-
return $exit1 | $exit2 | $exit3 | $exit4;
128131
}
129132
}

0 commit comments

Comments
 (0)