Skip to content

Commit deafe71

Browse files
authored
Add blueprint:build --only and --skip options (#276)
1 parent 18ae1e1 commit deafe71

20 files changed

+635
-297
lines changed

src/Blueprint.php

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ class Blueprint
1414

1515
public static function relativeNamespace(string $fullyQualifiedClassName)
1616
{
17-
$namespace = config('blueprint.namespace') . '\\';
17+
$namespace = config('blueprint.namespace').'\\';
1818
$reference = ltrim($fullyQualifiedClassName, '\\');
1919

2020
if (Str::startsWith($reference, $namespace)) {
@@ -70,12 +70,14 @@ public function analyze(array $tokens)
7070
return $registry;
7171
}
7272

73-
public function generate(array $tree): array
73+
public function generate(array $tree, array $only = [], array $skip = []): array
7474
{
7575
$components = [];
7676

7777
foreach ($this->generators as $generator) {
78-
$components = array_merge_recursive($components, $generator->output($tree));
78+
if ($this->shouldGenerate($generator->types(), $only, $skip)) {
79+
$components = array_merge_recursive($components, $generator->output($tree));
80+
}
7981
}
8082

8183
return $components;
@@ -106,4 +108,27 @@ public function swapGenerator(string $concrete, Generator $generator)
106108

107109
$this->registerGenerator($generator);
108110
}
111+
112+
protected function shouldGenerate(array $types, array $only, array $skip): bool
113+
{
114+
if (count($only)) {
115+
$found = 0;
116+
foreach ($types as $type) {
117+
$found += in_array($type, $only) ? 1 : 0;
118+
}
119+
120+
return $found > 0;
121+
}
122+
123+
if (count($skip)) {
124+
$found = 0;
125+
foreach ($types as $type) {
126+
$found += in_array($type, $skip) ? 1 : 0;
127+
}
128+
129+
return $found === 0;
130+
}
131+
132+
return true;
133+
}
109134
}

src/Builder.php

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

77
class Builder
88
{
9-
public static function execute(Blueprint $blueprint, Filesystem $files, string $draft)
9+
public static function execute(Blueprint $blueprint, Filesystem $files, string $draft, string $only = '', string $skip = '')
1010
{
1111
$cache = [];
1212
if ($files->exists('.blueprint')) {
@@ -16,7 +16,11 @@ public static function execute(Blueprint $blueprint, Filesystem $files, string $
1616
$tokens = $blueprint->parse($files->get($draft));
1717
$tokens['cache'] = $cache['models'] ?? [];
1818
$registry = $blueprint->analyze($tokens);
19-
$generated = $blueprint->generate($registry);
19+
20+
$only = array_filter(explode(',', $only));
21+
$skip = array_filter(explode(',', $skip));
22+
23+
$generated = $blueprint->generate($registry, $only, $skip);
2024

2125
$models = array_merge($tokens['cache'], $tokens['models'] ?? []);
2226

src/Commands/BuildCommand.php

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,10 @@ class BuildCommand extends Command
1616
*
1717
* @var string
1818
*/
19-
protected $signature = 'blueprint:build
19+
protected $signature = 'blueprint:build
2020
{draft? : The path to the draft file, default: draft.yaml or draft.yml }
21+
{--only= : Comma separated list of file classes to generate, skipping the rest }
22+
{--skip= : Comma separated list of file classes to skip, generating the rest }
2123
';
2224

2325
/**
@@ -27,7 +29,7 @@ class BuildCommand extends Command
2729
*/
2830
protected $description = 'Build components from a Blueprint draft';
2931

30-
/** @var Filesystem $files */
32+
/** @var Filesystem */
3133
protected $files;
3234

3335
/**
@@ -49,18 +51,21 @@ public function handle()
4951
{
5052
$file = $this->argument('draft') ?? $this->defaultDraftFile();
5153

52-
if (!file_exists($file)) {
53-
$this->error('Draft file could not be found: ' . ($file ?: 'draft.yaml'));
54+
if (! file_exists($file)) {
55+
$this->error('Draft file could not be found: '.($file ?: 'draft.yaml'));
5456
exit(1);
5557
}
5658

59+
$only = $this->option('only') ?: '';
60+
$skip = $this->option('skip') ?: '';
61+
5762
$blueprint = resolve(Blueprint::class);
58-
$generated = Builder::execute($blueprint, $this->files, $file);
63+
$generated = Builder::execute($blueprint, $this->files, $file, $only, $skip);
5964

6065
collect($generated)->each(function ($files, $action) {
61-
$this->line(Str::studly($action) . ':', $this->outputStyle($action));
66+
$this->line(Str::studly($action).':', $this->outputStyle($action));
6267
collect($files)->each(function ($file) {
63-
$this->line('- ' . $file);
68+
$this->line('- '.$file);
6469
});
6570

6671
$this->line('');
@@ -99,7 +104,5 @@ private function defaultDraftFile()
99104
if (file_exists('draft.yml')) {
100105
return 'draft.yml';
101106
}
102-
103-
return null;
104107
}
105108
}

src/Contracts/Generator.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,6 @@ interface Generator
1010
public function __construct($files);
1111

1212
public function output(array $tree): array;
13+
14+
public function types(): array;
1315
}

src/Generators/ControllerGenerator.php

Lines changed: 38 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44

55
use Blueprint\Blueprint;
66
use Blueprint\Contracts\Generator;
7-
use Blueprint\Models\Model;
87
use Blueprint\Models\Controller;
8+
use Blueprint\Models\Model;
99
use Blueprint\Models\Statements\DispatchStatement;
1010
use Blueprint\Models\Statements\EloquentStatement;
1111
use Blueprint\Models\Statements\FireStatement;
@@ -53,7 +53,7 @@ public function output(array $tree): array
5353

5454
$path = $this->getPath($controller);
5555

56-
if (!$this->files->exists(dirname($path))) {
56+
if (! $this->files->exists(dirname($path))) {
5757
$this->files->makeDirectory(dirname($path), 0755, true);
5858
}
5959

@@ -65,6 +65,11 @@ public function output(array $tree): array
6565
return $output;
6666
}
6767

68+
public function types(): array
69+
{
70+
return ['controllers'];
71+
}
72+
6873
protected function populateStub(string $stub, Controller $controller)
6974
{
7075
$stub = str_replace('DummyNamespace', $controller->fullyQualifiedNamespace(), $stub);
@@ -87,82 +92,82 @@ private function buildMethods(Controller $controller)
8792
if (in_array($name, ['edit', 'update', 'show', 'destroy'])) {
8893
$context = Str::singular($controller->prefix());
8994
$reference = $this->fullyQualifyModelReference($controller->namespace(), Str::camel($context));
90-
$variable = '$' . Str::camel($context);
95+
$variable = '$'.Str::camel($context);
9196

9297
// TODO: verify controller prefix references a model
9398
$search = ' * @return \\Illuminate\\Http\\Response';
94-
$method = str_replace($search, ' * @param \\' . $reference . ' ' . $variable . PHP_EOL . $search, $method);
99+
$method = str_replace($search, ' * @param \\'.$reference.' '.$variable.PHP_EOL.$search, $method);
95100

96101
$search = '(Request $request';
97-
$method = str_replace($search, $search . ', ' . $context . ' ' . $variable, $method);
102+
$method = str_replace($search, $search.', '.$context.' '.$variable, $method);
98103
$this->addImport($controller, $reference);
99104
}
100105

101106
$body = '';
102107
foreach ($statements as $statement) {
103108
if ($statement instanceof SendStatement) {
104-
$body .= self::INDENT . $statement->output() . PHP_EOL;
109+
$body .= self::INDENT.$statement->output().PHP_EOL;
105110
if ($statement->type() === SendStatement::TYPE_NOTIFICATION_WITH_FACADE) {
106111
$this->addImport($controller, 'Illuminate\\Support\\Facades\\Notification');
107-
$this->addImport($controller, config('blueprint.namespace') . '\\Notification\\' . $statement->mail());
112+
$this->addImport($controller, config('blueprint.namespace').'\\Notification\\'.$statement->mail());
108113
} elseif ($statement->type() === SendStatement::TYPE_MAIL) {
109114
$this->addImport($controller, 'Illuminate\\Support\\Facades\\Mail');
110-
$this->addImport($controller, config('blueprint.namespace') . '\\Mail\\' . $statement->mail());
115+
$this->addImport($controller, config('blueprint.namespace').'\\Mail\\'.$statement->mail());
111116
}
112117
} elseif ($statement instanceof ValidateStatement) {
113-
$class_name = $controller->name() . Str::studly($name) . 'Request';
118+
$class_name = $controller->name().Str::studly($name).'Request';
114119

115-
$fqcn = config('blueprint.namespace') . '\\Http\\Requests\\' . ($controller->namespace() ? $controller->namespace() . '\\' : '') . $class_name;
120+
$fqcn = config('blueprint.namespace').'\\Http\\Requests\\'.($controller->namespace() ? $controller->namespace().'\\' : '').$class_name;
116121

117-
$method = str_replace('\Illuminate\Http\Request $request', '\\' . $fqcn . ' $request', $method);
118-
$method = str_replace('(Request $request', '(' . $class_name . ' $request', $method);
122+
$method = str_replace('\Illuminate\Http\Request $request', '\\'.$fqcn.' $request', $method);
123+
$method = str_replace('(Request $request', '('.$class_name.' $request', $method);
119124

120125
$this->addImport($controller, $fqcn);
121126
} elseif ($statement instanceof DispatchStatement) {
122-
$body .= self::INDENT . $statement->output() . PHP_EOL;
123-
$this->addImport($controller, config('blueprint.namespace') . '\\Jobs\\' . $statement->job());
127+
$body .= self::INDENT.$statement->output().PHP_EOL;
128+
$this->addImport($controller, config('blueprint.namespace').'\\Jobs\\'.$statement->job());
124129
} elseif ($statement instanceof FireStatement) {
125-
$body .= self::INDENT . $statement->output() . PHP_EOL;
126-
if (!$statement->isNamedEvent()) {
127-
$this->addImport($controller, config('blueprint.namespace') . '\\Events\\' . $statement->event());
130+
$body .= self::INDENT.$statement->output().PHP_EOL;
131+
if (! $statement->isNamedEvent()) {
132+
$this->addImport($controller, config('blueprint.namespace').'\\Events\\'.$statement->event());
128133
}
129134
} elseif ($statement instanceof RenderStatement) {
130-
$body .= self::INDENT . $statement->output() . PHP_EOL;
135+
$body .= self::INDENT.$statement->output().PHP_EOL;
131136
} elseif ($statement instanceof ResourceStatement) {
132-
$fqcn = config('blueprint.namespace') . '\\Http\\Resources\\' . ($controller->namespace() ? $controller->namespace() . '\\' : '') . $statement->name();
137+
$fqcn = config('blueprint.namespace').'\\Http\\Resources\\'.($controller->namespace() ? $controller->namespace().'\\' : '').$statement->name();
133138

134-
$method = str_replace('* @return \\Illuminate\\Http\\Response', '* @return \\' . $fqcn, $method);
139+
$method = str_replace('* @return \\Illuminate\\Http\\Response', '* @return \\'.$fqcn, $method);
135140

136141
$import = $fqcn;
137-
if (!$statement->collection()) {
138-
$import .= ' as ' . $statement->name() . 'Resource';
142+
if (! $statement->collection()) {
143+
$import .= ' as '.$statement->name().'Resource';
139144
}
140145

141146
$this->addImport($controller, $import);
142147

143-
$body .= self::INDENT . $statement->output() . PHP_EOL;
148+
$body .= self::INDENT.$statement->output().PHP_EOL;
144149
} elseif ($statement instanceof RedirectStatement) {
145-
$body .= self::INDENT . $statement->output() . PHP_EOL;
150+
$body .= self::INDENT.$statement->output().PHP_EOL;
146151
} elseif ($statement instanceof RespondStatement) {
147-
$body .= self::INDENT . $statement->output() . PHP_EOL;
152+
$body .= self::INDENT.$statement->output().PHP_EOL;
148153
} elseif ($statement instanceof SessionStatement) {
149-
$body .= self::INDENT . $statement->output() . PHP_EOL;
154+
$body .= self::INDENT.$statement->output().PHP_EOL;
150155
} elseif ($statement instanceof EloquentStatement) {
151-
$body .= self::INDENT . $statement->output($controller->prefix(), $name) . PHP_EOL;
156+
$body .= self::INDENT.$statement->output($controller->prefix(), $name).PHP_EOL;
152157
$this->addImport($controller, $this->determineModel($controller, $statement->reference()));
153158
} elseif ($statement instanceof QueryStatement) {
154-
$body .= self::INDENT . $statement->output($controller->prefix()) . PHP_EOL;
159+
$body .= self::INDENT.$statement->output($controller->prefix()).PHP_EOL;
155160
$this->addImport($controller, $this->determineModel($controller, $statement->model()));
156161
}
157162

158163
$body .= PHP_EOL;
159164
}
160165

161-
if (!empty($body)) {
166+
if (! empty($body)) {
162167
$method = str_replace('//', trim($body), $method);
163168
}
164169

165-
$methods .= PHP_EOL . $method;
170+
$methods .= PHP_EOL.$method;
166171
}
167172

168173
return trim($methods);
@@ -172,7 +177,7 @@ protected function getPath(Controller $controller)
172177
{
173178
$path = str_replace('\\', '/', Blueprint::relativeNamespace($controller->fullyQualifiedClassName()));
174179

175-
return Blueprint::appPath() . '/' . $path . '.php';
180+
return Blueprint::appPath().'/'.$path.'.php';
176181
}
177182

178183
private function addImport(Controller $controller, $class)
@@ -186,7 +191,7 @@ private function buildImports(Controller $controller)
186191
sort($imports);
187192

188193
return implode(PHP_EOL, array_map(function ($class) {
189-
return 'use ' . $class . ';';
194+
return 'use '.$class.';';
190195
}, $imports));
191196
}
192197

@@ -216,7 +221,7 @@ private function fullyQualifyModelReference(string $sub_namespace, string $model
216221
return $model->fullyQualifiedClassName();
217222
}
218223

219-
return config('blueprint.namespace') . '\\' . ($sub_namespace ? $sub_namespace . '\\' : '') . $model_name;
224+
return config('blueprint.namespace').'\\'.($sub_namespace ? $sub_namespace.'\\' : '').$model_name;
220225
}
221226

222227
private function modelForContext(string $context)

0 commit comments

Comments
 (0)