lagoon 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.md +10 -0
- data/LICENSE.txt +21 -0
- data/README.md +229 -0
- data/Rakefile +8 -0
- data/exe/lagoon +8 -0
- data/lib/lagoon/cli.rb +112 -0
- data/lib/lagoon/configuration.rb +20 -0
- data/lib/lagoon/diagram/base.rb +38 -0
- data/lib/lagoon/diagram/controller_diagram.rb +31 -0
- data/lib/lagoon/diagram/er_diagram.rb +31 -0
- data/lib/lagoon/diagram/model_diagram.rb +31 -0
- data/lib/lagoon/parser/controller_parser.rb +94 -0
- data/lib/lagoon/parser/model_parser.rb +161 -0
- data/lib/lagoon/parser/schema_parser.rb +114 -0
- data/lib/lagoon/railtie.rb +11 -0
- data/lib/lagoon/renderer/base_renderer.rb +45 -0
- data/lib/lagoon/renderer/class_diagram_renderer.rb +91 -0
- data/lib/lagoon/renderer/er_diagram_renderer.rb +108 -0
- data/lib/lagoon/version.rb +5 -0
- data/lib/lagoon.rb +51 -0
- data/lib/tasks/lagoon.rake +39 -0
- metadata +94 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 7e61c00e57856f9b4ad31cdadc75bfcff1af554453d93a35804d32c29ea35fec
|
|
4
|
+
data.tar.gz: d3089dbe9a76eabc00e95d925981f2ff9c2d7418ea773209a72367789549b198
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 169036710b052193519bc94501fba05f7e6a9cc6b32d4a03883c5ef06fa628f043a4c2c48529e4c28b1bee7ad1cdc70cac5fe114e8570ef787a25d59f260515e
|
|
7
|
+
data.tar.gz: 43a2172c67d6d46fb7a1f11a89050e151548b2b07f904481d001456e04c3ae06815a6c498563174c0c62bc2229ee816207bc79553be4931f9bde767e948934a7
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
- Initial release
|
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Yudai Takada
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
|
13
|
+
all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
# Lagoon
|
|
2
|
+
|
|
3
|
+
Generate Mermaid diagrams from Rails models and controllers.
|
|
4
|
+
|
|
5
|
+
Lagoon is a Ruby gem that generates Mermaid class diagrams and ER diagrams from Rails applications, inspired by [RailRoady](https://github.com/preston/railroady). Unlike RailRoady, which outputs DOT/SVG format and depends on Graphviz, Lagoon outputs Mermaid syntax that can be directly displayed on GitHub, GitLab, Notion, and other platforms that support Mermaid.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- Generate Mermaid class diagrams from ActiveRecord models
|
|
10
|
+
- Generate Mermaid class diagrams from Rails controllers
|
|
11
|
+
- Generate Mermaid ER diagrams from database schema
|
|
12
|
+
- No external dependencies (no Graphviz required)
|
|
13
|
+
- CLI tool and Rake tasks for easy integration
|
|
14
|
+
- Configurable output options
|
|
15
|
+
- Support for associations, inheritance, and foreign key relationships
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
18
|
+
|
|
19
|
+
Add this line to your application's Gemfile:
|
|
20
|
+
|
|
21
|
+
```ruby
|
|
22
|
+
gem 'lagoon'
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
And then execute:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
bundle install
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Or install it yourself as:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
gem install lagoon
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Usage
|
|
38
|
+
|
|
39
|
+
### Command Line Interface
|
|
40
|
+
|
|
41
|
+
Lagoon provides a CLI tool for generating diagrams:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
# Generate model class diagram
|
|
45
|
+
lagoon models -o doc/models.mermaid
|
|
46
|
+
|
|
47
|
+
# Generate controller class diagram
|
|
48
|
+
lagoon controllers -o doc/controllers.mermaid
|
|
49
|
+
|
|
50
|
+
# Generate ER diagram
|
|
51
|
+
lagoon er -o doc/er_diagram.mermaid
|
|
52
|
+
|
|
53
|
+
# Generate all diagrams
|
|
54
|
+
lagoon all
|
|
55
|
+
|
|
56
|
+
# Generate compact diagrams (no attributes/methods)
|
|
57
|
+
lagoon models -b -i
|
|
58
|
+
|
|
59
|
+
# Specify diagram direction
|
|
60
|
+
lagoon models -d LR # Left to Right (default: TB - Top to Bottom)
|
|
61
|
+
|
|
62
|
+
# Show help
|
|
63
|
+
lagoon help models
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Rake Tasks
|
|
67
|
+
|
|
68
|
+
In your Rails application, you can use Rake tasks:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
# Generate all diagrams
|
|
72
|
+
rake mermaid:all
|
|
73
|
+
|
|
74
|
+
# Generate specific diagrams
|
|
75
|
+
rake mermaid:models
|
|
76
|
+
rake mermaid:controllers
|
|
77
|
+
rake mermaid:er
|
|
78
|
+
|
|
79
|
+
# Generate brief diagrams
|
|
80
|
+
rake mermaid:brief
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Programmatic Usage
|
|
84
|
+
|
|
85
|
+
You can also use Lagoon programmatically in your Ruby code:
|
|
86
|
+
|
|
87
|
+
```ruby
|
|
88
|
+
require 'lagoon'
|
|
89
|
+
|
|
90
|
+
# Configure Lagoon
|
|
91
|
+
Lagoon.configure do |config|
|
|
92
|
+
config.output_dir = "doc/diagrams"
|
|
93
|
+
config.diagram_direction = "LR"
|
|
94
|
+
config.show_attributes = true
|
|
95
|
+
config.show_methods = false
|
|
96
|
+
config.include_inheritance = true
|
|
97
|
+
config.exclude_models = ["ApplicationRecord"]
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# Generate diagrams
|
|
101
|
+
Lagoon.generate_model_diagram
|
|
102
|
+
Lagoon.generate_controller_diagram
|
|
103
|
+
Lagoon.generate_er_diagram
|
|
104
|
+
|
|
105
|
+
# Or generate all at once
|
|
106
|
+
Lagoon.generate_all
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Configuration Options
|
|
110
|
+
|
|
111
|
+
You can configure Lagoon globally or per-diagram:
|
|
112
|
+
|
|
113
|
+
```ruby
|
|
114
|
+
Lagoon.configure do |config|
|
|
115
|
+
config.output_dir = "doc/diagrams" # Default: "doc/diagrams"
|
|
116
|
+
config.diagram_direction = "TB" # Default: "TB" (Top to Bottom)
|
|
117
|
+
# Options: "TB", "BT", "LR", "RL"
|
|
118
|
+
config.show_attributes = true # Default: true
|
|
119
|
+
config.show_methods = false # Default: false
|
|
120
|
+
config.include_inheritance = true # Default: true
|
|
121
|
+
config.exclude_models = [] # Default: []
|
|
122
|
+
config.exclude_controllers = [] # Default: []
|
|
123
|
+
config.diagram_format = :class_diagram # Default: :class_diagram
|
|
124
|
+
# Options: :class_diagram, :er_diagram
|
|
125
|
+
end
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## CLI Options
|
|
129
|
+
|
|
130
|
+
Lagoon CLI supports various options:
|
|
131
|
+
|
|
132
|
+
### Model Diagrams
|
|
133
|
+
|
|
134
|
+
- `-b, --brief`: Compact diagram (no attributes/methods)
|
|
135
|
+
- `-i, --inheritance`: Include inheritance relationships
|
|
136
|
+
- `-e, --exclude`: Exclude specified models
|
|
137
|
+
- `-s, --specify`: Only process specified models
|
|
138
|
+
- `-a, --all-models`: Include all models
|
|
139
|
+
- `--show-belongs-to`: Show belongs_to associations
|
|
140
|
+
- `--hide-through`: Hide through associations
|
|
141
|
+
- `--all-columns`: Show all columns
|
|
142
|
+
- `--hide-magic`: Hide magic fields (id, timestamps)
|
|
143
|
+
- `--hide-types`: Hide attribute types
|
|
144
|
+
|
|
145
|
+
### Controller Diagrams
|
|
146
|
+
|
|
147
|
+
- `-b, --brief`: Compact diagram (no methods)
|
|
148
|
+
- `-i, --inheritance`: Include inheritance relationships
|
|
149
|
+
- `-e, --exclude`: Exclude specified controllers
|
|
150
|
+
- `-s, --specify`: Only process specified controllers
|
|
151
|
+
- `--hide-public`: Hide public methods
|
|
152
|
+
- `--hide-protected`: Hide protected methods
|
|
153
|
+
- `--hide-private`: Hide private methods
|
|
154
|
+
|
|
155
|
+
### Common Options
|
|
156
|
+
|
|
157
|
+
- `-o, --output`: Output file path
|
|
158
|
+
- `-d, --direction`: Diagram direction (TB/BT/LR/RL)
|
|
159
|
+
- `-r, --root`: Application root path
|
|
160
|
+
- `-v, --verbose`: Enable verbose output
|
|
161
|
+
|
|
162
|
+
## Output Examples
|
|
163
|
+
|
|
164
|
+
### Model Class Diagram
|
|
165
|
+
|
|
166
|
+
```mermaid
|
|
167
|
+
classDiagram
|
|
168
|
+
direction TB
|
|
169
|
+
|
|
170
|
+
class User {
|
|
171
|
+
+Integer id
|
|
172
|
+
+String name
|
|
173
|
+
+String email
|
|
174
|
+
+DateTime created_at
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
class Post {
|
|
178
|
+
+Integer id
|
|
179
|
+
+String title
|
|
180
|
+
+Text content
|
|
181
|
+
+Integer user_id
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
User "1" --> "*" Post : has_many posts
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### ER Diagram
|
|
188
|
+
|
|
189
|
+
```mermaid
|
|
190
|
+
erDiagram
|
|
191
|
+
USER ||--o{ POST : "has many"
|
|
192
|
+
|
|
193
|
+
USER {
|
|
194
|
+
int id PK
|
|
195
|
+
string name
|
|
196
|
+
string email
|
|
197
|
+
datetime created_at
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
POST {
|
|
201
|
+
int id PK
|
|
202
|
+
string title
|
|
203
|
+
text content
|
|
204
|
+
int user_id FK
|
|
205
|
+
}
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
## Requirements
|
|
209
|
+
|
|
210
|
+
- Ruby >= 3.0.0
|
|
211
|
+
- Rails >= 6.0 (for Rails integration)
|
|
212
|
+
|
|
213
|
+
## Development
|
|
214
|
+
|
|
215
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
|
216
|
+
|
|
217
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
|
218
|
+
|
|
219
|
+
## Contributing
|
|
220
|
+
|
|
221
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/ydah/lagoon.
|
|
222
|
+
|
|
223
|
+
## License
|
|
224
|
+
|
|
225
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
|
226
|
+
|
|
227
|
+
## Acknowledgments
|
|
228
|
+
|
|
229
|
+
Lagoon is inspired by [RailRoady](https://github.com/preston/railroady), which has been a valuable tool for Rails developers for many years.
|
data/Rakefile
ADDED
data/exe/lagoon
ADDED
data/lib/lagoon/cli.rb
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "thor"
|
|
4
|
+
|
|
5
|
+
module Lagoon
|
|
6
|
+
class CLI < Thor
|
|
7
|
+
class_option :verbose, type: :boolean, aliases: "-v", desc: "Enable verbose output"
|
|
8
|
+
class_option :output, type: :string, aliases: "-o", desc: "Output file path"
|
|
9
|
+
class_option :direction, type: :string, aliases: "-d", desc: "Diagram direction (TB/BT/LR/RL)"
|
|
10
|
+
class_option :root, type: :string, aliases: "-r", desc: "Application root path"
|
|
11
|
+
|
|
12
|
+
desc "models", "Generate Mermaid model diagram"
|
|
13
|
+
method_option :brief, type: :boolean, aliases: "-b", desc: "Compact diagram (no attributes/methods)"
|
|
14
|
+
method_option :inheritance, type: :boolean, aliases: "-i", desc: "Include inheritance relationships"
|
|
15
|
+
method_option :exclude, type: :array, aliases: "-e", desc: "Exclude specified models"
|
|
16
|
+
method_option :specify, type: :array, aliases: "-s", desc: "Only process specified models"
|
|
17
|
+
method_option :all_models, type: :boolean, aliases: "-a", desc: "Include all models"
|
|
18
|
+
method_option :show_belongs_to, type: :boolean, desc: "Show belongs_to associations"
|
|
19
|
+
method_option :hide_through, type: :boolean, desc: "Hide through associations"
|
|
20
|
+
method_option :all_columns, type: :boolean, desc: "Show all columns"
|
|
21
|
+
method_option :hide_magic, type: :boolean, desc: "Hide magic fields (id, timestamps)"
|
|
22
|
+
method_option :hide_types, type: :boolean, desc: "Hide attribute types"
|
|
23
|
+
def models
|
|
24
|
+
load_rails_environment
|
|
25
|
+
setup_configuration
|
|
26
|
+
|
|
27
|
+
output_file = Lagoon.generate_model_diagram(build_options)
|
|
28
|
+
say "Model diagram generated: #{output_file}", :green
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
desc "controllers", "Generate Mermaid controller diagram"
|
|
32
|
+
method_option :brief, type: :boolean, aliases: "-b", desc: "Compact diagram (no attributes/methods)"
|
|
33
|
+
method_option :inheritance, type: :boolean, aliases: "-i", desc: "Include inheritance relationships"
|
|
34
|
+
method_option :exclude, type: :array, aliases: "-e", desc: "Exclude specified controllers"
|
|
35
|
+
method_option :specify, type: :array, aliases: "-s", desc: "Only process specified controllers"
|
|
36
|
+
method_option :hide_public, type: :boolean, desc: "Hide public methods"
|
|
37
|
+
method_option :hide_protected, type: :boolean, desc: "Hide protected methods"
|
|
38
|
+
method_option :hide_private, type: :boolean, desc: "Hide private methods"
|
|
39
|
+
def controllers
|
|
40
|
+
load_rails_environment
|
|
41
|
+
setup_configuration
|
|
42
|
+
|
|
43
|
+
output_file = Lagoon.generate_controller_diagram(build_options)
|
|
44
|
+
say "Controller diagram generated: #{output_file}", :green
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
desc "er", "Generate Mermaid ER diagram"
|
|
48
|
+
method_option :exclude, type: :array, aliases: "-e", desc: "Exclude specified tables"
|
|
49
|
+
method_option :specify, type: :array, aliases: "-s", desc: "Only process specified tables"
|
|
50
|
+
def er
|
|
51
|
+
load_rails_environment
|
|
52
|
+
setup_configuration
|
|
53
|
+
|
|
54
|
+
output_file = Lagoon.generate_er_diagram(build_options)
|
|
55
|
+
say "ER diagram generated: #{output_file}", :green
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
desc "all", "Generate all diagrams"
|
|
59
|
+
method_option :brief, type: :boolean, aliases: "-b", desc: "Compact diagrams (no attributes/methods)"
|
|
60
|
+
def all
|
|
61
|
+
load_rails_environment
|
|
62
|
+
setup_configuration
|
|
63
|
+
|
|
64
|
+
results = Lagoon.generate_all(build_options)
|
|
65
|
+
say "All diagrams generated:", :green
|
|
66
|
+
say " Models: #{results[:models]}", :green
|
|
67
|
+
say " Controllers: #{results[:controllers]}", :green
|
|
68
|
+
say " ER: #{results[:er]}", :green
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
desc "version", "Show version"
|
|
72
|
+
def version
|
|
73
|
+
say "Lagoon version #{Lagoon::VERSION}"
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
private
|
|
77
|
+
|
|
78
|
+
def load_rails_environment
|
|
79
|
+
rails_root = options[:root] || Dir.pwd
|
|
80
|
+
|
|
81
|
+
unless File.exist?(File.join(rails_root, "config", "environment.rb"))
|
|
82
|
+
say "Error: Rails application not found. Please run from Rails root or use --root option.", :red
|
|
83
|
+
exit 1
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
Dir.chdir(rails_root)
|
|
87
|
+
require File.expand_path("config/environment", rails_root)
|
|
88
|
+
rescue LoadError => e
|
|
89
|
+
say "Error loading Rails environment: #{e.message}", :red
|
|
90
|
+
exit 1
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def setup_configuration
|
|
94
|
+
Lagoon.configure do |config|
|
|
95
|
+
config.diagram_direction = options[:direction] if options[:direction]
|
|
96
|
+
config.show_attributes = !options[:brief] if options.key?(:brief)
|
|
97
|
+
config.show_methods = !options[:brief] if options.key?(:brief)
|
|
98
|
+
config.include_inheritance = options[:inheritance] if options.key?(:inheritance)
|
|
99
|
+
config.exclude_models = options[:exclude] if options[:exclude]
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def build_options
|
|
104
|
+
opts = options.dup
|
|
105
|
+
opts[:show_belongs_to] = true if opts[:show_belongs_to]
|
|
106
|
+
opts[:hide_through] = true if opts[:hide_through]
|
|
107
|
+
opts[:all_columns] = true if opts[:all_columns]
|
|
108
|
+
opts[:hide_magic] = true if opts[:hide_magic]
|
|
109
|
+
opts
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Lagoon
|
|
4
|
+
class Configuration
|
|
5
|
+
attr_accessor :output_dir, :diagram_direction, :show_attributes,
|
|
6
|
+
:show_methods, :include_inheritance, :exclude_models,
|
|
7
|
+
:exclude_controllers, :diagram_format
|
|
8
|
+
|
|
9
|
+
def initialize
|
|
10
|
+
@output_dir = "doc/diagrams"
|
|
11
|
+
@diagram_direction = "TB"
|
|
12
|
+
@show_attributes = true
|
|
13
|
+
@show_methods = false
|
|
14
|
+
@include_inheritance = true
|
|
15
|
+
@exclude_models = []
|
|
16
|
+
@exclude_controllers = []
|
|
17
|
+
@diagram_format = :class_diagram # or :er_diagram
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Lagoon
|
|
4
|
+
module Diagram
|
|
5
|
+
class Base
|
|
6
|
+
attr_reader :options, :config
|
|
7
|
+
|
|
8
|
+
def initialize(options = {})
|
|
9
|
+
@options = options
|
|
10
|
+
@config = Lagoon.configuration
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def generate
|
|
14
|
+
raise NotImplementedError, "Subclasses must implement #generate"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
protected
|
|
18
|
+
|
|
19
|
+
def output_path
|
|
20
|
+
@output_path ||= File.join(@config.output_dir, default_filename)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def default_filename
|
|
24
|
+
raise NotImplementedError, "Subclasses must implement #default_filename"
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def ensure_output_directory
|
|
28
|
+
FileUtils.mkdir_p(@config.output_dir)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def write_to_file(content)
|
|
32
|
+
ensure_output_directory
|
|
33
|
+
File.write(output_path, content)
|
|
34
|
+
output_path
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "fileutils"
|
|
4
|
+
|
|
5
|
+
module Lagoon
|
|
6
|
+
module Diagram
|
|
7
|
+
class ControllerDiagram < Base
|
|
8
|
+
def generate
|
|
9
|
+
parser = Parser::ControllerParser.new(@options)
|
|
10
|
+
parsed_data = parser.parse
|
|
11
|
+
|
|
12
|
+
renderer = Renderer::ClassDiagramRenderer.new(
|
|
13
|
+
direction: @options[:direction] || @config.diagram_direction
|
|
14
|
+
)
|
|
15
|
+
content = renderer.render(parsed_data)
|
|
16
|
+
|
|
17
|
+
output_file = @options[:output] || output_path
|
|
18
|
+
ensure_output_directory
|
|
19
|
+
File.write(output_file, content)
|
|
20
|
+
|
|
21
|
+
output_file
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
protected
|
|
25
|
+
|
|
26
|
+
def default_filename
|
|
27
|
+
"controllers.mermaid"
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "fileutils"
|
|
4
|
+
|
|
5
|
+
module Lagoon
|
|
6
|
+
module Diagram
|
|
7
|
+
class ErDiagram < Base
|
|
8
|
+
def generate
|
|
9
|
+
parser = Parser::SchemaParser.new(@options)
|
|
10
|
+
parsed_data = parser.parse
|
|
11
|
+
|
|
12
|
+
renderer = Renderer::ErDiagramRenderer.new(
|
|
13
|
+
direction: @options[:direction] || @config.diagram_direction
|
|
14
|
+
)
|
|
15
|
+
content = renderer.render(parsed_data)
|
|
16
|
+
|
|
17
|
+
output_file = @options[:output] || output_path
|
|
18
|
+
ensure_output_directory
|
|
19
|
+
File.write(output_file, content)
|
|
20
|
+
|
|
21
|
+
output_file
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
protected
|
|
25
|
+
|
|
26
|
+
def default_filename
|
|
27
|
+
"er_diagram.mermaid"
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "fileutils"
|
|
4
|
+
|
|
5
|
+
module Lagoon
|
|
6
|
+
module Diagram
|
|
7
|
+
class ModelDiagram < Base
|
|
8
|
+
def generate
|
|
9
|
+
parser = Parser::ModelParser.new(@options)
|
|
10
|
+
parsed_data = parser.parse
|
|
11
|
+
|
|
12
|
+
renderer = Renderer::ClassDiagramRenderer.new(
|
|
13
|
+
direction: @options[:direction] || @config.diagram_direction
|
|
14
|
+
)
|
|
15
|
+
content = renderer.render(parsed_data)
|
|
16
|
+
|
|
17
|
+
output_file = @options[:output] || output_path
|
|
18
|
+
ensure_output_directory
|
|
19
|
+
File.write(output_file, content)
|
|
20
|
+
|
|
21
|
+
output_file
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
protected
|
|
25
|
+
|
|
26
|
+
def default_filename
|
|
27
|
+
"models.mermaid"
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Lagoon
|
|
4
|
+
module Parser
|
|
5
|
+
class ControllerParser
|
|
6
|
+
attr_reader :options, :config
|
|
7
|
+
|
|
8
|
+
def initialize(options = {})
|
|
9
|
+
@options = options
|
|
10
|
+
@config = Lagoon.configuration
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def parse
|
|
14
|
+
controllers = load_controllers
|
|
15
|
+
classes = []
|
|
16
|
+
relationships = []
|
|
17
|
+
|
|
18
|
+
controllers.each do |controller|
|
|
19
|
+
next if excluded?(controller)
|
|
20
|
+
|
|
21
|
+
classes << parse_controller(controller)
|
|
22
|
+
relationships.concat(extract_inheritance(controller)) if config.include_inheritance
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
{
|
|
26
|
+
classes: classes,
|
|
27
|
+
relationships: relationships
|
|
28
|
+
}
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
private
|
|
32
|
+
|
|
33
|
+
def load_controllers
|
|
34
|
+
# Railsアプリケーションの全コントローラをロード
|
|
35
|
+
return [] unless defined?(Rails)
|
|
36
|
+
|
|
37
|
+
Rails.application.eager_load!
|
|
38
|
+
ActionController::Base.descendants
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def excluded?(controller)
|
|
42
|
+
controller_name = controller.name
|
|
43
|
+
config.exclude_controllers.include?(controller_name)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def parse_controller(controller)
|
|
47
|
+
{
|
|
48
|
+
name: controller.name,
|
|
49
|
+
abstract: false,
|
|
50
|
+
attributes: [],
|
|
51
|
+
methods: extract_methods(controller)
|
|
52
|
+
}
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def extract_methods(controller)
|
|
56
|
+
methods = []
|
|
57
|
+
|
|
58
|
+
# Public methods
|
|
59
|
+
unless options[:hide_public]
|
|
60
|
+
public_methods = controller.action_methods.to_a
|
|
61
|
+
methods.concat(public_methods.map { |m| { name: m, visibility: "+" } })
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# Protected methods
|
|
65
|
+
unless options[:hide_protected]
|
|
66
|
+
protected_methods = controller.protected_instance_methods(false)
|
|
67
|
+
methods.concat(protected_methods.map { |m| { name: m, visibility: "#" } })
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# Private methods
|
|
71
|
+
unless options[:hide_private]
|
|
72
|
+
private_methods = controller.private_instance_methods(false)
|
|
73
|
+
methods.concat(private_methods.map { |m| { name: m, visibility: "-" } })
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
methods
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def extract_inheritance(controller)
|
|
80
|
+
return [] if controller.superclass == ActionController::Base
|
|
81
|
+
return [] unless controller.superclass.name
|
|
82
|
+
|
|
83
|
+
[{
|
|
84
|
+
source: controller.superclass.name,
|
|
85
|
+
target: controller.name,
|
|
86
|
+
type: :inheritance,
|
|
87
|
+
label: nil
|
|
88
|
+
}]
|
|
89
|
+
rescue StandardError
|
|
90
|
+
[]
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|