railsforge 1.0.1 → 2.0.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 +4 -4
- data/README.md +105 -444
- data/lib/railsforge/analyzers/controller_analyzer.rb +29 -55
- data/lib/railsforge/analyzers/database_analyzer.rb +16 -30
- data/lib/railsforge/analyzers/metrics_analyzer.rb +8 -22
- data/lib/railsforge/analyzers/model_analyzer.rb +29 -46
- data/lib/railsforge/analyzers/performance_analyzer.rb +34 -94
- data/lib/railsforge/analyzers/refactor_analyzer.rb +77 -57
- data/lib/railsforge/analyzers/security_analyzer.rb +34 -91
- data/lib/railsforge/analyzers/spec_analyzer.rb +17 -31
- data/lib/railsforge/cli.rb +14 -636
- data/lib/railsforge/cli_minimal.rb +8 -55
- data/lib/railsforge/doctor.rb +52 -225
- data/lib/railsforge/formatter.rb +102 -0
- data/lib/railsforge/issue.rb +23 -0
- data/lib/railsforge/loader.rb +5 -54
- data/lib/railsforge/version.rb +1 -1
- metadata +16 -77
- data/lib/railsforge/api_generator.rb +0 -397
- data/lib/railsforge/audit.rb +0 -289
- data/lib/railsforge/config.rb +0 -181
- data/lib/railsforge/database_analyzer.rb +0 -300
- data/lib/railsforge/feature_generator.rb +0 -560
- data/lib/railsforge/generator.rb +0 -313
- data/lib/railsforge/generators/base_generator.rb +0 -70
- data/lib/railsforge/generators/demo_generator.rb +0 -307
- data/lib/railsforge/generators/devops_generator.rb +0 -287
- data/lib/railsforge/generators/monitoring_generator.rb +0 -134
- data/lib/railsforge/generators/service_generator.rb +0 -122
- data/lib/railsforge/generators/stimulus_controller_generator.rb +0 -129
- data/lib/railsforge/generators/test_generator.rb +0 -289
- data/lib/railsforge/generators/view_component_generator.rb +0 -169
- data/lib/railsforge/graph.rb +0 -270
- data/lib/railsforge/mailer_generator.rb +0 -191
- data/lib/railsforge/plugins/plugin_loader.rb +0 -60
- data/lib/railsforge/plugins.rb +0 -30
- data/lib/railsforge/profiles.rb +0 -99
- data/lib/railsforge/refactor_analyzer.rb +0 -401
- data/lib/railsforge/refactor_controller.rb +0 -277
- data/lib/railsforge/refactors/refactor_controller.rb +0 -117
- data/lib/railsforge/template_loader.rb +0 -105
- data/lib/railsforge/templates/v1/form/spec_template.rb +0 -18
- data/lib/railsforge/templates/v1/form/template.rb +0 -28
- data/lib/railsforge/templates/v1/job/spec_template.rb +0 -17
- data/lib/railsforge/templates/v1/job/template.rb +0 -13
- data/lib/railsforge/templates/v1/policy/spec_template.rb +0 -41
- data/lib/railsforge/templates/v1/policy/template.rb +0 -57
- data/lib/railsforge/templates/v1/presenter/spec_template.rb +0 -12
- data/lib/railsforge/templates/v1/presenter/template.rb +0 -13
- data/lib/railsforge/templates/v1/query/spec_template.rb +0 -12
- data/lib/railsforge/templates/v1/query/template.rb +0 -16
- data/lib/railsforge/templates/v1/serializer/spec_template.rb +0 -13
- data/lib/railsforge/templates/v1/serializer/template.rb +0 -11
- data/lib/railsforge/templates/v1/service/spec_template.rb +0 -12
- data/lib/railsforge/templates/v1/service/template.rb +0 -25
- data/lib/railsforge/templates/v1/stimulus_controller/template.rb +0 -35
- data/lib/railsforge/templates/v1/view_component/template.rb +0 -24
- data/lib/railsforge/templates/v2/job/template.rb +0 -49
- data/lib/railsforge/templates/v2/query/template.rb +0 -66
- data/lib/railsforge/templates/v2/service/spec_template.rb +0 -33
- data/lib/railsforge/templates/v2/service/template.rb +0 -71
- data/lib/railsforge/templates/v3/job/template.rb +0 -72
- data/lib/railsforge/templates/v3/query/spec_template.rb +0 -54
- data/lib/railsforge/templates/v3/query/template.rb +0 -115
- data/lib/railsforge/templates/v3/service/spec_template.rb +0 -51
- data/lib/railsforge/templates/v3/service/template.rb +0 -93
- data/lib/railsforge/wizard.rb +0 -265
- data/lib/railsforge/wizard_tui.rb +0 -286
data/lib/railsforge/cli.rb
CHANGED
|
@@ -1,671 +1,49 @@
|
|
|
1
|
-
# CLI
|
|
2
|
-
#
|
|
1
|
+
# CLI — RailsForge v2 command dispatcher
|
|
2
|
+
# Supported commands: doctor
|
|
3
3
|
|
|
4
4
|
module RailsForge
|
|
5
|
-
# CLI class handles command-line interface
|
|
6
5
|
class CLI
|
|
7
|
-
# Main entry point
|
|
8
6
|
def self.start(args)
|
|
9
7
|
command = args.shift
|
|
10
8
|
|
|
11
9
|
case command
|
|
12
|
-
when "new"
|
|
13
|
-
handle_new_command(args)
|
|
14
|
-
when "generate", "g"
|
|
15
|
-
handle_generate_command(args)
|
|
16
|
-
when "analyze", "a"
|
|
17
|
-
handle_analyze_command(args)
|
|
18
|
-
when "refactor", "r"
|
|
19
|
-
handle_refactor_command(args)
|
|
20
10
|
when "doctor"
|
|
21
11
|
handle_doctor_command(args)
|
|
22
|
-
when "audit"
|
|
23
|
-
handle_audit_command(args)
|
|
24
|
-
when "graph"
|
|
25
|
-
handle_graph_command(args)
|
|
26
|
-
when "wizard", "wiz"
|
|
27
|
-
handle_wizard_command(args)
|
|
28
|
-
when "plugins", "plug"
|
|
29
|
-
handle_plugins_command(args)
|
|
30
|
-
when "config", "cfg"
|
|
31
|
-
handle_config_command(args)
|
|
32
|
-
when "profiles"
|
|
33
|
-
puts RailsForge::Profile.show_available
|
|
34
12
|
when "--version", "-v"
|
|
35
13
|
puts "RailsForge #{VERSION}"
|
|
36
14
|
when nil, "--help", "-h"
|
|
37
15
|
display_help
|
|
38
16
|
else
|
|
39
17
|
puts "Unknown command: #{command}"
|
|
40
|
-
|
|
18
|
+
puts "Run `railsforge --help` for usage."
|
|
41
19
|
exit 1
|
|
42
20
|
end
|
|
43
21
|
end
|
|
44
22
|
|
|
45
|
-
# Display help
|
|
46
23
|
def self.display_help
|
|
47
24
|
puts <<~HELP
|
|
48
|
-
RailsForge
|
|
25
|
+
RailsForge — Rails application health diagnostics
|
|
49
26
|
|
|
50
27
|
Usage:
|
|
51
|
-
railsforge
|
|
52
|
-
railsforge
|
|
53
|
-
railsforge
|
|
54
|
-
railsforge
|
|
55
|
-
railsforge generate demo <name> Generate a demo project
|
|
56
|
-
railsforge generate devops Generate Docker/CI-CD configs
|
|
57
|
-
railsforge generate monitoring Generate Sentry/Lograge configs
|
|
58
|
-
railsforge generate test <name> Generate test files
|
|
59
|
-
railsforge analyze Analyze code quality
|
|
60
|
-
railsforge doctor Full project health check
|
|
61
|
-
railsforge audit Architecture audit
|
|
62
|
-
railsforge graph Dependency graph
|
|
63
|
-
railsforge refactor Refactoring suggestions
|
|
64
|
-
railsforge wizard Interactive project setup
|
|
65
|
-
railsforge plugins Plugin management
|
|
66
|
-
railsforge config Configuration
|
|
67
|
-
railsforge profiles List available profiles
|
|
68
|
-
railsforge --version, -v Show version
|
|
69
|
-
railsforge --help, -h Show this help
|
|
28
|
+
railsforge doctor Run full diagnostic scan
|
|
29
|
+
railsforge doctor --format=json Output as JSON
|
|
30
|
+
railsforge --version Show version
|
|
31
|
+
railsforge --help Show this help
|
|
70
32
|
HELP
|
|
71
33
|
end
|
|
72
34
|
|
|
73
|
-
# Handle new command
|
|
74
|
-
def self.handle_new_command(args)
|
|
75
|
-
options = {}
|
|
76
|
-
app_name = nil
|
|
77
|
-
interactive = true
|
|
78
|
-
|
|
79
|
-
args.each do |arg|
|
|
80
|
-
if arg.start_with?("--")
|
|
81
|
-
key, value = arg[2..].split("=", 2)
|
|
82
|
-
interactive = false
|
|
83
|
-
case key
|
|
84
|
-
when "auth"
|
|
85
|
-
options[:auth] = value || "devise"
|
|
86
|
-
when "admin"
|
|
87
|
-
options[:admin] = value || "activeadmin"
|
|
88
|
-
when "jobs"
|
|
89
|
-
options[:jobs] = value || "sidekiq"
|
|
90
|
-
when "profile"
|
|
91
|
-
options[:profile] = value
|
|
92
|
-
end
|
|
93
|
-
elsif !arg.start_with?("-") && app_name.nil?
|
|
94
|
-
app_name = arg
|
|
95
|
-
end
|
|
96
|
-
end
|
|
97
|
-
|
|
98
|
-
if app_name.nil?
|
|
99
|
-
puts "Usage: railsforge new <app_name> [options]"
|
|
100
|
-
exit 1
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
if interactive
|
|
104
|
-
options = prompt_for_features(app_name)
|
|
105
|
-
end
|
|
106
|
-
|
|
107
|
-
begin
|
|
108
|
-
result = RailsForge::Generator.create_app(app_name, options)
|
|
109
|
-
puts "\n#{result}"
|
|
110
|
-
rescue => e
|
|
111
|
-
puts "Error: #{e.message}"
|
|
112
|
-
exit 1
|
|
113
|
-
end
|
|
114
|
-
end
|
|
115
|
-
|
|
116
|
-
# Prompt for features
|
|
117
|
-
def self.prompt_for_features(app_name)
|
|
118
|
-
options = {}
|
|
119
|
-
puts "\n#{'=' * 50}"
|
|
120
|
-
puts "RailsForge Interactive Setup"
|
|
121
|
-
puts "#{'=' * 50}"
|
|
122
|
-
|
|
123
|
-
if prompt_yes_no("Add authentication?")
|
|
124
|
-
options[:auth] = "devise"
|
|
125
|
-
end
|
|
126
|
-
|
|
127
|
-
if prompt_yes_no("Add admin panel?")
|
|
128
|
-
options[:admin] = "activeadmin"
|
|
129
|
-
end
|
|
130
|
-
|
|
131
|
-
if prompt_yes_no("Add background jobs?")
|
|
132
|
-
options[:jobs] = "sidekiq"
|
|
133
|
-
end
|
|
134
|
-
|
|
135
|
-
options
|
|
136
|
-
end
|
|
137
|
-
|
|
138
|
-
# Prompt yes/no
|
|
139
|
-
def self.prompt_yes_no(question, default: false)
|
|
140
|
-
suffix = default ? " [Y/n]" : " [y/N]"
|
|
141
|
-
print "#{question}#{suffix}: "
|
|
142
|
-
answer = STDIN.gets.strip.downcase
|
|
143
|
-
return default if answer.empty?
|
|
144
|
-
answer == "y" || answer == "yes"
|
|
145
|
-
end
|
|
146
|
-
|
|
147
|
-
# Handle generate command
|
|
148
|
-
def self.handle_generate_command(args)
|
|
149
|
-
template_version = "v1"
|
|
150
|
-
dry_run = false
|
|
151
|
-
|
|
152
|
-
# Parse options
|
|
153
|
-
args = args.reject do |arg|
|
|
154
|
-
if arg.start_with?("--template=")
|
|
155
|
-
template_version = arg.split("=").last
|
|
156
|
-
true
|
|
157
|
-
elsif arg == "--dry-run"
|
|
158
|
-
dry_run = true
|
|
159
|
-
true
|
|
160
|
-
else
|
|
161
|
-
false
|
|
162
|
-
end
|
|
163
|
-
end
|
|
164
|
-
|
|
165
|
-
generator_type = args.shift
|
|
166
|
-
names = args # Multiple names allowed for bulk generation
|
|
167
|
-
|
|
168
|
-
# Generators that don't require names
|
|
169
|
-
no_name_generators = ["devops", "ops", "monitoring", "mon"]
|
|
170
|
-
|
|
171
|
-
# Handle bulk generation
|
|
172
|
-
if names.empty? && generator_type && !no_name_generators.include?(generator_type)
|
|
173
|
-
puts "Error: Name required"
|
|
174
|
-
exit 1
|
|
175
|
-
end
|
|
176
|
-
|
|
177
|
-
case generator_type
|
|
178
|
-
when "service", "s"
|
|
179
|
-
handle_generate_bulk(:service, names, template_version, dry_run)
|
|
180
|
-
when "query", "q"
|
|
181
|
-
handle_generate_bulk(:query, names, template_version, dry_run)
|
|
182
|
-
when "job", "j"
|
|
183
|
-
handle_generate_bulk(:job, names, template_version, dry_run)
|
|
184
|
-
when "form", "f"
|
|
185
|
-
handle_generate_bulk(:form, names, template_version, dry_run)
|
|
186
|
-
when "presenter", "p"
|
|
187
|
-
handle_generate_bulk(:presenter, names, template_version, dry_run)
|
|
188
|
-
when "policy", "pol"
|
|
189
|
-
handle_generate_bulk(:policy, names, template_version, dry_run)
|
|
190
|
-
when "serializer", "ser"
|
|
191
|
-
handle_generate_bulk(:serializer, names, template_version, dry_run)
|
|
192
|
-
when "component", "c"
|
|
193
|
-
handle_generate_bulk(:component, names, template_version, dry_run)
|
|
194
|
-
when "stimulus", "stim"
|
|
195
|
-
handle_generate_bulk(:stimulus, names, template_version, dry_run)
|
|
196
|
-
when "demo"
|
|
197
|
-
handle_generate_demo(args, names.first)
|
|
198
|
-
when "devops", "ops"
|
|
199
|
-
handle_generate_devops(args)
|
|
200
|
-
when "monitoring", "mon"
|
|
201
|
-
handle_generate_monitoring(args)
|
|
202
|
-
when "test", "t"
|
|
203
|
-
handle_generate_test(args, names.first)
|
|
204
|
-
when "mailer", "mail"
|
|
205
|
-
handle_generate_bulk(:mailer, names, template_version, dry_run)
|
|
206
|
-
when "feature", "feat"
|
|
207
|
-
handle_generate_feature(args, names.first)
|
|
208
|
-
when "api"
|
|
209
|
-
handle_generate_api(args, names.first)
|
|
210
|
-
else
|
|
211
|
-
puts "Usage: railsforge generate <type> <name> [<name>...]"
|
|
212
|
-
puts "Types: service, query, job, form, presenter, policy, serializer, component, stimulus, mailer, feature, api"
|
|
213
|
-
puts "Options: --template=v2, --dry-run"
|
|
214
|
-
exit 1
|
|
215
|
-
end
|
|
216
|
-
end
|
|
217
|
-
|
|
218
|
-
# Handle bulk generation
|
|
219
|
-
def self.handle_generate_bulk(type, names, template_version, dry_run)
|
|
220
|
-
if dry_run
|
|
221
|
-
puts "Dry run - would generate:"
|
|
222
|
-
names.each { |name| puts " - #{type}: #{name} (template: #{template_version})" }
|
|
223
|
-
return
|
|
224
|
-
end
|
|
225
|
-
|
|
226
|
-
results = []
|
|
227
|
-
names.each do |name|
|
|
228
|
-
result = generate_single(type, name, template_version)
|
|
229
|
-
results << result
|
|
230
|
-
end
|
|
231
|
-
|
|
232
|
-
puts results.join("\n")
|
|
233
|
-
end
|
|
234
|
-
|
|
235
|
-
# Generate a single item
|
|
236
|
-
def self.generate_single(type, name, template_version)
|
|
237
|
-
case type
|
|
238
|
-
when :service
|
|
239
|
-
"Generating service: #{name}" + "\n" + RailsForge::Generators::ServiceGenerator.generate(name, with_spec: true, template_version: template_version)
|
|
240
|
-
when :query
|
|
241
|
-
"Generating query: #{name}"
|
|
242
|
-
when :job
|
|
243
|
-
"Generating job: #{name}"
|
|
244
|
-
when :component
|
|
245
|
-
"Generating component: #{name}" + "\n" + RailsForge::Generators::ViewComponentGenerator.new(name, template_version: template_version).generate
|
|
246
|
-
when :stimulus
|
|
247
|
-
"Generating stimulus: #{name}" + "\n" + RailsForge::Generators::StimulusControllerGenerator.new(name, template_version: template_version).generate
|
|
248
|
-
else
|
|
249
|
-
"Generator for #{type} not fully implemented"
|
|
250
|
-
end
|
|
251
|
-
rescue => e
|
|
252
|
-
"Error generating #{name}: #{e.message}"
|
|
253
|
-
end
|
|
254
|
-
|
|
255
|
-
# Generate service
|
|
256
|
-
def self.handle_generate_service(args, name, template_version)
|
|
257
|
-
with_spec = !args.include?("--no-spec")
|
|
258
|
-
|
|
259
|
-
begin
|
|
260
|
-
puts "Generating service: #{name}..."
|
|
261
|
-
result = RailsForge::Generators::ServiceGenerator.generate(name, with_spec: with_spec, template_version: template_version)
|
|
262
|
-
puts "\n#{result}"
|
|
263
|
-
rescue => e
|
|
264
|
-
puts "Error: #{e.message}"
|
|
265
|
-
exit 1
|
|
266
|
-
end
|
|
267
|
-
end
|
|
268
|
-
|
|
269
|
-
# Generate query
|
|
270
|
-
def self.handle_generate_query(args, name, template_version)
|
|
271
|
-
with_spec = !args.include?("--no-spec")
|
|
272
|
-
|
|
273
|
-
begin
|
|
274
|
-
puts "Generating query: #{name}..."
|
|
275
|
-
result = RailsForge::Generators::QueryGenerator.generate(name, with_spec: with_spec, template_version: template_version)
|
|
276
|
-
puts "\n#{result}"
|
|
277
|
-
rescue => e
|
|
278
|
-
puts "Error: #{e.message}"
|
|
279
|
-
exit 1
|
|
280
|
-
end
|
|
281
|
-
end
|
|
282
|
-
|
|
283
|
-
# Generate job
|
|
284
|
-
def self.handle_generate_job(args, name, template_version)
|
|
285
|
-
with_spec = !args.include?("--no-spec")
|
|
286
|
-
|
|
287
|
-
begin
|
|
288
|
-
puts "Generating job: #{name}..."
|
|
289
|
-
result = RailsForge::Generators::JobGenerator.generate(name, with_spec: with_spec, template_version: template_version)
|
|
290
|
-
puts "\n#{result}"
|
|
291
|
-
rescue => e
|
|
292
|
-
puts "Error: #{e.message}"
|
|
293
|
-
exit 1
|
|
294
|
-
end
|
|
295
|
-
end
|
|
296
|
-
|
|
297
|
-
# Generate form
|
|
298
|
-
def self.handle_generate_form(args, name, template_version)
|
|
299
|
-
with_spec = !args.include?("--no-spec")
|
|
300
|
-
|
|
301
|
-
begin
|
|
302
|
-
puts "Generating form: #{name}..."
|
|
303
|
-
result = RailsForge::Generators::FormGenerator.generate(name, with_spec: with_spec, template_version: template_version)
|
|
304
|
-
puts "\n#{result}"
|
|
305
|
-
rescue => e
|
|
306
|
-
puts "Error: #{e.message}"
|
|
307
|
-
exit 1
|
|
308
|
-
end
|
|
309
|
-
end
|
|
310
|
-
|
|
311
|
-
# Generate presenter
|
|
312
|
-
def self.handle_generate_presenter(args, name, template_version)
|
|
313
|
-
with_spec = !args.include?("--no-spec")
|
|
314
|
-
|
|
315
|
-
begin
|
|
316
|
-
puts "Generating presenter: #{name}..."
|
|
317
|
-
result = RailsForge::Generators::PresenterGenerator.generate(name, with_spec: with_spec, template_version: template_version)
|
|
318
|
-
puts "\n#{result}"
|
|
319
|
-
rescue => e
|
|
320
|
-
puts "Error: #{e.message}"
|
|
321
|
-
exit 1
|
|
322
|
-
end
|
|
323
|
-
end
|
|
324
|
-
|
|
325
|
-
# Generate policy
|
|
326
|
-
def self.handle_generate_policy(args, name, template_version)
|
|
327
|
-
with_spec = !args.include?("--no-spec")
|
|
328
|
-
|
|
329
|
-
begin
|
|
330
|
-
puts "Generating policy: #{name}..."
|
|
331
|
-
result = RailsForge::Generators::PolicyGenerator.generate(name, with_spec: with_spec, template_version: template_version)
|
|
332
|
-
puts "\n#{result}"
|
|
333
|
-
rescue => e
|
|
334
|
-
puts "Error: #{e.message}"
|
|
335
|
-
exit 1
|
|
336
|
-
end
|
|
337
|
-
end
|
|
338
|
-
|
|
339
|
-
# Generate serializer
|
|
340
|
-
def self.handle_generate_serializer(args, name, template_version)
|
|
341
|
-
with_spec = !args.include?("--no-spec")
|
|
342
|
-
|
|
343
|
-
begin
|
|
344
|
-
puts "Generating serializer: #{name}..."
|
|
345
|
-
result = RailsForge::Generators::SerializerGenerator.generate(name, with_spec: with_spec, template_version: template_version)
|
|
346
|
-
puts "\n#{result}"
|
|
347
|
-
rescue => e
|
|
348
|
-
puts "Error: #{e.message}"
|
|
349
|
-
exit 1
|
|
350
|
-
end
|
|
351
|
-
end
|
|
352
|
-
|
|
353
|
-
# Generate mailer
|
|
354
|
-
def self.handle_generate_mailer(args, name)
|
|
355
|
-
with_spec = !args.include?("--no-spec")
|
|
356
|
-
|
|
357
|
-
begin
|
|
358
|
-
puts "Generating mailer: #{name}..."
|
|
359
|
-
result = RailsForge::Generators::MailerGenerator.generate(name, with_spec: with_spec)
|
|
360
|
-
puts "\n#{result}"
|
|
361
|
-
rescue => e
|
|
362
|
-
puts "Error: #{e.message}"
|
|
363
|
-
exit 1
|
|
364
|
-
end
|
|
365
|
-
end
|
|
366
|
-
|
|
367
|
-
# Generate feature
|
|
368
|
-
def self.handle_generate_feature(args, name)
|
|
369
|
-
with_spec = !args.include?("--no-spec")
|
|
370
|
-
|
|
371
|
-
begin
|
|
372
|
-
puts "Generating feature: #{name}..."
|
|
373
|
-
result = RailsForge::Generators::FeatureGenerator.generate(name, with_spec: with_spec)
|
|
374
|
-
puts "\n#{result}"
|
|
375
|
-
rescue => e
|
|
376
|
-
puts "Error: #{e.message}"
|
|
377
|
-
exit 1
|
|
378
|
-
end
|
|
379
|
-
end
|
|
380
|
-
|
|
381
|
-
# Generate API
|
|
382
|
-
def self.handle_generate_api(args, name)
|
|
383
|
-
with_spec = !args.include?("--no-spec")
|
|
384
|
-
|
|
385
|
-
begin
|
|
386
|
-
puts "Generating API resource: #{name}..."
|
|
387
|
-
result = RailsForge::Generators::ApiGenerator.generate(name, with_spec: with_spec)
|
|
388
|
-
puts "\n#{result}"
|
|
389
|
-
rescue => e
|
|
390
|
-
puts "Error: #{e.message}"
|
|
391
|
-
exit 1
|
|
392
|
-
end
|
|
393
|
-
end
|
|
394
|
-
|
|
395
|
-
# Generate demo project
|
|
396
|
-
def self.handle_generate_demo(args, name)
|
|
397
|
-
options = {}
|
|
398
|
-
args.each do |arg|
|
|
399
|
-
if arg.start_with?("--")
|
|
400
|
-
key, value = arg[2..].split("=", 2)
|
|
401
|
-
options[key.to_sym] = value || true
|
|
402
|
-
end
|
|
403
|
-
end
|
|
404
|
-
|
|
405
|
-
begin
|
|
406
|
-
puts "Generating demo project: #{name}..."
|
|
407
|
-
result = RailsForge::Generators::DemoGenerator.new(name, options).generate
|
|
408
|
-
puts "\n#{result}"
|
|
409
|
-
rescue => e
|
|
410
|
-
puts "Error: #{e.message}"
|
|
411
|
-
exit 1
|
|
412
|
-
end
|
|
413
|
-
end
|
|
414
|
-
|
|
415
|
-
# Generate devops configs
|
|
416
|
-
def self.handle_generate_devops(args)
|
|
417
|
-
options = {}
|
|
418
|
-
args.each do |arg|
|
|
419
|
-
if arg.start_with?("--")
|
|
420
|
-
key, value = arg[2..].split("=", 2)
|
|
421
|
-
options[key.to_sym] = value || true
|
|
422
|
-
end
|
|
423
|
-
end
|
|
424
|
-
|
|
425
|
-
begin
|
|
426
|
-
puts "Generating DevOps configurations..."
|
|
427
|
-
result = RailsForge::Generators::DevopsGenerator.new("devops", options).generate
|
|
428
|
-
puts "\n#{result}"
|
|
429
|
-
rescue => e
|
|
430
|
-
puts "Error: #{e.message}"
|
|
431
|
-
exit 1
|
|
432
|
-
end
|
|
433
|
-
end
|
|
434
|
-
|
|
435
|
-
# Generate monitoring configs
|
|
436
|
-
def self.handle_generate_monitoring(args)
|
|
437
|
-
options = {}
|
|
438
|
-
args.each do |arg|
|
|
439
|
-
if arg.start_with?("--")
|
|
440
|
-
key, value = arg[2..].split("=", 2)
|
|
441
|
-
options[key.to_sym] = value || true
|
|
442
|
-
end
|
|
443
|
-
end
|
|
444
|
-
|
|
445
|
-
begin
|
|
446
|
-
puts "Generating Monitoring configurations..."
|
|
447
|
-
result = RailsForge::Generators::MonitoringGenerator.new("monitoring", options).generate
|
|
448
|
-
puts "\n#{result}"
|
|
449
|
-
rescue => e
|
|
450
|
-
puts "Error: #{e.message}"
|
|
451
|
-
exit 1
|
|
452
|
-
end
|
|
453
|
-
end
|
|
454
|
-
|
|
455
|
-
# Generate test files
|
|
456
|
-
def self.handle_generate_test(args, name)
|
|
457
|
-
options = { type: "model" }
|
|
458
|
-
args.each do |arg|
|
|
459
|
-
if arg.start_with?("--")
|
|
460
|
-
key, value = arg[2..].split("=", 2)
|
|
461
|
-
options[key.to_sym] = value || true
|
|
462
|
-
end
|
|
463
|
-
end
|
|
464
|
-
|
|
465
|
-
begin
|
|
466
|
-
puts "Generating test files for: #{name}..."
|
|
467
|
-
result = RailsForge::Generators::TestGenerator.new(name, options).generate
|
|
468
|
-
puts "\n#{result}"
|
|
469
|
-
rescue => e
|
|
470
|
-
puts "Error: #{e.message}"
|
|
471
|
-
exit 1
|
|
472
|
-
end
|
|
473
|
-
end
|
|
474
|
-
|
|
475
|
-
# Handle analyze command
|
|
476
|
-
def self.handle_analyze_command(args)
|
|
477
|
-
target = args.shift
|
|
478
|
-
|
|
479
|
-
case target
|
|
480
|
-
when nil, "controllers", "c"
|
|
481
|
-
analyze_controllers
|
|
482
|
-
when "models", "m"
|
|
483
|
-
analyze_models
|
|
484
|
-
when "specs", "spec", "s"
|
|
485
|
-
analyze_specs
|
|
486
|
-
when "db", "database", "d"
|
|
487
|
-
analyze_db
|
|
488
|
-
when "metrics", "metric", "met"
|
|
489
|
-
analyze_metrics(args)
|
|
490
|
-
when "security", "sec", "security"
|
|
491
|
-
analyze_security
|
|
492
|
-
when "performance", "perf", "p"
|
|
493
|
-
analyze_performance
|
|
494
|
-
when "all", "full", "a"
|
|
495
|
-
analyze_all
|
|
496
|
-
else
|
|
497
|
-
puts "Unknown analyze target: #{target}"
|
|
498
|
-
puts "Available: controllers, models, specs, db, metrics, security, performance, all"
|
|
499
|
-
exit 1
|
|
500
|
-
end
|
|
501
|
-
end
|
|
502
|
-
|
|
503
|
-
def self.analyze_security
|
|
504
|
-
results = RailsForge::Analyzers::SecurityAnalyzer.analyze
|
|
505
|
-
RailsForge::Analyzers::SecurityAnalyzer.print_report(results)
|
|
506
|
-
end
|
|
507
|
-
|
|
508
|
-
def self.analyze_performance
|
|
509
|
-
results = RailsForge::Analyzers::PerformanceAnalyzer.analyze
|
|
510
|
-
RailsForge::Analyzers::PerformanceAnalyzer.print_report(results)
|
|
511
|
-
end
|
|
512
|
-
|
|
513
|
-
def self.analyze_controllers
|
|
514
|
-
results = RailsForge::Analyzers::ControllerAnalyzer.analyze
|
|
515
|
-
RailsForge::Analyzers::ControllerAnalyzer.print_results(results)
|
|
516
|
-
end
|
|
517
|
-
|
|
518
|
-
def self.analyze_models
|
|
519
|
-
results = RailsForge::Analyzers::ModelAnalyzer.analyze
|
|
520
|
-
RailsForge::Analyzers::ModelAnalyzer.print_results(results)
|
|
521
|
-
end
|
|
522
|
-
|
|
523
|
-
def self.analyze_specs
|
|
524
|
-
results = RailsForge::Analyzers::SpecAnalyzer.analyze
|
|
525
|
-
RailsForge::Analyzers::SpecAnalyzer.print_results(results)
|
|
526
|
-
end
|
|
527
|
-
|
|
528
|
-
def self.analyze_db
|
|
529
|
-
results = RailsForge::Analyzers::DatabaseAnalyzer.analyze
|
|
530
|
-
RailsForge::Analyzers::DatabaseAnalyzer.print_report(results)
|
|
531
|
-
end
|
|
532
|
-
|
|
533
|
-
def self.analyze_metrics(args)
|
|
534
|
-
results = RailsForge::Analyzers::MetricsAnalyzer.analyze
|
|
535
|
-
RailsForge::Analyzers::MetricsAnalyzer.print_results(results)
|
|
536
|
-
end
|
|
537
|
-
|
|
538
|
-
def self.analyze_all
|
|
539
|
-
RailsForge::ReportFormatter.generate_report
|
|
540
|
-
end
|
|
541
|
-
|
|
542
|
-
# Handle refactor command
|
|
543
|
-
def self.handle_refactor_command(args)
|
|
544
|
-
target = args.shift
|
|
545
|
-
|
|
546
|
-
case target
|
|
547
|
-
when nil, "controllers", "c"
|
|
548
|
-
refactor_controllers
|
|
549
|
-
when "models", "m"
|
|
550
|
-
refactor_models
|
|
551
|
-
when "controller"
|
|
552
|
-
refactor_specific_controller(args.shift)
|
|
553
|
-
else
|
|
554
|
-
puts "Usage: railsforge refactor [controllers|models|controller <name>]"
|
|
555
|
-
exit 1
|
|
556
|
-
end
|
|
557
|
-
end
|
|
558
|
-
|
|
559
|
-
def self.refactor_controllers
|
|
560
|
-
results = RailsForge::Analyzers::RefactorAnalyzer.analyze_controllers
|
|
561
|
-
RailsForge::Analyzers::RefactorAnalyzer.print_report(results)
|
|
562
|
-
end
|
|
563
|
-
|
|
564
|
-
def self.refactor_models
|
|
565
|
-
results = RailsForge::Analyzers::RefactorAnalyzer.analyze_models
|
|
566
|
-
RailsForge::Analyzers::RefactorAnalyzer.print_report(results)
|
|
567
|
-
end
|
|
568
|
-
|
|
569
|
-
def self.refactor_specific_controller(name)
|
|
570
|
-
refactor = RailsForge::Refactors::RefactorController.new
|
|
571
|
-
refactor.refactor(name)
|
|
572
|
-
end
|
|
573
|
-
|
|
574
|
-
# Handle doctor command
|
|
575
35
|
def self.handle_doctor_command(args)
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
rescue => e
|
|
579
|
-
puts "Error: #{e.message}"
|
|
580
|
-
exit 1
|
|
581
|
-
end
|
|
582
|
-
|
|
583
|
-
# Handle audit command
|
|
584
|
-
def self.handle_audit_command(args)
|
|
585
|
-
results = RailsForge::Audit.run
|
|
586
|
-
RailsForge::Audit.print_report(results)
|
|
587
|
-
rescue => e
|
|
588
|
-
puts "Error: #{e.message}"
|
|
589
|
-
exit 1
|
|
590
|
-
end
|
|
36
|
+
json = args.include?("--format=json") || args.include?("--json")
|
|
37
|
+
result = RailsForge::Doctor.new.run
|
|
591
38
|
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
graph = RailsForge::Graph.new
|
|
595
|
-
graph.generate
|
|
596
|
-
rescue => e
|
|
597
|
-
puts "Error: #{e.message}"
|
|
598
|
-
exit 1
|
|
599
|
-
end
|
|
600
|
-
|
|
601
|
-
# Handle wizard command
|
|
602
|
-
def self.handle_wizard_command(args)
|
|
603
|
-
# Check for --tty or --text flag
|
|
604
|
-
use_tty = !args.include?("--text") && ENV.fetch("FORCE_TTY", nil) != "false"
|
|
605
|
-
|
|
606
|
-
# Try to use TTY wizard if available
|
|
607
|
-
if use_tty
|
|
608
|
-
begin
|
|
609
|
-
require "tty-prompt"
|
|
610
|
-
tui = RailsForge::WizardTUI.new
|
|
611
|
-
tui.run
|
|
612
|
-
return
|
|
613
|
-
rescue LoadError
|
|
614
|
-
puts "TTY::Prompt not available, falling back to text wizard..."
|
|
615
|
-
rescue => e
|
|
616
|
-
puts "Warning: TUI failed (#{e.message}), falling back..."
|
|
617
|
-
end
|
|
618
|
-
end
|
|
619
|
-
|
|
620
|
-
# Fall back to text-based wizard
|
|
621
|
-
wizard = RailsForge::Wizard.new
|
|
622
|
-
options = wizard.run
|
|
623
|
-
print "\nCreate this project? (y/N): "
|
|
624
|
-
answer = STDIN.gets.strip.downcase
|
|
625
|
-
if answer == "y" || answer == "yes"
|
|
626
|
-
wizard.execute
|
|
39
|
+
if json
|
|
40
|
+
puts RailsForge::Formatter.render_json(result[:issues], result[:score], result[:metrics])
|
|
627
41
|
else
|
|
628
|
-
puts
|
|
42
|
+
puts RailsForge::Formatter.render_text(result[:issues], result[:score])
|
|
629
43
|
end
|
|
630
|
-
rescue => e
|
|
44
|
+
rescue RailsForge::Doctor::DoctorError => e
|
|
631
45
|
puts "Error: #{e.message}"
|
|
632
46
|
exit 1
|
|
633
47
|
end
|
|
634
|
-
|
|
635
|
-
# Handle plugins command
|
|
636
|
-
def self.handle_plugins_command(args)
|
|
637
|
-
action = args.shift
|
|
638
|
-
|
|
639
|
-
case action
|
|
640
|
-
when nil, "list", "ls"
|
|
641
|
-
RailsForge::Plugins.show_installed
|
|
642
|
-
when "load"
|
|
643
|
-
RailsForge::Plugins.load(args.shift)
|
|
644
|
-
when "create"
|
|
645
|
-
RailsForge::Plugins.create(args.shift)
|
|
646
|
-
else
|
|
647
|
-
puts "Usage: railsforge plugins [list|load|create]"
|
|
648
|
-
end
|
|
649
|
-
end
|
|
650
|
-
|
|
651
|
-
# Handle config command
|
|
652
|
-
def self.handle_config_command(args)
|
|
653
|
-
action = args.shift
|
|
654
|
-
|
|
655
|
-
case action
|
|
656
|
-
when nil, "show"
|
|
657
|
-
RailsForge::Config.show
|
|
658
|
-
when "init"
|
|
659
|
-
RailsForge::Config.init
|
|
660
|
-
when "get"
|
|
661
|
-
puts RailsForge::Config.get(args.shift)
|
|
662
|
-
when "set"
|
|
663
|
-
RailsForge::Config.set(args.shift, args.shift)
|
|
664
|
-
when "reset"
|
|
665
|
-
RailsForge::Config.reset
|
|
666
|
-
else
|
|
667
|
-
puts "Usage: railsforge config [show|init|get|set|reset]"
|
|
668
|
-
end
|
|
669
|
-
end
|
|
670
48
|
end
|
|
671
49
|
end
|