-
Notifications
You must be signed in to change notification settings - Fork 199
5.0.0 #122
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
5.0.0 #122
Changes from all commits
62ebdc4
0360382
26f3104
dd92522
24667b8
e57de54
e23750d
f880c14
9818964
20687c6
f05eb01
1572c0e
0277242
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
name: run-tests | ||
|
||
on: | ||
push: | ||
branches: | ||
- master | ||
- dev | ||
pull_request: | ||
branches: | ||
- master | ||
|
||
jobs: | ||
php-tests: | ||
runs-on: ubuntu-latest | ||
|
||
strategy: | ||
fail-fast: true | ||
matrix: | ||
php: ['8.4', '8.3', '8.2'] | ||
laravel: ['10.*', '11.*', '12.*'] | ||
dependency-version: [prefer-stable] | ||
exclude: | ||
- php: 8.4 | ||
laravel: 10.* | ||
- php: 8.4 | ||
laravel: 11.* | ||
include: | ||
- laravel: 10.* | ||
testbench: 8.* | ||
- laravel: 11.* | ||
testbench: 9.* | ||
- laravel: 12.* | ||
testbench: 10.* | ||
|
||
name: P${{ matrix.php }} - L${{ matrix.laravel }} - ${{ matrix.dependency-version }} - ubuntu-latest | ||
|
||
steps: | ||
- name: Checkout code | ||
uses: actions/checkout@v4 | ||
|
||
- name: Install Graphviz | ||
run: sudo apt-get update && sudo apt-get install -y graphviz | ||
|
||
- name: Setup PHP | ||
uses: shivammathur/setup-php@v2 | ||
with: | ||
php-version: ${{ matrix.php }} | ||
extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite, bcmath, soap, intl, gd, exif, iconv, imagick | ||
coverage: none | ||
|
||
- name: Install dependencies | ||
run: | | ||
composer require "laravel/framework:${{ matrix.laravel }}" "orchestra/testbench:${{ matrix.testbench }}" --no-interaction --no-update | ||
if [[ "${{ matrix.laravel }}" == "10.*" ]]; then composer require "doctrine/dbal:^3.3" --no-interaction --no-update; fi | ||
composer update --${{ matrix.dependency-version }} --prefer-dist --no-interaction | ||
|
||
- name: Execute tests | ||
run: vendor/bin/phpunit |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -84,6 +84,52 @@ Or use one of the other [output formats](https://www.graphviz.org/doc/info/outpu | |
php artisan generate:erd output.svg --format=svg | ||
``` | ||
|
||
### Text Output | ||
|
||
If you want to generate a text representation of the ER diagram instead of an image, you can use the `--text-output` option: | ||
|
||
```bash | ||
php artisan generate:erd output.txt --text-output | ||
``` | ||
|
||
This will generate a text file with the GraphViz DOT representation of the ER diagram. | ||
|
||
### Structured Text Output for AI Models | ||
|
||
If you want to generate a structured text representation of the ER diagram that is more suitable for AI models, simply specify a filename with a `.txt` extension: | ||
|
||
```bash | ||
php artisan generate:erd output.txt | ||
``` | ||
|
||
This will automatically generate a Markdown file with a structured representation of the entities and their relationships, which can be used as context for AI models. | ||
|
||
#### Output Format | ||
|
||
The structured output format looks like this: | ||
|
||
```markdown | ||
# Entity Relationship Diagram | ||
|
||
## Entities | ||
|
||
### User (`App\Models\User`) | ||
|
||
#### Attributes: | ||
- `id` (integer) | ||
- `name` (string) | ||
- `email` (string) | ||
... | ||
|
||
## Relationships | ||
|
||
### User Relationships | ||
- **HasMany** `posts` to Post (Local Key: `id`, Foreign Key: `user_id`) | ||
... | ||
``` | ||
|
||
This format is particularly useful when providing context to AI models about your database structure. | ||
|
||
## Customization | ||
|
||
Please take a look at the published `erd-generator.php` configuration file for all available customization options. | ||
|
@@ -121,4 +167,4 @@ If you discover any security related issues, please email [email protected] ins | |
|
||
## License | ||
|
||
The MIT License (MIT). Please see [License File](LICENSE.md) for more information. | ||
The MIT License (MIT). Please see [License File](LICENSE.md) for more information. |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -3,6 +3,7 @@ | |||||||||||||||||||
namespace BeyondCode\ErdGenerator; | ||||||||||||||||||||
|
||||||||||||||||||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany; | ||||||||||||||||||||
use Illuminate\Support\Facades\Schema; | ||||||||||||||||||||
use phpDocumentor\GraphViz\Graph; | ||||||||||||||||||||
use Illuminate\Support\Collection; | ||||||||||||||||||||
use phpDocumentor\GraphViz\Node; | ||||||||||||||||||||
|
@@ -30,6 +31,75 @@ public function buildGraph(Collection $models) : Graph | |||||||||||||||||||
return $this->graph; | ||||||||||||||||||||
} | ||||||||||||||||||||
|
||||||||||||||||||||
/** | ||||||||||||||||||||
* Generate a structured text representation of the ER diagram | ||||||||||||||||||||
* | ||||||||||||||||||||
* @param Collection $models | ||||||||||||||||||||
* @return string | ||||||||||||||||||||
*/ | ||||||||||||||||||||
public function generateStructuredTextRepresentation(Collection $models) : string | ||||||||||||||||||||
{ | ||||||||||||||||||||
$output = "# Entity Relationship Diagram\n\n"; | ||||||||||||||||||||
|
||||||||||||||||||||
// First list all models/entities with their attributes | ||||||||||||||||||||
$output .= "## Entities\n\n"; | ||||||||||||||||||||
|
||||||||||||||||||||
foreach ($models as $model) { | ||||||||||||||||||||
/** @var Model $model */ | ||||||||||||||||||||
$eloquentModel = app($model->getModel()); | ||||||||||||||||||||
$output .= "### " . $model->getLabel() . " (`" . $model->getModel() . "`)\n\n"; | ||||||||||||||||||||
|
||||||||||||||||||||
// Add table columns if available | ||||||||||||||||||||
if (config('erd-generator.use_db_schema')) { | ||||||||||||||||||||
$columns = $this->getTableColumnsFromModel($eloquentModel); | ||||||||||||||||||||
if (count($columns) > 0) { | ||||||||||||||||||||
$output .= "#### Attributes:\n\n"; | ||||||||||||||||||||
foreach ($columns as $column) { | ||||||||||||||||||||
if (is_object($column)) { | ||||||||||||||||||||
$name = $column->getName(); | ||||||||||||||||||||
$typeName = $column->getType()->getName(); | ||||||||||||||||||||
} else { | ||||||||||||||||||||
$name = $column['name'] ?? ''; | ||||||||||||||||||||
$typeName = $column['type_name'] ?? ''; | ||||||||||||||||||||
} | ||||||||||||||||||||
$columnType = config('erd-generator.use_column_types') ? ' (' . $typeName . ')' : ''; | ||||||||||||||||||||
$output .= "- `" . $name . "`" . $columnType . "\n"; | ||||||||||||||||||||
} | ||||||||||||||||||||
$output .= "\n"; | ||||||||||||||||||||
} | ||||||||||||||||||||
} | ||||||||||||||||||||
} | ||||||||||||||||||||
|
||||||||||||||||||||
// Then list all relationships | ||||||||||||||||||||
$output .= "## Relationships\n\n"; | ||||||||||||||||||||
|
||||||||||||||||||||
foreach ($models as $model) { | ||||||||||||||||||||
/** @var Model $model */ | ||||||||||||||||||||
if (count($model->getRelations()) > 0) { | ||||||||||||||||||||
$output .= "### " . $model->getLabel() . " Relationships\n\n"; | ||||||||||||||||||||
|
||||||||||||||||||||
foreach ($model->getRelations() as $relation) { | ||||||||||||||||||||
/** @var ModelRelation $relation */ | ||||||||||||||||||||
// Find the related model by comparing model class names | ||||||||||||||||||||
$relatedModelClass = $relation->getModel(); | ||||||||||||||||||||
|
||||||||||||||||||||
$relatedModel = $models->first(function ($m) use ($relatedModelClass) { | ||||||||||||||||||||
return $m->getModel() === $relatedModelClass; | ||||||||||||||||||||
}); | ||||||||||||||||||||
if ($relatedModel) { | ||||||||||||||||||||
$output .= "- **" . $relation->getType() . "** `" . $relation->getName() . "` to " . | ||||||||||||||||||||
$relatedModel->getLabel() . " (Local Key: `" . $relation->getLocalKey() . | ||||||||||||||||||||
"`, Foreign Key: `" . $relation->getForeignKey() . "`)\n"; | ||||||||||||||||||||
} | ||||||||||||||||||||
} | ||||||||||||||||||||
|
||||||||||||||||||||
$output .= "\n"; | ||||||||||||||||||||
} | ||||||||||||||||||||
} | ||||||||||||||||||||
|
||||||||||||||||||||
return $output; | ||||||||||||||||||||
} | ||||||||||||||||||||
|
||||||||||||||||||||
protected function getTableColumnsFromModel(EloquentModel $model) | ||||||||||||||||||||
{ | ||||||||||||||||||||
try { | ||||||||||||||||||||
|
@@ -49,6 +119,11 @@ protected function getTableColumnsFromModel(EloquentModel $model) | |||||||||||||||||||
} catch (\Throwable $e) { | ||||||||||||||||||||
} | ||||||||||||||||||||
|
||||||||||||||||||||
try { | ||||||||||||||||||||
return Schema::getColumns($model->getTable()); | ||||||||||||||||||||
} catch (\Throwable $e) { | ||||||||||||||||||||
} | ||||||||||||||||||||
|
||||||||||||||||||||
return []; | ||||||||||||||||||||
} | ||||||||||||||||||||
|
||||||||||||||||||||
|
@@ -61,11 +136,18 @@ protected function getModelLabel(EloquentModel $model, string $label) | |||||||||||||||||||
if (config('erd-generator.use_db_schema')) { | ||||||||||||||||||||
$columns = $this->getTableColumnsFromModel($model); | ||||||||||||||||||||
foreach ($columns as $column) { | ||||||||||||||||||||
$label = $column->getName(); | ||||||||||||||||||||
if (is_object($column)) { | ||||||||||||||||||||
$name = $column->getName(); | ||||||||||||||||||||
$typeName = $column->getType()->getName(); | ||||||||||||||||||||
} else { // it's an array! | ||||||||||||||||||||
$name = $column['name'] ?? ''; | ||||||||||||||||||||
$typeName = $column['type_name'] ?? ''; | ||||||||||||||||||||
} | ||||||||||||||||||||
Comment on lines
+139
to
+145
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [nitpick] Handling two different column representations (object vs array) here adds complexity. It might be cleaner to normalize the column data in
Suggested change
Copilot uses AI. Check for mistakes. Positive FeedbackNegative Feedback |
||||||||||||||||||||
$label = $name; | ||||||||||||||||||||
if (config('erd-generator.use_column_types')) { | ||||||||||||||||||||
$label .= ' ('.$column->getType()->getName().')'; | ||||||||||||||||||||
$label .= ' ('. $typeName .')'; | ||||||||||||||||||||
} | ||||||||||||||||||||
$table .= '<tr width="100%"><td port="' . $column->getName() . '" align="left" width="100%" bgcolor="'.config('erd-generator.table.row_background_color').'"><font color="'.config('erd-generator.table.row_font_color').'" >' . $label . '</font></td></tr>' . PHP_EOL; | ||||||||||||||||||||
$table .= '<tr width="100%"><td port="' . $name . '" align="left" width="100%" bgcolor="'.config('erd-generator.table.row_background_color').'"><font color="'.config('erd-generator.table.row_font_color').'" >' . $label . '</font></td></tr>' . PHP_EOL; | ||||||||||||||||||||
} | ||||||||||||||||||||
} | ||||||||||||||||||||
|
||||||||||||||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] The command handler has multiple return points and duplicated file-write logic for text and structured outputs. Consider refactoring into smaller methods (e.g.,
handleTextOutput
&handleStructuredOutput
) to improve readability and reduce duplication.Copilot uses AI. Check for mistakes.