From 81aa9f9fbf583ca1aacee87f133b82f36d554edd Mon Sep 17 00:00:00 2001 From: Clayton Salazar Date: Thu, 22 Feb 2024 17:10:28 -0600 Subject: [PATCH 1/5] Allowing table inspection to gracefully fail so other IDE helpers for models may still be generated --- config/ide-helper.php | 15 ++++++++++++++- src/Console/ModelsCommand.php | 33 ++++++++++++++++++++++++++++++++- 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/config/ide-helper.php b/config/ide-helper.php index e3bdc574c..c0c2c38cf 100644 --- a/config/ide-helper.php +++ b/config/ide-helper.php @@ -11,7 +11,7 @@ | */ - 'filename' => '_ide_helper.php', + 'filename' => '_ide_helper.php', /* |-------------------------------------------------------------------------- @@ -155,6 +155,19 @@ ], + /* + |-------------------------------------------------------------------------- + | Models to silence warnings + |-------------------------------------------------------------------------- + | + | Define which models should have warnings silenced + | + */ + + 'silenced_models' => [ + + ], + /* |-------------------------------------------------------------------------- | Models hooks diff --git a/src/Console/ModelsCommand.php b/src/Console/ModelsCommand.php index d2d484ff5..fbb5d008c 100644 --- a/src/Console/ModelsCommand.php +++ b/src/Console/ModelsCommand.php @@ -252,6 +252,8 @@ protected function generateDocs($loadModels, $ignore = '') $this->laravel['config']->get('ide-helper.ignored_models', []) ); + $skippedGeneratingTablePropertiesForModels = []; + foreach ($models as $name) { if (in_array($name, $ignore)) { if ($this->output->getVerbosity() >= OutputInterface::VERBOSITY_VERBOSE) { @@ -280,7 +282,20 @@ protected function generateDocs($loadModels, $ignore = '') $model = $this->laravel->make($name); - $this->getPropertiesFromTable($model); + try { + $this->getPropertiesFromTable($model); + } catch (Throwable $e) { + $modelName = $model::class; + + if ($this->warningsAreAllowedForForModel($model)) { + $connectionName = $model->getConnectionName() ?? $this->laravel['config']->get('database.default'); + $driver = $model->getConnection()::class; + + $this->warn("Could not get table properties for model [{$modelName}] using connection [{$connectionName}]. The underlying database driver [{$driver}] may not be supported."); + + $skippedGeneratingTablePropertiesForModels[] = $model; + } + } if (method_exists($model, 'getCasts')) { $this->castPropertiesType($model); @@ -304,6 +319,16 @@ protected function generateDocs($loadModels, $ignore = '') } } + if (! empty($skippedGeneratingTablePropertiesForModels)) { + $classes = collect($skippedGeneratingTablePropertiesForModels) + ->map(fn ($model) => ' • ' . $model::class); + $this->warn('Could not inspect table properties for some models. See output above for any warnings'); + $this->warn('Models without table inspection:'); + $this->newLine(); + $this->warn($classes->implode(PHP_EOL)); + $this->newLine(); + } + return $output; } @@ -1626,4 +1651,10 @@ protected function setForeignKeys($schema, $table) } } } + + protected function warningsAreAllowedForForModel(Model $model): bool + { + return collect($this->laravel['config']->get('ide-helper.silenced_models')) + ->doesntContain($model::class); + } } From 9a27bee785ee7217912cb61979d2c587426df5f9 Mon Sep 17 00:00:00 2001 From: Clayton Salazar Date: Fri, 23 Feb 2024 16:58:42 -0600 Subject: [PATCH 2/5] Added example model class to ide-helper.silenced_models array --- config/ide-helper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/ide-helper.php b/config/ide-helper.php index c0c2c38cf..afe3ecad4 100644 --- a/config/ide-helper.php +++ b/config/ide-helper.php @@ -165,7 +165,7 @@ */ 'silenced_models' => [ - + // App\Models\User::class ], /* From 7f0e6b58a8eeb9834f2ca7248b7d34c2a13d99fb Mon Sep 17 00:00:00 2001 From: Clayton Salazar Date: Fri, 23 Feb 2024 17:01:47 -0600 Subject: [PATCH 3/5] Allowing exception to be thrown by default if the ide-helper.silenced_models key is null or missing. Adjusting and tidying logic around warnings --- src/Console/ModelsCommand.php | 71 ++++++++++++++++++++++++----------- src/Enums/ModelWarning.php | 18 +++++++++ 2 files changed, 68 insertions(+), 21 deletions(-) create mode 100644 src/Enums/ModelWarning.php diff --git a/src/Console/ModelsCommand.php b/src/Console/ModelsCommand.php index fbb5d008c..69a33b934 100644 --- a/src/Console/ModelsCommand.php +++ b/src/Console/ModelsCommand.php @@ -12,6 +12,7 @@ namespace Barryvdh\LaravelIdeHelper\Console; use Barryvdh\LaravelIdeHelper\Contracts\ModelHookInterface; +use Barryvdh\LaravelIdeHelper\Enums\ModelWarning; use Barryvdh\Reflection\DocBlock; use Barryvdh\Reflection\DocBlock\Context; use Barryvdh\Reflection\DocBlock\Serializer as DocBlockSerializer; @@ -116,6 +117,8 @@ class ModelsCommand extends Command */ protected $foreignKeyConstraintsColumns = []; + protected $modelWarnings = []; + /** * During initialization we use Laravels Date Facade to * determine the actual date class and store it here. @@ -285,16 +288,7 @@ protected function generateDocs($loadModels, $ignore = '') try { $this->getPropertiesFromTable($model); } catch (Throwable $e) { - $modelName = $model::class; - - if ($this->warningsAreAllowedForForModel($model)) { - $connectionName = $model->getConnectionName() ?? $this->laravel['config']->get('database.default'); - $driver = $model->getConnection()::class; - - $this->warn("Could not get table properties for model [{$modelName}] using connection [{$connectionName}]. The underlying database driver [{$driver}] may not be supported."); - - $skippedGeneratingTablePropertiesForModels[] = $model; - } + $this->tableInspectionFailedForModel($model, $e); } if (method_exists($model, 'getCasts')) { @@ -319,14 +313,17 @@ protected function generateDocs($loadModels, $ignore = '') } } - if (! empty($skippedGeneratingTablePropertiesForModels)) { - $classes = collect($skippedGeneratingTablePropertiesForModels) - ->map(fn ($model) => ' • ' . $model::class); - $this->warn('Could not inspect table properties for some models. See output above for any warnings'); - $this->warn('Models without table inspection:'); - $this->newLine(); - $this->warn($classes->implode(PHP_EOL)); - $this->newLine(); + if (! empty($this->modelWarnings)) { + foreach ($this->modelWarnings as $modelClass => $warnings) { + $this->newline(); + $this->warn("{$modelClass} has the following warnings:"); + foreach ($warnings as $warning) { + $this->warn('• '.$warning->message()); + } + } + + $this->newline(); + $this->warn('There are warnings for some of the models that we tried to generate docs for. Please see the output above for more information.'); } return $output; @@ -1652,9 +1649,41 @@ protected function setForeignKeys($schema, $table) } } - protected function warningsAreAllowedForForModel(Model $model): bool + protected function gracefullyHandleExceptions(): bool + { + return ! is_null($this->laravel['config']->get('ide-helper.silenced_models')); + } + + protected function warningsAreSilencedForModel(Model $model): bool + { + $silencedModels = $this->laravel['config']->get('ide-helper.silenced_models'); + + return collect($silencedModels)->contains($model::class); + } + + protected function tableInspectionFailedForModel(Model $model, ?Throwable $e = null): void { - return collect($this->laravel['config']->get('ide-helper.silenced_models')) - ->doesntContain($model::class); + if ($e && ! $this->gracefullyHandleExceptions()) { + throw $e; + } + + if ($this->warningsAreSilencedForModel($model)) { + return; + } + + $modelName = $model::class; + + $connectionName = $model->getConnectionName() ?? $this->laravel['config']->get('database.default'); + $driver = $model->getConnection()::class; + + $this->warn("Could not get table properties for model [{$modelName}] using connection [{$connectionName}]. The underlying database driver [{$driver}] may not be supported."); + + if ($e) { + $this->warn(get_class($e).' '.$e->getMessage()); + } + + $this->modelWarnings[$model::class] ??= []; + + $this->modelWarnings[$model::class][] = ModelWarning::TableInspectionFailed; } } diff --git a/src/Enums/ModelWarning.php b/src/Enums/ModelWarning.php new file mode 100644 index 000000000..6fa8163bc --- /dev/null +++ b/src/Enums/ModelWarning.php @@ -0,0 +1,18 @@ + str($this->name) + ->headline() + ->lower() + ->ucfirst() + }; + } +} From 5f5feba520371634d1c0db0ab3b73bcebf39b9f8 Mon Sep 17 00:00:00 2001 From: Clayton Salazar Date: Fri, 23 Feb 2024 17:03:17 -0600 Subject: [PATCH 4/5] Removed unused variable --- src/Console/ModelsCommand.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Console/ModelsCommand.php b/src/Console/ModelsCommand.php index 69a33b934..90f0711d9 100644 --- a/src/Console/ModelsCommand.php +++ b/src/Console/ModelsCommand.php @@ -255,8 +255,6 @@ protected function generateDocs($loadModels, $ignore = '') $this->laravel['config']->get('ide-helper.ignored_models', []) ); - $skippedGeneratingTablePropertiesForModels = []; - foreach ($models as $name) { if (in_array($name, $ignore)) { if ($this->output->getVerbosity() >= OutputInterface::VERBOSITY_VERBOSE) { From feef29a37b23a46083619a4ffe473c5af9b2b42c Mon Sep 17 00:00:00 2001 From: Clayton Salazar Date: Fri, 23 Feb 2024 17:31:49 -0600 Subject: [PATCH 5/5] Moved warning output to separate method --- src/Console/ModelsCommand.php | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/src/Console/ModelsCommand.php b/src/Console/ModelsCommand.php index 90f0711d9..020324706 100644 --- a/src/Console/ModelsCommand.php +++ b/src/Console/ModelsCommand.php @@ -178,7 +178,9 @@ public function handle() $content = $this->generateDocs($model, $ignore); - if (!$this->write || $this->write_mixin) { + $this->handleWarnings(); + + if (! $this->write || $this->write_mixin) { $written = $this->files->put($filename, $content); if ($written !== false) { $this->info("Model information was written to $filename"); @@ -311,19 +313,6 @@ protected function generateDocs($loadModels, $ignore = '') } } - if (! empty($this->modelWarnings)) { - foreach ($this->modelWarnings as $modelClass => $warnings) { - $this->newline(); - $this->warn("{$modelClass} has the following warnings:"); - foreach ($warnings as $warning) { - $this->warn('• '.$warning->message()); - } - } - - $this->newline(); - $this->warn('There are warnings for some of the models that we tried to generate docs for. Please see the output above for more information.'); - } - return $output; } @@ -1647,6 +1636,22 @@ protected function setForeignKeys($schema, $table) } } + protected function handleWarnings(): void + { + if (! empty($this->modelWarnings)) { + foreach ($this->modelWarnings as $modelClass => $warnings) { + $this->newline(); + $this->warn("{$modelClass} has the following warnings:"); + foreach ($warnings as $warning) { + $this->warn('• '.$warning->message()); + } + } + + $this->newline(); + $this->warn('There are warnings for some of the models that we tried to generate docs for. Please see the output above for more information.'); + } + } + protected function gracefullyHandleExceptions(): bool { return ! is_null($this->laravel['config']->get('ide-helper.silenced_models'));