railsforge 1.0.2 → 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.
Files changed (75) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +105 -444
  3. data/lib/railsforge/analyzers/controller_analyzer.rb +29 -55
  4. data/lib/railsforge/analyzers/database_analyzer.rb +16 -30
  5. data/lib/railsforge/analyzers/metrics_analyzer.rb +8 -22
  6. data/lib/railsforge/analyzers/model_analyzer.rb +29 -46
  7. data/lib/railsforge/analyzers/performance_analyzer.rb +34 -94
  8. data/lib/railsforge/analyzers/refactor_analyzer.rb +77 -57
  9. data/lib/railsforge/analyzers/security_analyzer.rb +34 -91
  10. data/lib/railsforge/analyzers/spec_analyzer.rb +17 -31
  11. data/lib/railsforge/cli.rb +14 -650
  12. data/lib/railsforge/cli_minimal.rb +8 -55
  13. data/lib/railsforge/doctor.rb +52 -225
  14. data/lib/railsforge/formatter.rb +102 -0
  15. data/lib/railsforge/issue.rb +23 -0
  16. data/lib/railsforge/loader.rb +4 -64
  17. data/lib/railsforge/version.rb +1 -1
  18. metadata +14 -82
  19. data/lib/railsforge/api_generator.rb +0 -397
  20. data/lib/railsforge/audit.rb +0 -289
  21. data/lib/railsforge/config.rb +0 -181
  22. data/lib/railsforge/database_analyzer.rb +0 -300
  23. data/lib/railsforge/feature_generator.rb +0 -560
  24. data/lib/railsforge/generator.rb +0 -313
  25. data/lib/railsforge/generators/api_generator.rb +0 -392
  26. data/lib/railsforge/generators/base_generator.rb +0 -75
  27. data/lib/railsforge/generators/demo_generator.rb +0 -307
  28. data/lib/railsforge/generators/devops_generator.rb +0 -287
  29. data/lib/railsforge/generators/form_generator.rb +0 -180
  30. data/lib/railsforge/generators/job_generator.rb +0 -176
  31. data/lib/railsforge/generators/monitoring_generator.rb +0 -134
  32. data/lib/railsforge/generators/policy_generator.rb +0 -220
  33. data/lib/railsforge/generators/presenter_generator.rb +0 -173
  34. data/lib/railsforge/generators/query_generator.rb +0 -174
  35. data/lib/railsforge/generators/serializer_generator.rb +0 -166
  36. data/lib/railsforge/generators/service_generator.rb +0 -122
  37. data/lib/railsforge/generators/stimulus_controller_generator.rb +0 -129
  38. data/lib/railsforge/generators/test_generator.rb +0 -289
  39. data/lib/railsforge/generators/view_component_generator.rb +0 -169
  40. data/lib/railsforge/graph.rb +0 -270
  41. data/lib/railsforge/mailer_generator.rb +0 -191
  42. data/lib/railsforge/plugins/plugin_loader.rb +0 -60
  43. data/lib/railsforge/plugins.rb +0 -30
  44. data/lib/railsforge/profiles.rb +0 -99
  45. data/lib/railsforge/refactor_analyzer.rb +0 -401
  46. data/lib/railsforge/refactor_controller.rb +0 -277
  47. data/lib/railsforge/refactors/refactor_controller.rb +0 -117
  48. data/lib/railsforge/template_loader.rb +0 -105
  49. data/lib/railsforge/templates/v1/form/spec_template.rb +0 -18
  50. data/lib/railsforge/templates/v1/form/template.rb +0 -28
  51. data/lib/railsforge/templates/v1/job/spec_template.rb +0 -17
  52. data/lib/railsforge/templates/v1/job/template.rb +0 -13
  53. data/lib/railsforge/templates/v1/policy/spec_template.rb +0 -41
  54. data/lib/railsforge/templates/v1/policy/template.rb +0 -57
  55. data/lib/railsforge/templates/v1/presenter/spec_template.rb +0 -12
  56. data/lib/railsforge/templates/v1/presenter/template.rb +0 -13
  57. data/lib/railsforge/templates/v1/query/spec_template.rb +0 -12
  58. data/lib/railsforge/templates/v1/query/template.rb +0 -16
  59. data/lib/railsforge/templates/v1/serializer/spec_template.rb +0 -13
  60. data/lib/railsforge/templates/v1/serializer/template.rb +0 -11
  61. data/lib/railsforge/templates/v1/service/spec_template.rb +0 -12
  62. data/lib/railsforge/templates/v1/service/template.rb +0 -25
  63. data/lib/railsforge/templates/v1/stimulus_controller/template.rb +0 -35
  64. data/lib/railsforge/templates/v1/view_component/template.rb +0 -24
  65. data/lib/railsforge/templates/v2/job/template.rb +0 -49
  66. data/lib/railsforge/templates/v2/query/template.rb +0 -66
  67. data/lib/railsforge/templates/v2/service/spec_template.rb +0 -33
  68. data/lib/railsforge/templates/v2/service/template.rb +0 -71
  69. data/lib/railsforge/templates/v3/job/template.rb +0 -72
  70. data/lib/railsforge/templates/v3/query/spec_template.rb +0 -54
  71. data/lib/railsforge/templates/v3/query/template.rb +0 -115
  72. data/lib/railsforge/templates/v3/service/spec_template.rb +0 -51
  73. data/lib/railsforge/templates/v3/service/template.rb +0 -93
  74. data/lib/railsforge/wizard.rb +0 -265
  75. data/lib/railsforge/wizard_tui.rb +0 -286
metadata CHANGED
@@ -1,29 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: railsforge
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - RailsForge Contributors
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-03-10 00:00:00.000000000 Z
11
+ date: 2026-04-11 00:00:00.000000000 Z
12
12
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: thor
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - "~>"
18
- - !ruby/object:Gem::Version
19
- version: '1.3'
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - "~>"
25
- - !ruby/object:Gem::Version
26
- version: '1.3'
27
13
  - !ruby/object:Gem::Dependency
28
14
  name: bundler
29
15
  requirement: !ruby/object:Gem::Requirement
@@ -81,10 +67,11 @@ dependencies:
81
67
  - !ruby/object:Gem::Version
82
68
  version: '1.85'
83
69
  description: |
84
- RailsForge is a comprehensive command-line tool for automatically generating
85
- essential Rails application components, including monitoring configurations,
86
- DevOps setups, and security/performance analyzers.
87
- email:
70
+ RailsForge analyzes Rails applications and produces structured,
71
+ severity-ranked diagnostics with actionable fixes. Run
72
+ `railsforge doctor` to get a health score and full issue report
73
+ for your codebase.
74
+ email:
88
75
  executables:
89
76
  - railsforge
90
77
  extensions: []
@@ -103,77 +90,22 @@ files:
103
90
  - lib/railsforge/analyzers/refactor_analyzer.rb
104
91
  - lib/railsforge/analyzers/security_analyzer.rb
105
92
  - lib/railsforge/analyzers/spec_analyzer.rb
106
- - lib/railsforge/api_generator.rb
107
- - lib/railsforge/audit.rb
108
93
  - lib/railsforge/cli.rb
109
94
  - lib/railsforge/cli_minimal.rb
110
- - lib/railsforge/config.rb
111
- - lib/railsforge/database_analyzer.rb
112
95
  - lib/railsforge/doctor.rb
113
- - lib/railsforge/feature_generator.rb
114
- - lib/railsforge/generator.rb
115
- - lib/railsforge/generators/api_generator.rb
116
- - lib/railsforge/generators/base_generator.rb
117
- - lib/railsforge/generators/demo_generator.rb
118
- - lib/railsforge/generators/devops_generator.rb
119
- - lib/railsforge/generators/form_generator.rb
120
- - lib/railsforge/generators/job_generator.rb
121
- - lib/railsforge/generators/monitoring_generator.rb
122
- - lib/railsforge/generators/policy_generator.rb
123
- - lib/railsforge/generators/presenter_generator.rb
124
- - lib/railsforge/generators/query_generator.rb
125
- - lib/railsforge/generators/serializer_generator.rb
126
- - lib/railsforge/generators/service_generator.rb
127
- - lib/railsforge/generators/stimulus_controller_generator.rb
128
- - lib/railsforge/generators/test_generator.rb
129
- - lib/railsforge/generators/view_component_generator.rb
130
- - lib/railsforge/graph.rb
96
+ - lib/railsforge/formatter.rb
97
+ - lib/railsforge/issue.rb
131
98
  - lib/railsforge/loader.rb
132
- - lib/railsforge/mailer_generator.rb
133
- - lib/railsforge/plugins.rb
134
- - lib/railsforge/plugins/plugin_loader.rb
135
- - lib/railsforge/profiles.rb
136
99
  - lib/railsforge/profiles/admin_app.yml
137
100
  - lib/railsforge/profiles/api_only.yml
138
101
  - lib/railsforge/profiles/blog.yml
139
102
  - lib/railsforge/profiles/standard.yml
140
- - lib/railsforge/refactor_analyzer.rb
141
- - lib/railsforge/refactor_controller.rb
142
- - lib/railsforge/refactors/refactor_controller.rb
143
- - lib/railsforge/template_loader.rb
144
- - lib/railsforge/templates/v1/form/spec_template.rb
145
- - lib/railsforge/templates/v1/form/template.rb
146
- - lib/railsforge/templates/v1/job/spec_template.rb
147
- - lib/railsforge/templates/v1/job/template.rb
148
- - lib/railsforge/templates/v1/policy/spec_template.rb
149
- - lib/railsforge/templates/v1/policy/template.rb
150
- - lib/railsforge/templates/v1/presenter/spec_template.rb
151
- - lib/railsforge/templates/v1/presenter/template.rb
152
- - lib/railsforge/templates/v1/query/spec_template.rb
153
- - lib/railsforge/templates/v1/query/template.rb
154
- - lib/railsforge/templates/v1/serializer/spec_template.rb
155
- - lib/railsforge/templates/v1/serializer/template.rb
156
- - lib/railsforge/templates/v1/service/spec_template.rb
157
- - lib/railsforge/templates/v1/service/template.rb
158
- - lib/railsforge/templates/v1/stimulus_controller/template.rb
159
- - lib/railsforge/templates/v1/view_component/template.rb
160
- - lib/railsforge/templates/v2/job/template.rb
161
- - lib/railsforge/templates/v2/query/template.rb
162
- - lib/railsforge/templates/v2/service/spec_template.rb
163
- - lib/railsforge/templates/v2/service/template.rb
164
- - lib/railsforge/templates/v3/job/template.rb
165
- - lib/railsforge/templates/v3/query/spec_template.rb
166
- - lib/railsforge/templates/v3/query/template.rb
167
- - lib/railsforge/templates/v3/service/spec_template.rb
168
- - lib/railsforge/templates/v3/service/template.rb
169
103
  - lib/railsforge/version.rb
170
- - lib/railsforge/wizard.rb
171
- - lib/railsforge/wizard_tui.rb
172
104
  homepage: https://github.com/mfifth/RailsForge
173
105
  licenses:
174
106
  - MIT
175
107
  metadata: {}
176
- post_install_message:
108
+ post_install_message:
177
109
  rdoc_options: []
178
110
  require_paths:
179
111
  - lib
@@ -188,8 +120,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
188
120
  - !ruby/object:Gem::Version
189
121
  version: '0'
190
122
  requirements: []
191
- rubygems_version: 3.4.1
192
- signing_key:
123
+ rubygems_version: 3.2.3
124
+ signing_key:
193
125
  specification_version: 4
194
- summary: A Rails development toolkit with generators and analyzers
126
+ summary: Rails application health diagnostics
195
127
  test_files: []
@@ -1,397 +0,0 @@
1
- module RailsForge
2
- # ApiGenerator module handles generating API resources
3
- module ApiGenerator
4
- # Error class for invalid resource names
5
- class InvalidResourceNameError < StandardError; end
6
-
7
- # Simple pluralize helper
8
- def self.pluralize(word)
9
- return word + 's' unless word.end_with?('s')
10
- return word + 'es' if word.end_with?('sh') || word.end_with?('ch')
11
- word + 's'
12
- end
13
-
14
- # Simple underscore helper
15
- def self.underscore(word)
16
- word.gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
17
- .gsub(/([a-z\d])([A-Z])/, '\1_\2')
18
- .downcase
19
- end
20
-
21
- # Validates the resource name
22
- def self.validate_resource_name(name)
23
- if name.nil? || name.strip.empty?
24
- raise InvalidResourceNameError, "Resource name cannot be empty"
25
- end
26
-
27
- unless name =~ /\A[A-Z][a-zA-Z0-9]*\z/
28
- raise InvalidResourceNameError, "Resource name must be in PascalCase (e.g., User)"
29
- end
30
- end
31
-
32
- # Generates an API resource with all necessary files
33
- def self.generate(resource_name, with_spec: true, version: "v1", namespace: "api")
34
- validate_resource_name(resource_name)
35
-
36
- base_path = find_rails_app_path
37
- raise InvalidResourceNameError, "Not in a Rails application directory" unless base_path
38
-
39
- results = []
40
-
41
- # Generate directories
42
- controller_dir = File.join(base_path, "app", "controllers", namespace, version)
43
- FileUtils.mkdir_p(controller_dir)
44
-
45
- serializer_dir = File.join(base_path, "app", "serializers")
46
- FileUtils.mkdir_p(serializer_dir)
47
-
48
- policy_dir = File.join(base_path, "app", "policies")
49
- FileUtils.mkdir_p(policy_dir)
50
-
51
- service_dir = File.join(base_path, "app", "services")
52
- FileUtils.mkdir_p(service_dir)
53
-
54
- query_dir = File.join(base_path, "app", "queries")
55
- FileUtils.mkdir_p(query_dir)
56
-
57
- results << generate_controller(base_path, resource_name, namespace, version)
58
- results << generate_serializer(base_path, resource_name)
59
- results << generate_policy(base_path, resource_name)
60
- results << generate_service(base_path, resource_name)
61
- results << generate_query(base_path, resource_name)
62
-
63
- if with_spec
64
- spec_dir = File.join(base_path, "spec", "requests", namespace, version)
65
- FileUtils.mkdir_p(spec_dir)
66
- results << generate_request_spec(base_path, resource_name, namespace, version)
67
- end
68
-
69
- "API resource '#{resource_name}' generated successfully with #{results.count} files!"
70
- end
71
-
72
- def self.generate_controller(base_path, resource_name, namespace, version)
73
- resource_plural = pluralize(resource_name)
74
- resource_underscore = underscore(resource_name)
75
- resource_underscore_plural = pluralize(resource_underscore)
76
-
77
- file_name = "#{resource_underscore}_controller.rb"
78
- file_path = File.join(base_path, "app", "controllers", namespace, version, file_name)
79
-
80
- return " Skipping controller (already exists)" if File.exist?(file_path)
81
-
82
- content = <<~RUBY
83
- # API Controller for #{resource_name}
84
- # Version: #{version}
85
- # Namespace: #{namespace}
86
- #
87
- # Generates standard CRUD actions for REST API
88
- class #{resource_plural}Controller < ApplicationController
89
- before_action :set_#{resource_underscore}, only: [:show, :update, :destroy]
90
- before_action :authenticate_user!, unless: :devise_controller?
91
-
92
- # GET /#{resource_underscore_plural}
93
- def index
94
- @#{resource_underscore_plural} = #{resource_name}Query.call
95
- render json: #{resource_name}Serializer.new(@#{resource_underscore_plural}).serializable_hash
96
- end
97
-
98
- # GET /#{resource_underscore_plural}/:id
99
- def show
100
- render json: #{resource_name}Serializer.new(@#{resource_underscore}).serializable_hash
101
- end
102
-
103
- # POST /#{resource_underscore_plural}
104
- def create
105
- @result = Create#{resource_name}Service.call(#{resource_underscore}_params)
106
-
107
- if @result.success?
108
- render json: #{resource_name}Serializer.new(@result.#{resource_underscore}).serializable_hash, status: :created
109
- else
110
- render json: { errors: @result.errors }, status: :unprocessable_entity
111
- end
112
- end
113
-
114
- # PATCH/PUT /#{resource_underscore_plural}/:id
115
- def update
116
- @result = Update#{resource_name}Service.call(@#{resource_underscore}, #{resource_underscore}_params)
117
-
118
- if @result.success?
119
- render json: #{resource_name}Serializer.new(@result.#{resource_underscore}).serializable_hash
120
- else
121
- render json: { errors: @result.errors }, status: :unprocessable_entity
122
- end
123
- end
124
-
125
- # DELETE /#{resource_underscore_plural}/:id
126
- def destroy
127
- @#{resource_underscore}.destroy
128
- head :no_content
129
- end
130
-
131
- private
132
-
133
- def set_#{resource_underscore}
134
- @#{resource_underscore} = #{resource_name}.find(params[:id])
135
- end
136
-
137
- def #{resource_underscore}_params
138
- params.require(:#{resource_underscore}).permit(:name)
139
- end
140
- end
141
- RUBY
142
-
143
- File.write(file_path, content)
144
- puts " Created app/controllers/#{namespace}/#{version}/#{file_name}"
145
- file_path
146
- end
147
-
148
- def self.generate_serializer(base_path, resource_name)
149
- file_name = "#{underscore(resource_name)}_serializer.rb"
150
- file_path = File.join(base_path, "app", "serializers", file_name)
151
-
152
- return " Skipping serializer (already exists)" if File.exist?(file_path)
153
-
154
- content = <<~RUBY
155
- # Serializer for #{resource_name}
156
- class #{resource_name}Serializer < ApplicationSerializer
157
- attributes :id, :name, :created_at, :updated_at
158
- end
159
- RUBY
160
-
161
- File.write(file_path, content)
162
- puts " Created app/serializers/#{file_name}"
163
- file_path
164
- end
165
-
166
- def self.generate_policy(base_path, resource_name)
167
- file_name = "#{underscore(resource_name)}_policy.rb"
168
- file_path = File.join(base_path, "app", "policies", file_name)
169
-
170
- return " Skipping policy (already exists)" if File.exist?(file_path)
171
-
172
- content = <<~RUBY
173
- # Policy for #{resource_name}
174
- class #{resource_name}Policy
175
- attr_reader :user, :record
176
-
177
- def initialize(user, record)
178
- @user = user
179
- @record = record
180
- end
181
-
182
- def index?
183
- true
184
- end
185
-
186
- def show?
187
- true
188
- end
189
-
190
- def create?
191
- user.present?
192
- end
193
-
194
- def update?
195
- user.present?
196
- end
197
-
198
- def destroy?
199
- user.present?
200
- end
201
-
202
- class Scope
203
- def initialize(user, scope)
204
- @user = user
205
- @scope = scope
206
- end
207
-
208
- def resolve
209
- scope.all
210
- end
211
- end
212
- end
213
- RUBY
214
-
215
- File.write(file_path, content)
216
- puts " Created app/policies/#{file_name}"
217
- file_path
218
- end
219
-
220
- def self.generate_service(base_path, resource_name)
221
- res_underscore = underscore(resource_name)
222
-
223
- # Create service
224
- file_name = "create_#{res_underscore}_service.rb"
225
- file_path = File.join(base_path, "app", "services", file_name)
226
-
227
- unless File.exist?(file_path)
228
- content = <<~RUBY
229
- # Service for creating #{resource_name}
230
- class Create#{resource_name}Service
231
- def initialize(params)
232
- @params = params
233
- end
234
-
235
- def call
236
- @#{res_underscore} = #{resource_name}.create!(@params)
237
- Result.new(success: true, #{res_underscore}: @#{res_underscore})
238
- rescue => e
239
- Result.new(success: false, errors: e.message)
240
- end
241
-
242
- class Result
243
- attr_reader :#{res_underscore}, :errors
244
- def initialize(success:, #{res_underscore}: nil, errors: nil)
245
- @success = success
246
- @#{res_underscore} = #{res_underscore}
247
- @errors = errors
248
- end
249
-
250
- def success?
251
- @success
252
- end
253
- end
254
- end
255
- RUBY
256
-
257
- File.write(file_path, content)
258
- puts " Created app/services/#{file_name}"
259
- end
260
-
261
- # Update service
262
- file_name = "update_#{res_underscore}_service.rb"
263
- file_path = File.join(base_path, "app", "services", file_name)
264
-
265
- unless File.exist?(file_path)
266
- content = <<~RUBY
267
- # Service for updating #{resource_name}
268
- class Update#{resource_name}Service
269
- def initialize(#{res_underscore}, params)
270
- @#{res_underscore} = #{res_underscore}
271
- @params = params
272
- end
273
-
274
- def call
275
- if @#{res_underscore}.update(@params)
276
- Result.new(success: true, #{res_underscore}: @#{res_underscore})
277
- else
278
- Result.new(success: false, errors: @#{res_underscore}.errors.full_messages)
279
- end
280
- end
281
-
282
- class Result
283
- attr_reader :#{res_underscore}, :errors
284
- def initialize(success:, #{res_underscore}: nil, errors: nil)
285
- @success = success
286
- @#{res_underscore} = #{res_underscore}
287
- @errors = errors
288
- end
289
-
290
- def success?
291
- @success
292
- end
293
- end
294
- end
295
- RUBY
296
-
297
- File.write(file_path, content)
298
- puts " Created app/services/#{file_name}"
299
- end
300
-
301
- "services"
302
- end
303
-
304
- def self.generate_query(base_path, resource_name)
305
- file_name = "find_#{underscore(resource_name)}.rb"
306
- file_path = File.join(base_path, "app", "queries", file_name)
307
-
308
- return " Skipping query (already exists)" if File.exist?(file_path)
309
-
310
- content = <<~RUBY
311
- # Query for finding #{resource_name}
312
- class Find#{resource_name}
313
- def initialize(scope: nil)
314
- @scope = scope || #{resource_name}.all
315
- end
316
-
317
- def call
318
- @scope
319
- end
320
- end
321
- RUBY
322
-
323
- File.write(file_path, content)
324
- puts " Created app/queries/#{file_name}"
325
- file_path
326
- end
327
-
328
- def self.generate_request_spec(base_path, resource_name, namespace, version)
329
- resource_plural = pluralize(resource_name)
330
- resource_underscore = underscore(resource_name)
331
-
332
- file_name = "#{resource_underscore}_spec.rb"
333
- file_path = File.join(base_path, "spec", "requests", namespace, version, file_name)
334
-
335
- return " Skipping spec (already exists)" if File.exist?(file_path)
336
-
337
- content = <<~RUBY
338
- require 'rails_helper'
339
-
340
- RSpec.describe "#{namespace.capitalize}::#{version.capitalize}::#{resource_plural}Controller" do
341
- let(:user) { User.create!(name: "Test", email: "test@example.com") }
342
- let(:#{resource_underscore}) { #{resource_name}.create!(name: "Test #{resource_name}") }
343
-
344
- before do
345
- sign_in user
346
- end
347
-
348
- describe "GET /index" do
349
- it "returns a success response" do
350
- get :index
351
- expect(response).to be_successful
352
- end
353
- end
354
-
355
- describe "GET /show" do
356
- it "returns a success response" do
357
- get :show, params: { id: #{resource_underscore}.id }
358
- expect(response).to be_successful
359
- end
360
- end
361
-
362
- describe "POST /create" do
363
- it "creates a new #{resource_underscore}" do
364
- expect {
365
- post :create, params: { #{resource_underscore}: { name: "New #{resource_name}" } }
366
- }.to change(#{resource_name}, :count).by(1)
367
- end
368
- end
369
-
370
- describe "DELETE /destroy" do
371
- it "deletes the #{resource_underscore}" do
372
- #{resource_underscore}
373
- expect {
374
- delete :destroy, params: { id: #{resource_underscore}.id }
375
- }.to change(#{resource_name}, :count).by(-1)
376
- end
377
- end
378
- end
379
- RUBY
380
-
381
- File.write(file_path, content)
382
- puts " Created spec/requests/#{namespace}/#{version}/#{file_name}"
383
- file_path
384
- end
385
-
386
- def self.find_rails_app_path
387
- path = Dir.pwd
388
- 10.times do
389
- return path if File.exist?(File.join(path, "config", "application.rb"))
390
- parent = File.dirname(path)
391
- break if parent == path
392
- path = parent
393
- end
394
- nil
395
- end
396
- end
397
- end