rails_architect_analyzer 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/.github/workflows/tests.yml +52 -0
- data/.gitignore +39 -0
- data/.rubocop.yml +51 -0
- data/CHANGELOG.md +66 -0
- data/CODE_OF_CONDUCT.md +41 -0
- data/CONTRIBUTING.md +534 -0
- data/EXAMPLE_GEMFILE +11 -0
- data/Gemfile +12 -0
- data/INDEX.md +192 -0
- data/LICENSE.md +21 -0
- data/README.md +270 -0
- data/Rakefile +15 -0
- data/exe/rails_architect +6 -0
- data/lib/rails_architect/analyzers/architecture_analyzer.rb +148 -0
- data/lib/rails_architect/analyzers/bdd_analyzer.rb +160 -0
- data/lib/rails_architect/analyzers/solid_analyzer.rb +239 -0
- data/lib/rails_architect/analyzers/tdd_analyzer.rb +138 -0
- data/lib/rails_architect/cli.rb +83 -0
- data/lib/rails_architect/reporters/report_generator.rb +212 -0
- data/lib/rails_architect/version.rb +5 -0
- data/lib/rails_architect.rb +53 -0
- data/rails_architect.gemspec +34 -0
- metadata +136 -0
data/INDEX.md
ADDED
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
# 📚 Índice de Documentação - Rails Architect
|
|
2
|
+
|
|
3
|
+
## 🚀 Primeiros Passos
|
|
4
|
+
|
|
5
|
+
- **[QUICKSTART.md](QUICKSTART.md)** - Comece em minutos
|
|
6
|
+
- Instalação simples
|
|
7
|
+
- Primeiros comandos
|
|
8
|
+
- Interpretação de resultados
|
|
9
|
+
- Dicas de início rápido
|
|
10
|
+
|
|
11
|
+
## 📖 Documentação Principal
|
|
12
|
+
|
|
13
|
+
- **[README.md](README.md)** - Documentação completa
|
|
14
|
+
- Características
|
|
15
|
+
- Instalação detalhada
|
|
16
|
+
- Uso em linha de comando e código
|
|
17
|
+
- O que é analisado
|
|
18
|
+
- Padrões recomendados
|
|
19
|
+
- Roadmap
|
|
20
|
+
|
|
21
|
+
- **[CONTRIBUTING.md](CONTRIBUTING.md)** - Guia de contribuição
|
|
22
|
+
- Como contribuir
|
|
23
|
+
- Diretrizes
|
|
24
|
+
- Roadmap
|
|
25
|
+
- Referências
|
|
26
|
+
|
|
27
|
+
## 💻 Exemplos e Padrões
|
|
28
|
+
|
|
29
|
+
- **[REFACTORING_EXAMPLES.md](REFACTORING_EXAMPLES.md)** - Exemplos práticos
|
|
30
|
+
- Problema 1: Fat Models
|
|
31
|
+
- Problema 2: Fat Controllers
|
|
32
|
+
- Problema 3: Dependency Injection
|
|
33
|
+
- Problema 4: Falta de Testes
|
|
34
|
+
- Problema 5: DRY com Concerns
|
|
35
|
+
- Resumo de melhorias
|
|
36
|
+
|
|
37
|
+
## 📦 Publicação
|
|
38
|
+
|
|
39
|
+
- **[PUBLISHING.md](PUBLISHING.md)** - Publicar no RubyGems
|
|
40
|
+
- Configuração de credenciais
|
|
41
|
+
- Passos de publicação
|
|
42
|
+
- Checklist
|
|
43
|
+
- Troubleshooting
|
|
44
|
+
- Guia de versionamento
|
|
45
|
+
|
|
46
|
+
## 📝 Histórico
|
|
47
|
+
|
|
48
|
+
- **[CHANGELOG.md](CHANGELOG.md)** - Histórico de versões
|
|
49
|
+
- v0.1.0 - Versão inicial
|
|
50
|
+
- Planejado para futuras versões
|
|
51
|
+
|
|
52
|
+
## 📋 Código de Conduta
|
|
53
|
+
|
|
54
|
+
- **[CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md)** - Código de conduta
|
|
55
|
+
- Nossa promessa
|
|
56
|
+
- Padrões aceitáveis
|
|
57
|
+
- Responsabilidades
|
|
58
|
+
|
|
59
|
+
## 🔧 Referência Rápida
|
|
60
|
+
|
|
61
|
+
### Instalação
|
|
62
|
+
```bash
|
|
63
|
+
gem 'rails_architect'
|
|
64
|
+
bundle install
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Uso
|
|
68
|
+
```bash
|
|
69
|
+
rails_architect analyze # Análise completa
|
|
70
|
+
rails_architect suggest # Apenas sugestões
|
|
71
|
+
rails_architect analyze --json --output report.json
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Estrutura do Projeto
|
|
75
|
+
|
|
76
|
+
```
|
|
77
|
+
rails_architect/
|
|
78
|
+
├── lib/
|
|
79
|
+
│ ├── rails_architect.rb # Entrada principal
|
|
80
|
+
│ ├── rails_architect/
|
|
81
|
+
│ │ ├── version.rb # Versão
|
|
82
|
+
│ │ ├── cli.rb # Interface de linha de comando
|
|
83
|
+
│ │ ├── analyzers/ # Analisadores
|
|
84
|
+
│ │ │ ├── architecture_analyzer.rb
|
|
85
|
+
│ │ │ ├── tdd_analyzer.rb
|
|
86
|
+
│ │ │ ├── bdd_analyzer.rb
|
|
87
|
+
│ │ │ └── solid_analyzer.rb
|
|
88
|
+
│ │ └── reporters/ # Geradores de relatórios
|
|
89
|
+
│ │ └── report_generator.rb
|
|
90
|
+
├── exe/
|
|
91
|
+
│ └── rails_architect # Executável
|
|
92
|
+
├── spec/
|
|
93
|
+
│ └── rails_architect/
|
|
94
|
+
│ ├── rails_architect_spec.rb
|
|
95
|
+
│ └── analyzers/
|
|
96
|
+
│ └── architecture_analyzer_spec.rb
|
|
97
|
+
├── rails_architect.gemspec # Especificação da gem
|
|
98
|
+
├── Gemfile # Dependências
|
|
99
|
+
├── Rakefile # Tasks
|
|
100
|
+
├── README.md
|
|
101
|
+
├── QUICKSTART.md
|
|
102
|
+
├── CONTRIBUTING.md
|
|
103
|
+
├── REFACTORING_EXAMPLES.md
|
|
104
|
+
├── PUBLISHING.md
|
|
105
|
+
├── CODE_OF_CONDUCT.md
|
|
106
|
+
├── CHANGELOG.md
|
|
107
|
+
├── LICENSE.md
|
|
108
|
+
└── .gitignore
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Analisadores Disponíveis
|
|
112
|
+
|
|
113
|
+
1. **ArchitectureAnalyzer** (`lib/rails_architect/analyzers/architecture_analyzer.rb`)
|
|
114
|
+
- Valida estrutura padrão Rails
|
|
115
|
+
- Detecta padrões opcionais
|
|
116
|
+
- Encontra "fat models" e "fat controllers"
|
|
117
|
+
- Score: 0-100%
|
|
118
|
+
|
|
119
|
+
2. **TddAnalyzer** (`lib/rails_architect/analyzers/tdd_analyzer.rb`)
|
|
120
|
+
- Avalia cobertura de testes
|
|
121
|
+
- Conta testes por tipo
|
|
122
|
+
- Estima qualidade TDD
|
|
123
|
+
- Score: 0-100%
|
|
124
|
+
|
|
125
|
+
3. **BddAnalyzer** (`lib/rails_architect/analyzers/bdd_analyzer.rb`)
|
|
126
|
+
- Verifica BDD (Cucumber/RSpec)
|
|
127
|
+
- Analisa feature files
|
|
128
|
+
- Valida user stories
|
|
129
|
+
- Score: 0-100%
|
|
130
|
+
|
|
131
|
+
4. **SolidAnalyzer** (`lib/rails_architect/analyzers/solid_analyzer.rb`)
|
|
132
|
+
- Avalia 5 princípios SOLID
|
|
133
|
+
- Detecta violações
|
|
134
|
+
- Sugere refatorações
|
|
135
|
+
- Score: 0-100
|
|
136
|
+
|
|
137
|
+
### Reportes
|
|
138
|
+
|
|
139
|
+
**ReportGenerator** (`lib/rails_architect/reporters/report_generator.rb`)
|
|
140
|
+
- Gera relatórios coloridos
|
|
141
|
+
- Exporta para JSON
|
|
142
|
+
- Fornece recomendações
|
|
143
|
+
|
|
144
|
+
### CLI
|
|
145
|
+
|
|
146
|
+
**CLI** (`lib/rails_architect/cli.rb`)
|
|
147
|
+
- `analyze` - análise completa
|
|
148
|
+
- `suggest` - apenas sugestões
|
|
149
|
+
- `version` - mostrar versão
|
|
150
|
+
|
|
151
|
+
## ❓ Dúvidas Frequentes
|
|
152
|
+
|
|
153
|
+
### Como instalar?
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
### Como usar?
|
|
157
|
+
```bash
|
|
158
|
+
rails_architect analyze
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### Como interpretar os scores?
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
### Posso usar em meu projeto Rails?
|
|
165
|
+
Sim! A gem é compatível com Rails 6.0+.
|
|
166
|
+
|
|
167
|
+
### Como contribuir?
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
### Como publicar?
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
## 🔗 Links Úteis
|
|
174
|
+
|
|
175
|
+
- **GitHub**: https://github.com/daniel8486/rails_architect
|
|
176
|
+
- **RubyGems**: https://rubygems.org/gems/rails_architect
|
|
177
|
+
- **Issues**: https://github.com/daniel8486/rails_architect/issues
|
|
178
|
+
- **Discussions**: https://github.com/daniel8486/rails_architect/discussions
|
|
179
|
+
|
|
180
|
+
## 📞 Suporte
|
|
181
|
+
|
|
182
|
+
- 📧 Email: eu@danieldjam.dev.br | danielmatos404@gmail.com
|
|
183
|
+
- 🐛 Bugs: Abra uma issue no GitHub
|
|
184
|
+
- 💬 Dúvidas: Inicie uma discussão no GitHub
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
**Última atualização:** 8 de dezembro de 2025
|
|
189
|
+
|
|
190
|
+
**Versão:** 0.1.0
|
|
191
|
+
|
|
192
|
+
**Licença:** MIT
|
data/LICENSE.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Daniel Matos
|
|
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 all
|
|
13
|
+
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 THE
|
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
# Rails Architect
|
|
2
|
+
|
|
3
|
+
🏗️ Uma gem Ruby para análise completa de projetos Rails com foco em arquitetura, TDD, BDD e princípios SOLID.
|
|
4
|
+
|
|
5
|
+
## Características
|
|
6
|
+
|
|
7
|
+
- **📐 Análise de Arquitetura**: Verifica a estrutura padrão do Rails e recomenda padrões opcionais
|
|
8
|
+
- **🧪 Análise TDD**: Avalia cobertura de testes e sugere melhorias
|
|
9
|
+
- **🎯 Análise BDD**: Identifica funcionalidades BDD com Cucumber e RSpec
|
|
10
|
+
- **⚡ Análise SOLID**: Avalia cada princípio SOLID do seu código
|
|
11
|
+
- **💡 Sugestões Inteligentes**: Recomendações específicas para seu projeto
|
|
12
|
+
- **📊 Relatórios Detalhados**: Saída colorida e JSON exportável
|
|
13
|
+
|
|
14
|
+
## Instalação
|
|
15
|
+
|
|
16
|
+
Adicione à seu Gemfile:
|
|
17
|
+
|
|
18
|
+
```ruby
|
|
19
|
+
gem 'rails_architect'
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Depois execute:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
bundle install
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Uso
|
|
29
|
+
|
|
30
|
+
### Linha de Comando
|
|
31
|
+
|
|
32
|
+
Analisar seu projeto Rails atual:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
rails_architect analyze
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Analisar um projeto específico:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
rails_architect analyze /caminho/para/seu/projeto
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Obter sugestões de arquitetura:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
rails_architect suggest
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Salvar relatório em JSON:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
rails_architect analyze --json --output report.json
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Salvar relatório em arquivo de texto:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
rails_architect analyze --output report.txt
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Dentro do Código Rails
|
|
63
|
+
|
|
64
|
+
```ruby
|
|
65
|
+
# Analisar projeto atual
|
|
66
|
+
results = RailsArchitect.analyze
|
|
67
|
+
|
|
68
|
+
# Analisar projeto específico
|
|
69
|
+
results = RailsArchitect.analyze('/caminho/para/seu/projeto')
|
|
70
|
+
|
|
71
|
+
# Acessar resultados específicos
|
|
72
|
+
results[:architecture][:score] # Score de arquitetura (0-100)
|
|
73
|
+
results[:tdd][:score][:score] # Score de cobertura TDD
|
|
74
|
+
results[:bdd][:score][:rating] # Rating de BDD
|
|
75
|
+
results[:solid][:score][:score] # Score SOLID (0-100)
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## O que é Analisado?
|
|
79
|
+
|
|
80
|
+
### 📐 Arquitetura Rails
|
|
81
|
+
|
|
82
|
+
- Estrutura padrão de diretórios
|
|
83
|
+
- Padrões opcionais (Services, Decorators, Policies, Presenters, Interactors, etc.)
|
|
84
|
+
- Detecção de "fat models" e "fat controllers"
|
|
85
|
+
- Qualidade de organização de helpers
|
|
86
|
+
|
|
87
|
+
### 🧪 Test-Driven Development (TDD)
|
|
88
|
+
|
|
89
|
+
- Cobertura de testes (modelo de estimativa)
|
|
90
|
+
- Número de testes por tipo (models, controllers, services, etc.)
|
|
91
|
+
- Uso de RSpec vs Minitest
|
|
92
|
+
- Sugestões para melhorar cobertura
|
|
93
|
+
|
|
94
|
+
### 🎯 Behavior-Driven Development (BDD)
|
|
95
|
+
|
|
96
|
+
- Presença de Cucumber
|
|
97
|
+
- Número de feature files e step definitions
|
|
98
|
+
- Análise de cenários legíveis (Given/When/Then)
|
|
99
|
+
- Testes de integração (request specs)
|
|
100
|
+
|
|
101
|
+
### ⚡ Princípios SOLID
|
|
102
|
+
|
|
103
|
+
1. **Single Responsibility**: Detecta classes com múltiplas responsabilidades
|
|
104
|
+
2. **Open/Closed**: Verifica uso de concerns e herança
|
|
105
|
+
3. **Liskov Substitution**: Analisa cadeias de herança
|
|
106
|
+
4. **Interface Segregation**: Detecta módulos e classes muito grandes
|
|
107
|
+
5. **Dependency Inversion**: Avalia uso de service layer e injeção de dependência
|
|
108
|
+
|
|
109
|
+
## Saída de Exemplo
|
|
110
|
+
|
|
111
|
+
```
|
|
112
|
+
================================================================================
|
|
113
|
+
🏗️ RAILS ARCHITECT - PROJECT ANALYSIS REPORT
|
|
114
|
+
================================================================================
|
|
115
|
+
|
|
116
|
+
📐 ARCHITECTURE ANALYSIS
|
|
117
|
+
────────────────────────────────────────────────────────────────────────────────
|
|
118
|
+
Overall Score: 65%
|
|
119
|
+
|
|
120
|
+
✓ Existing Directories (9/10):
|
|
121
|
+
✅ app/models (8 files)
|
|
122
|
+
✅ app/controllers (12 files)
|
|
123
|
+
✅ app/views (45 files)
|
|
124
|
+
...
|
|
125
|
+
|
|
126
|
+
💡 Suggestions:
|
|
127
|
+
• Consider creating 'app/services' directory for business logic
|
|
128
|
+
• Create 'app/decorators' for separating presentation logic from models
|
|
129
|
+
...
|
|
130
|
+
|
|
131
|
+
🧪 TEST-DRIVEN DEVELOPMENT (TDD) ANALYSIS
|
|
132
|
+
────────────────────────────────────────────────────────────────────────────────
|
|
133
|
+
Coverage Score: 45.5% ⚠️ Fair
|
|
134
|
+
|
|
135
|
+
Test Files:
|
|
136
|
+
• Spec files: 28
|
|
137
|
+
• Test files: 0
|
|
138
|
+
• Total: 28
|
|
139
|
+
|
|
140
|
+
...
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## Configuração
|
|
144
|
+
|
|
145
|
+
A gem funciona out-of-the-box. Coloque na raiz do seu projeto Rails:
|
|
146
|
+
|
|
147
|
+
```ruby
|
|
148
|
+
# config/initializers/rails_architect.rb (opcional)
|
|
149
|
+
# Configurações futuras
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
## Padrões Recomendados
|
|
153
|
+
|
|
154
|
+
### 1. Services (app/services)
|
|
155
|
+
|
|
156
|
+
```ruby
|
|
157
|
+
# app/services/user_creator.rb
|
|
158
|
+
class UserCreator
|
|
159
|
+
def initialize(user_params)
|
|
160
|
+
@user_params = user_params
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
def call
|
|
164
|
+
User.create(@user_params)
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
# Uso
|
|
169
|
+
UserCreator.new(params).call
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### 2. Decorators (app/decorators)
|
|
173
|
+
|
|
174
|
+
```ruby
|
|
175
|
+
# app/decorators/user_decorator.rb
|
|
176
|
+
class UserDecorator
|
|
177
|
+
def initialize(user)
|
|
178
|
+
@user = user
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
def full_name_with_email
|
|
182
|
+
"#{@user.full_name} <#{@user.email}>"
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### 3. Concerns (app/concerns)
|
|
188
|
+
|
|
189
|
+
```ruby
|
|
190
|
+
# app/concerns/timestampable.rb
|
|
191
|
+
module Timestampable
|
|
192
|
+
extend ActiveSupport::Concern
|
|
193
|
+
|
|
194
|
+
included do
|
|
195
|
+
before_save :update_timestamps
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
def update_timestamps
|
|
199
|
+
self.updated_at = Time.current
|
|
200
|
+
end
|
|
201
|
+
end
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
### 4. Policies (app/policies) com Pundit
|
|
205
|
+
|
|
206
|
+
```ruby
|
|
207
|
+
# app/policies/post_policy.rb
|
|
208
|
+
class PostPolicy
|
|
209
|
+
def initialize(user, post)
|
|
210
|
+
@user = user
|
|
211
|
+
@post = post
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
def update?
|
|
215
|
+
@user == @post.author
|
|
216
|
+
end
|
|
217
|
+
end
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### 5. Presenters (app/presenters)
|
|
221
|
+
|
|
222
|
+
```ruby
|
|
223
|
+
# app/presenters/dashboard_presenter.rb
|
|
224
|
+
class DashboardPresenter
|
|
225
|
+
def initialize(user)
|
|
226
|
+
@user = user
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
def total_posts
|
|
230
|
+
@user.posts.count
|
|
231
|
+
end
|
|
232
|
+
end
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
## Melhorias Futuras
|
|
236
|
+
|
|
237
|
+
- [ ] Análise de performance
|
|
238
|
+
- [ ] Detecção de code smells
|
|
239
|
+
- [ ] Sugestões de gems para padrões
|
|
240
|
+
- [ ] Integração com CI/CD
|
|
241
|
+
- [ ] Dashboard web
|
|
242
|
+
- [ ] Comparação entre projetos
|
|
243
|
+
- [ ] Análise histórica
|
|
244
|
+
|
|
245
|
+
## Contribuindo
|
|
246
|
+
|
|
247
|
+
1. Faça um fork
|
|
248
|
+
2. Crie uma branch para sua feature (`git checkout -b feature/AmazingFeature`)
|
|
249
|
+
3. Commit suas mudanças (`git commit -m 'Add some AmazingFeature'`)
|
|
250
|
+
4. Push para a branch (`git push origin feature/AmazingFeature`)
|
|
251
|
+
5. Abra um Pull Request
|
|
252
|
+
|
|
253
|
+
## Licença
|
|
254
|
+
|
|
255
|
+
MIT License - veja LICENSE.md para detalhes
|
|
256
|
+
|
|
257
|
+
## Changelog
|
|
258
|
+
|
|
259
|
+
### v0.1.0
|
|
260
|
+
- Versão inicial com análise de arquitetura, TDD, BDD e SOLID
|
|
261
|
+
- CLI completa com múltiplas opções de saída
|
|
262
|
+
- Relatórios detalhados e coloridos
|
|
263
|
+
|
|
264
|
+
## Autor
|
|
265
|
+
|
|
266
|
+
Daniel Matos - [@daniel8486](https://github.com/daniel8486)
|
|
267
|
+
|
|
268
|
+
## Suporte
|
|
269
|
+
|
|
270
|
+
Para reportar bugs ou sugerir features, abra uma issue no [GitHub](https://github.com/daniel8486/rails_architect/issues).
|
data/Rakefile
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "bundler/gem_tasks"
|
|
4
|
+
require "rspec/core/rake_task"
|
|
5
|
+
|
|
6
|
+
RSpec::Core::RakeTask.new(:spec)
|
|
7
|
+
|
|
8
|
+
task default: :spec
|
|
9
|
+
|
|
10
|
+
desc "Open an IRB session with the gem loaded"
|
|
11
|
+
task :console do
|
|
12
|
+
require "irb"
|
|
13
|
+
require "rails_architect"
|
|
14
|
+
IRB.start(__FILE__)
|
|
15
|
+
end
|
data/exe/rails_architect
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "fileutils"
|
|
4
|
+
|
|
5
|
+
module RailsArchitect
|
|
6
|
+
module Analyzers
|
|
7
|
+
# Analyzes Rails project architecture, structure, and design patterns
|
|
8
|
+
class ArchitectureAnalyzer
|
|
9
|
+
STANDARD_DIRS = %w[
|
|
10
|
+
app/models
|
|
11
|
+
app/controllers
|
|
12
|
+
app/views
|
|
13
|
+
app/helpers
|
|
14
|
+
app/services
|
|
15
|
+
app/decorators
|
|
16
|
+
app/policies
|
|
17
|
+
app/validators
|
|
18
|
+
config
|
|
19
|
+
lib
|
|
20
|
+
spec
|
|
21
|
+
].freeze
|
|
22
|
+
|
|
23
|
+
attr_reader :project_path
|
|
24
|
+
|
|
25
|
+
def initialize(project_path = Rails.root)
|
|
26
|
+
@project_path = project_path
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def analyze
|
|
30
|
+
{
|
|
31
|
+
score: calculate_score,
|
|
32
|
+
structure: check_structure,
|
|
33
|
+
suggestions: generate_suggestions,
|
|
34
|
+
missing_dirs: missing_directories,
|
|
35
|
+
optional_dirs: check_optional_dirs
|
|
36
|
+
}
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
private
|
|
40
|
+
|
|
41
|
+
def calculate_score
|
|
42
|
+
existing = existing_directories.count
|
|
43
|
+
total = STANDARD_DIRS.count
|
|
44
|
+
((existing.to_f / total) * 100).round(2)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def check_structure
|
|
48
|
+
STANDARD_DIRS.map do |dir|
|
|
49
|
+
full_path = File.join(project_path, dir)
|
|
50
|
+
{
|
|
51
|
+
name: dir,
|
|
52
|
+
exists: File.directory?(full_path),
|
|
53
|
+
files_count: count_files(full_path)
|
|
54
|
+
}
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def missing_directories
|
|
59
|
+
STANDARD_DIRS.reject { |dir| File.directory?(File.join(project_path, dir)) }
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def existing_directories
|
|
63
|
+
STANDARD_DIRS.select { |dir| File.directory?(File.join(project_path, dir)) }
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def check_optional_dirs
|
|
67
|
+
optional = {
|
|
68
|
+
"app/services" => "Service Objects",
|
|
69
|
+
"app/decorators" => "Decorator Pattern",
|
|
70
|
+
"app/policies" => "Authorization Policies",
|
|
71
|
+
"app/validators" => "Custom Validators",
|
|
72
|
+
"app/presenters" => "Presenter Pattern",
|
|
73
|
+
"app/interactors" => "Interactors/Use Cases",
|
|
74
|
+
"app/concerns" => "Shared Concerns"
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
optional.map do |dir, description|
|
|
78
|
+
full_path = File.join(project_path, dir)
|
|
79
|
+
{
|
|
80
|
+
name: dir,
|
|
81
|
+
description: description,
|
|
82
|
+
exists: File.directory?(full_path)
|
|
83
|
+
}
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def generate_suggestions
|
|
88
|
+
suggestions = []
|
|
89
|
+
|
|
90
|
+
if missing_directories.include?("app/services")
|
|
91
|
+
suggestions << "Consider creating 'app/services' directory for business logic"
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
if missing_directories.include?("app/decorators")
|
|
95
|
+
suggestions << "Create 'app/decorators' for separating presentation logic from models"
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
if missing_directories.include?("app/policies")
|
|
99
|
+
suggestions << "Implement 'app/policies' directory for authorization logic (using Pundit)"
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
suggestions << "⚠️ Detected fat models. Consider extracting logic to services or concerns" if fat_models?
|
|
103
|
+
|
|
104
|
+
suggestions << "⚠️ Detected fat controllers. Move business logic to services" if fat_controllers?
|
|
105
|
+
|
|
106
|
+
if poorly_organized_helpers?
|
|
107
|
+
suggestions << "Refactor helpers - consider moving logic to presenters or decorators"
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
suggestions
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def fat_models?
|
|
114
|
+
models_path = File.join(project_path, "app/models")
|
|
115
|
+
return false unless File.directory?(models_path)
|
|
116
|
+
|
|
117
|
+
Dir.glob(File.join(models_path, "*.rb")).any? do |file|
|
|
118
|
+
File.readlines(file).count > 200
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def fat_controllers?
|
|
123
|
+
controllers_path = File.join(project_path, "app/controllers")
|
|
124
|
+
return false unless File.directory?(controllers_path)
|
|
125
|
+
|
|
126
|
+
Dir.glob(File.join(controllers_path, "**/*.rb")).any? do |file|
|
|
127
|
+
File.readlines(file).count > 150
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def poorly_organized_helpers?
|
|
132
|
+
helpers_path = File.join(project_path, "app/helpers")
|
|
133
|
+
return false unless File.directory?(helpers_path)
|
|
134
|
+
|
|
135
|
+
helper_files = Dir.glob(File.join(helpers_path, "*.rb"))
|
|
136
|
+
helper_files.any? do |file|
|
|
137
|
+
File.readlines(file).count > 100
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def count_files(path)
|
|
142
|
+
return 0 unless File.directory?(path)
|
|
143
|
+
|
|
144
|
+
Dir.glob(File.join(path, "**/*.rb")).count
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
end
|