rails-metro 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.
Files changed (150) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +17 -0
  3. data/LICENSE +21 -0
  4. data/README.md +267 -0
  5. data/exe/metro +3 -0
  6. data/lib/rails/metro/cli.rb +162 -0
  7. data/lib/rails/metro/config.rb +40 -0
  8. data/lib/rails/metro/feature_pack.rb +59 -0
  9. data/lib/rails/metro/feature_registry.rb +147 -0
  10. data/lib/rails/metro/packs/aasm_pack.rb +29 -0
  11. data/lib/rails/metro/packs/ab_testing_pack.rb +39 -0
  12. data/lib/rails/metro/packs/action_text_pack.rb +29 -0
  13. data/lib/rails/metro/packs/activeadmin_pack.rb +32 -0
  14. data/lib/rails/metro/packs/activity_feed_pack.rb +31 -0
  15. data/lib/rails/metro/packs/acts_as_list_pack.rb +28 -0
  16. data/lib/rails/metro/packs/acts_as_votable_pack.rb +32 -0
  17. data/lib/rails/metro/packs/administrate_pack.rb +31 -0
  18. data/lib/rails/metro/packs/after_party_pack.rb +31 -0
  19. data/lib/rails/metro/packs/ahoy_pack.rb +31 -0
  20. data/lib/rails/metro/packs/amplitude_pack.rb +45 -0
  21. data/lib/rails/metro/packs/annotate_pack.rb +30 -0
  22. data/lib/rails/metro/packs/api_cors_pack.rb +41 -0
  23. data/lib/rails/metro/packs/api_docs_pack.rb +34 -0
  24. data/lib/rails/metro/packs/api_guard_pack.rb +31 -0
  25. data/lib/rails/metro/packs/api_serialization_pack.rb +38 -0
  26. data/lib/rails/metro/packs/app_linting_pack.rb +35 -0
  27. data/lib/rails/metro/packs/audit_trail_pack.rb +31 -0
  28. data/lib/rails/metro/packs/authentication_pack.rb +31 -0
  29. data/lib/rails/metro/packs/authorization_pack.rb +31 -0
  30. data/lib/rails/metro/packs/avo_pack.rb +32 -0
  31. data/lib/rails/metro/packs/aws_ses_pack.rb +45 -0
  32. data/lib/rails/metro/packs/background_jobs_pack.rb +34 -0
  33. data/lib/rails/metro/packs/blazer_pack.rb +62 -0
  34. data/lib/rails/metro/packs/breadcrumbs_pack.rb +31 -0
  35. data/lib/rails/metro/packs/caching_pack.rb +30 -0
  36. data/lib/rails/metro/packs/charting_pack.rb +67 -0
  37. data/lib/rails/metro/packs/circuit_breaker_pack.rb +34 -0
  38. data/lib/rails/metro/packs/clicky_pack.rb +37 -0
  39. data/lib/rails/metro/packs/cloudinary_pack.rb +42 -0
  40. data/lib/rails/metro/packs/components_pack.rb +30 -0
  41. data/lib/rails/metro/packs/counter_culture_pack.rb +29 -0
  42. data/lib/rails/metro/packs/data_migrate_pack.rb +29 -0
  43. data/lib/rails/metro/packs/datadog_pack.rb +41 -0
  44. data/lib/rails/metro/packs/deployment_pack.rb +30 -0
  45. data/lib/rails/metro/packs/devise_pack.rb +33 -0
  46. data/lib/rails/metro/packs/doorkeeper_pack.rb +32 -0
  47. data/lib/rails/metro/packs/dotenv_pack.rb +36 -0
  48. data/lib/rails/metro/packs/elasticsearch_pack.rb +31 -0
  49. data/lib/rails/metro/packs/encryption_pack.rb +37 -0
  50. data/lib/rails/metro/packs/error_tracking_pack.rb +40 -0
  51. data/lib/rails/metro/packs/event_sourcing_pack.rb +31 -0
  52. data/lib/rails/metro/packs/faraday_pack.rb +42 -0
  53. data/lib/rails/metro/packs/fathom_pack.rb +36 -0
  54. data/lib/rails/metro/packs/feature_flags_pack.rb +34 -0
  55. data/lib/rails/metro/packs/friendly_id_pack.rb +31 -0
  56. data/lib/rails/metro/packs/geocoder_pack.rb +38 -0
  57. data/lib/rails/metro/packs/good_job_pack.rb +34 -0
  58. data/lib/rails/metro/packs/google_analytics_pack.rb +42 -0
  59. data/lib/rails/metro/packs/google_tag_manager_pack.rb +51 -0
  60. data/lib/rails/metro/packs/graphql_pack.rb +31 -0
  61. data/lib/rails/metro/packs/health_check_pack.rb +34 -0
  62. data/lib/rails/metro/packs/heap_pack.rb +39 -0
  63. data/lib/rails/metro/packs/honeybadger_pack.rb +37 -0
  64. data/lib/rails/metro/packs/hotwire_livereload_pack.rb +28 -0
  65. data/lib/rails/metro/packs/icons_pack.rb +28 -0
  66. data/lib/rails/metro/packs/invisible_captcha_pack.rb +35 -0
  67. data/lib/rails/metro/packs/kredis_pack.rb +31 -0
  68. data/lib/rails/metro/packs/lemon_squeezy_pack.rb +36 -0
  69. data/lib/rails/metro/packs/letter_opener_pack.rb +31 -0
  70. data/lib/rails/metro/packs/letter_opener_web_pack.rb +32 -0
  71. data/lib/rails/metro/packs/logging_pack.rb +36 -0
  72. data/lib/rails/metro/packs/madmin_pack.rb +32 -0
  73. data/lib/rails/metro/packs/mailgun_pack.rb +44 -0
  74. data/lib/rails/metro/packs/maintenance_mode_pack.rb +30 -0
  75. data/lib/rails/metro/packs/maintenance_tasks_pack.rb +32 -0
  76. data/lib/rails/metro/packs/markdown_pack.rb +48 -0
  77. data/lib/rails/metro/packs/matomo_pack.rb +48 -0
  78. data/lib/rails/metro/packs/meilisearch_pack.rb +37 -0
  79. data/lib/rails/metro/packs/mixpanel_pack.rb +47 -0
  80. data/lib/rails/metro/packs/mobility_pack.rb +32 -0
  81. data/lib/rails/metro/packs/mollie_pack.rb +36 -0
  82. data/lib/rails/metro/packs/multitenancy_pack.rb +35 -0
  83. data/lib/rails/metro/packs/newrelic_pack.rb +52 -0
  84. data/lib/rails/metro/packs/notifications_pack.rb +31 -0
  85. data/lib/rails/metro/packs/omniauth_pack.rb +49 -0
  86. data/lib/rails/metro/packs/paddle_pack.rb +37 -0
  87. data/lib/rails/metro/packs/pagination_pack.rb +44 -0
  88. data/lib/rails/metro/packs/passwordless_pack.rb +32 -0
  89. data/lib/rails/metro/packs/payments_pack.rb +35 -0
  90. data/lib/rails/metro/packs/paypal_pack.rb +35 -0
  91. data/lib/rails/metro/packs/pdf_pack.rb +45 -0
  92. data/lib/rails/metro/packs/performance_pack.rb +37 -0
  93. data/lib/rails/metro/packs/pghero_pack.rb +31 -0
  94. data/lib/rails/metro/packs/plausible_pack.rb +36 -0
  95. data/lib/rails/metro/packs/posthog_pack.rb +40 -0
  96. data/lib/rails/metro/packs/postmark_pack.rb +39 -0
  97. data/lib/rails/metro/packs/pretender_pack.rb +33 -0
  98. data/lib/rails/metro/packs/profiling_pack.rb +30 -0
  99. data/lib/rails/metro/packs/pundit_pack.rb +50 -0
  100. data/lib/rails/metro/packs/qr_code_pack.rb +37 -0
  101. data/lib/rails/metro/packs/r2_storage_pack.rb +48 -0
  102. data/lib/rails/metro/packs/rack_timeout_pack.rb +34 -0
  103. data/lib/rails/metro/packs/rails_i18n_pack.rb +31 -0
  104. data/lib/rails/metro/packs/ransack_pack.rb +29 -0
  105. data/lib/rails/metro/packs/rate_limiting_pack.rb +39 -0
  106. data/lib/rails/metro/packs/recaptcha_pack.rb +38 -0
  107. data/lib/rails/metro/packs/resend_pack.rb +37 -0
  108. data/lib/rails/metro/packs/revenuecat_pack.rb +36 -0
  109. data/lib/rails/metro/packs/rolify_pack.rb +32 -0
  110. data/lib/rails/metro/packs/rollbar_pack.rb +38 -0
  111. data/lib/rails/metro/packs/s3_storage_pack.rb +45 -0
  112. data/lib/rails/metro/packs/scenic_pack.rb +28 -0
  113. data/lib/rails/metro/packs/scheduling_pack.rb +46 -0
  114. data/lib/rails/metro/packs/search_pack.rb +32 -0
  115. data/lib/rails/metro/packs/security_pack.rb +30 -0
  116. data/lib/rails/metro/packs/sendgrid_pack.rb +44 -0
  117. data/lib/rails/metro/packs/sent_dm_pack.rb +36 -0
  118. data/lib/rails/metro/packs/seo_pack.rb +40 -0
  119. data/lib/rails/metro/packs/shoulda_matchers_pack.rb +37 -0
  120. data/lib/rails/metro/packs/sidekiq_pack.rb +42 -0
  121. data/lib/rails/metro/packs/simple_calendar_pack.rb +29 -0
  122. data/lib/rails/metro/packs/simple_form_pack.rb +30 -0
  123. data/lib/rails/metro/packs/simplecov_pack.rb +38 -0
  124. data/lib/rails/metro/packs/slack_notifier_pack.rb +36 -0
  125. data/lib/rails/metro/packs/soft_deletes_pack.rb +30 -0
  126. data/lib/rails/metro/packs/solidus_pack.rb +31 -0
  127. data/lib/rails/metro/packs/spreadsheets_pack.rb +29 -0
  128. data/lib/rails/metro/packs/statcounter_pack.rb +41 -0
  129. data/lib/rails/metro/packs/stimulus_components_pack.rb +33 -0
  130. data/lib/rails/metro/packs/storage_validations_pack.rb +28 -0
  131. data/lib/rails/metro/packs/strong_migrations_pack.rb +30 -0
  132. data/lib/rails/metro/packs/tagging_pack.rb +31 -0
  133. data/lib/rails/metro/packs/test_mocking_pack.rb +41 -0
  134. data/lib/rails/metro/packs/testing_pack.rb +39 -0
  135. data/lib/rails/metro/packs/twilio_pack.rb +38 -0
  136. data/lib/rails/metro/packs/vite_rails_pack.rb +31 -0
  137. data/lib/rails/metro/packs/web_push_pack.rb +39 -0
  138. data/lib/rails/metro/packs/webhooks_pack.rb +45 -0
  139. data/lib/rails/metro/packs/websockets_pack.rb +29 -0
  140. data/lib/rails/metro/template_compiler.rb +85 -0
  141. data/lib/rails/metro/tui/app.rb +119 -0
  142. data/lib/rails/metro/tui/steps/app_name_step.rb +57 -0
  143. data/lib/rails/metro/tui/steps/database_step.rb +53 -0
  144. data/lib/rails/metro/tui/steps/pack_step.rb +248 -0
  145. data/lib/rails/metro/tui/steps/review_step.rb +94 -0
  146. data/lib/rails/metro/tui/styles.rb +47 -0
  147. data/lib/rails/metro/tui.rb +37 -0
  148. data/lib/rails/metro/version.rb +5 -0
  149. data/lib/rails/metro.rb +9 -0
  150. metadata +206 -0
@@ -0,0 +1,248 @@
1
+ module Rails
2
+ module Metro
3
+ module Tui
4
+ module Steps
5
+ class PackStep
6
+ attr_reader :selected_packs, :cursor, :category_cursor, :search_query,
7
+ :searching, :error
8
+
9
+ def initialize(registry: nil)
10
+ @registry = registry || FeatureRegistry.default
11
+ @categories = build_categories
12
+ @category_cursor = 0
13
+ @cursor = 0
14
+ @selected_packs = Set.new
15
+ @searching = false
16
+ @search_query = ""
17
+ @error = nil
18
+ @pane = :categories
19
+ end
20
+
21
+ def update(msg)
22
+ case msg
23
+ when Bubbletea::KeyMessage
24
+ return handle_search_key(msg) if @searching
25
+ return handle_key(msg)
26
+ end
27
+ [self, nil]
28
+ end
29
+
30
+ def view
31
+ lines = []
32
+ lines << Styles.title.render(" Select feature packs")
33
+ lines << ""
34
+
35
+ if @searching
36
+ lines << " Search: #{@search_query}█"
37
+ lines << ""
38
+ lines.concat(search_results_view)
39
+ elsif @pane == :categories
40
+ lines.concat(categories_view)
41
+ else
42
+ lines.concat(packs_view)
43
+ end
44
+
45
+ lines << ""
46
+ if @error
47
+ lines << " #{Styles.error_style.render(@error)}"
48
+ lines << ""
49
+ end
50
+ lines << status_line
51
+ lines << help_line
52
+ lines.join("\n")
53
+ end
54
+
55
+ def complete?
56
+ true
57
+ end
58
+
59
+ private
60
+
61
+ def build_categories
62
+ catalog = @registry.as_catalog
63
+ grouped = catalog.group_by { |p| p[:category] }
64
+ grouped.sort_by { |cat, _| cat }.map { |cat, packs|
65
+ {name: cat, packs: packs.sort_by { |p| p[:name] }}
66
+ }
67
+ end
68
+
69
+ def current_category
70
+ @categories[@category_cursor]
71
+ end
72
+
73
+ def current_packs
74
+ current_category[:packs]
75
+ end
76
+
77
+ def handle_key(msg)
78
+ if msg.enter?
79
+ return self, :next
80
+ elsif msg.char == "/"
81
+ @searching = true
82
+ @search_query = ""
83
+ @error = nil
84
+ elsif msg.tab?
85
+ toggle_pane
86
+ elsif msg.space?
87
+ toggle_pack if @pane == :packs
88
+ elsif msg.up? || msg.char == "k"
89
+ move_up
90
+ elsif msg.down? || msg.char == "j"
91
+ move_down
92
+ end
93
+ [self, nil]
94
+ end
95
+
96
+ def handle_search_key(msg)
97
+ if msg.esc?
98
+ @searching = false
99
+ @search_query = ""
100
+ elsif msg.enter?
101
+ toggle_search_result
102
+ elsif msg.backspace?
103
+ @search_query = @search_query[0...-1]
104
+ elsif msg.runes?
105
+ @search_query += msg.to_s
106
+ end
107
+ [self, nil]
108
+ end
109
+
110
+ def toggle_pane
111
+ if @pane == :categories
112
+ @pane = :packs
113
+ @cursor = 0
114
+ else
115
+ @pane = :categories
116
+ end
117
+ end
118
+
119
+ def move_up
120
+ if @pane == :categories
121
+ @category_cursor = (@category_cursor - 1) % @categories.length
122
+ @cursor = 0
123
+ else
124
+ @cursor = (@cursor - 1) % current_packs.length
125
+ end
126
+ end
127
+
128
+ def move_down
129
+ if @pane == :categories
130
+ @category_cursor = (@category_cursor + 1) % @categories.length
131
+ @cursor = 0
132
+ else
133
+ @cursor = (@cursor + 1) % current_packs.length
134
+ end
135
+ end
136
+
137
+ def toggle_pack
138
+ pack_name = current_packs[@cursor][:name]
139
+ if @selected_packs.include?(pack_name)
140
+ @selected_packs.delete(pack_name)
141
+ @error = nil
142
+ else
143
+ result = try_select(pack_name)
144
+ if result[:valid]
145
+ @selected_packs.add(pack_name)
146
+ result[:auto_added].each { |dep| @selected_packs.add(dep) }
147
+ @error = if result[:auto_added].any?
148
+ "Auto-added dependencies: #{result[:auto_added].join(", ")}"
149
+ end
150
+ else
151
+ @error = result[:errors].first
152
+ end
153
+ end
154
+ end
155
+
156
+ def toggle_search_result
157
+ results = filtered_packs
158
+ return if results.empty?
159
+
160
+ pack_name = results.first[:name]
161
+ if @selected_packs.include?(pack_name)
162
+ @selected_packs.delete(pack_name)
163
+ @error = nil
164
+ else
165
+ result = try_select(pack_name)
166
+ if result[:valid]
167
+ @selected_packs.add(pack_name)
168
+ result[:auto_added].each { |dep| @selected_packs.add(dep) }
169
+ @error = nil
170
+ else
171
+ @error = result[:errors].first
172
+ end
173
+ end
174
+ end
175
+
176
+ def try_select(pack_name)
177
+ test_set = @selected_packs.to_a + [pack_name]
178
+ @registry.validate_selection(test_set)
179
+ end
180
+
181
+ def filtered_packs
182
+ return [] if @search_query.empty?
183
+ q = @search_query.downcase
184
+ @registry.as_catalog.select { |p|
185
+ p[:name].include?(q) || p[:description].downcase.include?(q)
186
+ }
187
+ end
188
+
189
+ def categories_view
190
+ lines = []
191
+ @categories.each_with_index do |cat, i|
192
+ count = cat[:packs].count { |p| @selected_packs.include?(p[:name]) }
193
+ label = "#{cat[:name]} (#{count}/#{cat[:packs].length})"
194
+ lines << if i == @category_cursor
195
+ Styles.selected.render(" > #{label}")
196
+ else
197
+ " #{label}"
198
+ end
199
+ end
200
+ lines
201
+ end
202
+
203
+ def packs_view
204
+ lines = []
205
+ lines << Styles.category_header.render(" #{current_category[:name]}")
206
+ lines << ""
207
+ current_packs.each_with_index do |pack, i|
208
+ check = @selected_packs.include?(pack[:name]) ? "x" : " "
209
+ label = "[#{check}] #{pack[:name]} — #{pack[:description]}"
210
+ lines << if i == @cursor
211
+ Styles.selected.render(" #{label}")
212
+ else
213
+ " #{label}"
214
+ end
215
+ end
216
+ lines
217
+ end
218
+
219
+ def search_results_view
220
+ results = filtered_packs
221
+ if results.empty?
222
+ [Styles.dimmed.render(" No matching packs")]
223
+ else
224
+ results.first(10).map do |pack|
225
+ check = @selected_packs.include?(pack[:name]) ? "x" : " "
226
+ " [#{check}] #{pack[:name]} — #{pack[:description]}"
227
+ end
228
+ end
229
+ end
230
+
231
+ def status_line
232
+ Styles.status_bar.render(
233
+ " #{@selected_packs.length} packs selected"
234
+ )
235
+ end
236
+
237
+ def help_line
238
+ if @pane == :categories
239
+ Styles.help.render(" Tab to browse packs • / to search • Enter to continue • Space to toggle")
240
+ else
241
+ Styles.help.render(" Tab for categories • Space to toggle • / to search • Enter to continue")
242
+ end
243
+ end
244
+ end
245
+ end
246
+ end
247
+ end
248
+ end
@@ -0,0 +1,94 @@
1
+ module Rails
2
+ module Metro
3
+ module Tui
4
+ module Steps
5
+ class ReviewStep
6
+ attr_reader :action
7
+
8
+ def initialize(config:, registry: nil)
9
+ @config = config
10
+ @registry = registry || FeatureRegistry.default
11
+ @action = nil
12
+ @cursor = 0
13
+ end
14
+
15
+ ACTIONS = [
16
+ {key: "g", label: "Generate app (runs rails new)"},
17
+ {key: "e", label: "Export metro.yml config"},
18
+ {key: "t", label: "Export template.rb only"},
19
+ {key: "b", label: "Go back"}
20
+ ].freeze
21
+
22
+ def update(msg)
23
+ case msg
24
+ when Bubbletea::KeyMessage
25
+ if msg.enter?
26
+ @action = ACTIONS[@cursor][:key]
27
+ return self, :next if @action != "b"
28
+ return self, :back
29
+ elsif msg.up? || msg.char == "k"
30
+ @cursor = (@cursor - 1) % ACTIONS.length
31
+ elsif msg.down? || msg.char == "j"
32
+ @cursor = (@cursor + 1) % ACTIONS.length
33
+ elsif msg.char == "g"
34
+ @action = "g"
35
+ return self, :next
36
+ elsif msg.char == "e"
37
+ @action = "e"
38
+ return self, :next
39
+ elsif msg.char == "t"
40
+ @action = "t"
41
+ return self, :next
42
+ elsif msg.char == "b"
43
+ @action = "b"
44
+ return self, :back
45
+ end
46
+ end
47
+ [self, nil]
48
+ end
49
+
50
+ def view
51
+ lines = []
52
+ lines << Styles.title.render(" Review your configuration")
53
+ lines << ""
54
+ lines << " App name: #{Styles.selected.render(@config.app_name)}"
55
+ lines << " Database: #{@config.database}"
56
+ lines << " Packs: #{pack_summary}"
57
+ lines << ""
58
+
59
+ if @config.selected_packs.any?
60
+ lines << Styles.category_header.render(" Selected packs:")
61
+ @config.selected_packs.sort.each do |name|
62
+ lines << " • #{name}"
63
+ end
64
+ lines << ""
65
+ end
66
+
67
+ lines << Styles.category_header.render(" Actions:")
68
+ ACTIONS.each_with_index do |action, i|
69
+ lines << if i == @cursor
70
+ Styles.selected.render(" > [#{action[:key]}] #{action[:label]}")
71
+ else
72
+ " [#{action[:key]}] #{action[:label]}"
73
+ end
74
+ end
75
+ lines << ""
76
+ lines << Styles.help.render(" j/k to move • Enter or key shortcut to select")
77
+ lines.join("\n")
78
+ end
79
+
80
+ def complete?
81
+ !@action.nil? && @action != "b"
82
+ end
83
+
84
+ private
85
+
86
+ def pack_summary
87
+ count = @config.selected_packs.length
88
+ (count == 0) ? "none" : "#{count} selected"
89
+ end
90
+ end
91
+ end
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,47 @@
1
+ module Rails
2
+ module Metro
3
+ module Tui
4
+ module Styles
5
+ def self.title
6
+ @title ||= Lipgloss::Style.new.foreground("205").bold(true)
7
+ end
8
+
9
+ def self.subtitle
10
+ @subtitle ||= Lipgloss::Style.new.foreground("245")
11
+ end
12
+
13
+ def self.selected
14
+ @selected ||= Lipgloss::Style.new.foreground("205").bold(true)
15
+ end
16
+
17
+ def self.cursor
18
+ @cursor ||= Lipgloss::Style.new.foreground("205")
19
+ end
20
+
21
+ def self.dimmed
22
+ @dimmed ||= Lipgloss::Style.new.foreground("241")
23
+ end
24
+
25
+ def self.category_header
26
+ @category_header ||= Lipgloss::Style.new.foreground("111").bold(true)
27
+ end
28
+
29
+ def self.error_style
30
+ @error_style ||= Lipgloss::Style.new.foreground("196").bold(true)
31
+ end
32
+
33
+ def self.success
34
+ @success ||= Lipgloss::Style.new.foreground("82").bold(true)
35
+ end
36
+
37
+ def self.help
38
+ @help ||= Lipgloss::Style.new.foreground("241")
39
+ end
40
+
41
+ def self.status_bar
42
+ @status_bar ||= Lipgloss::Style.new.foreground("255").background("236").padding(0, 1)
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,37 @@
1
+ module Rails
2
+ module Metro
3
+ module Tui
4
+ def self.available?
5
+ require "bubbletea"
6
+ require "lipgloss"
7
+ true
8
+ rescue LoadError
9
+ false
10
+ end
11
+
12
+ def self.require_dependencies!
13
+ require "bubbletea"
14
+ require "lipgloss"
15
+ require_relative "tui/styles"
16
+ require_relative "tui/steps/app_name_step"
17
+ require_relative "tui/steps/database_step"
18
+ require_relative "tui/steps/pack_step"
19
+ require_relative "tui/steps/review_step"
20
+ require_relative "tui/app"
21
+ end
22
+
23
+ def self.run
24
+ require_dependencies!
25
+ app = App.new
26
+ runner = Bubbletea::Runner.new(app, alt_screen: true)
27
+ runner.run
28
+
29
+ [app.config, app.final_action]
30
+ rescue LoadError
31
+ warn "TUI requires the bubbletea gem. Install it with:"
32
+ warn " gem install bubbletea"
33
+ exit 1
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,5 @@
1
+ module Rails
2
+ module Metro
3
+ VERSION = "0.1.0"
4
+ end
5
+ end
@@ -0,0 +1,9 @@
1
+ require_relative "metro/version"
2
+ require_relative "metro/config"
3
+ require_relative "metro/feature_pack"
4
+ require_relative "metro/feature_registry"
5
+ require_relative "metro/template_compiler"
6
+ require_relative "metro/cli"
7
+
8
+ # Eagerly load all built-in packs
9
+ Rails::Metro::FeatureRegistry.load_builtin_packs
metadata ADDED
@@ -0,0 +1,206 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rails-metro
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - rails-metro contributors
8
+ bindir: exe
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: thor
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - "~>"
17
+ - !ruby/object:Gem::Version
18
+ version: '1.3'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - "~>"
24
+ - !ruby/object:Gem::Version
25
+ version: '1.3'
26
+ description: A toggle-driven Rails app generator that produces Rails Application Templates.
27
+ Pick your features (auth, storage, analytics, jobs, etc.) via CLI, TUI, or web UI,
28
+ and get a ready-to-run Rails app.
29
+ executables:
30
+ - metro
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - CHANGELOG.md
35
+ - LICENSE
36
+ - README.md
37
+ - exe/metro
38
+ - lib/rails/metro.rb
39
+ - lib/rails/metro/cli.rb
40
+ - lib/rails/metro/config.rb
41
+ - lib/rails/metro/feature_pack.rb
42
+ - lib/rails/metro/feature_registry.rb
43
+ - lib/rails/metro/packs/aasm_pack.rb
44
+ - lib/rails/metro/packs/ab_testing_pack.rb
45
+ - lib/rails/metro/packs/action_text_pack.rb
46
+ - lib/rails/metro/packs/activeadmin_pack.rb
47
+ - lib/rails/metro/packs/activity_feed_pack.rb
48
+ - lib/rails/metro/packs/acts_as_list_pack.rb
49
+ - lib/rails/metro/packs/acts_as_votable_pack.rb
50
+ - lib/rails/metro/packs/administrate_pack.rb
51
+ - lib/rails/metro/packs/after_party_pack.rb
52
+ - lib/rails/metro/packs/ahoy_pack.rb
53
+ - lib/rails/metro/packs/amplitude_pack.rb
54
+ - lib/rails/metro/packs/annotate_pack.rb
55
+ - lib/rails/metro/packs/api_cors_pack.rb
56
+ - lib/rails/metro/packs/api_docs_pack.rb
57
+ - lib/rails/metro/packs/api_guard_pack.rb
58
+ - lib/rails/metro/packs/api_serialization_pack.rb
59
+ - lib/rails/metro/packs/app_linting_pack.rb
60
+ - lib/rails/metro/packs/audit_trail_pack.rb
61
+ - lib/rails/metro/packs/authentication_pack.rb
62
+ - lib/rails/metro/packs/authorization_pack.rb
63
+ - lib/rails/metro/packs/avo_pack.rb
64
+ - lib/rails/metro/packs/aws_ses_pack.rb
65
+ - lib/rails/metro/packs/background_jobs_pack.rb
66
+ - lib/rails/metro/packs/blazer_pack.rb
67
+ - lib/rails/metro/packs/breadcrumbs_pack.rb
68
+ - lib/rails/metro/packs/caching_pack.rb
69
+ - lib/rails/metro/packs/charting_pack.rb
70
+ - lib/rails/metro/packs/circuit_breaker_pack.rb
71
+ - lib/rails/metro/packs/clicky_pack.rb
72
+ - lib/rails/metro/packs/cloudinary_pack.rb
73
+ - lib/rails/metro/packs/components_pack.rb
74
+ - lib/rails/metro/packs/counter_culture_pack.rb
75
+ - lib/rails/metro/packs/data_migrate_pack.rb
76
+ - lib/rails/metro/packs/datadog_pack.rb
77
+ - lib/rails/metro/packs/deployment_pack.rb
78
+ - lib/rails/metro/packs/devise_pack.rb
79
+ - lib/rails/metro/packs/doorkeeper_pack.rb
80
+ - lib/rails/metro/packs/dotenv_pack.rb
81
+ - lib/rails/metro/packs/elasticsearch_pack.rb
82
+ - lib/rails/metro/packs/encryption_pack.rb
83
+ - lib/rails/metro/packs/error_tracking_pack.rb
84
+ - lib/rails/metro/packs/event_sourcing_pack.rb
85
+ - lib/rails/metro/packs/faraday_pack.rb
86
+ - lib/rails/metro/packs/fathom_pack.rb
87
+ - lib/rails/metro/packs/feature_flags_pack.rb
88
+ - lib/rails/metro/packs/friendly_id_pack.rb
89
+ - lib/rails/metro/packs/geocoder_pack.rb
90
+ - lib/rails/metro/packs/good_job_pack.rb
91
+ - lib/rails/metro/packs/google_analytics_pack.rb
92
+ - lib/rails/metro/packs/google_tag_manager_pack.rb
93
+ - lib/rails/metro/packs/graphql_pack.rb
94
+ - lib/rails/metro/packs/health_check_pack.rb
95
+ - lib/rails/metro/packs/heap_pack.rb
96
+ - lib/rails/metro/packs/honeybadger_pack.rb
97
+ - lib/rails/metro/packs/hotwire_livereload_pack.rb
98
+ - lib/rails/metro/packs/icons_pack.rb
99
+ - lib/rails/metro/packs/invisible_captcha_pack.rb
100
+ - lib/rails/metro/packs/kredis_pack.rb
101
+ - lib/rails/metro/packs/lemon_squeezy_pack.rb
102
+ - lib/rails/metro/packs/letter_opener_pack.rb
103
+ - lib/rails/metro/packs/letter_opener_web_pack.rb
104
+ - lib/rails/metro/packs/logging_pack.rb
105
+ - lib/rails/metro/packs/madmin_pack.rb
106
+ - lib/rails/metro/packs/mailgun_pack.rb
107
+ - lib/rails/metro/packs/maintenance_mode_pack.rb
108
+ - lib/rails/metro/packs/maintenance_tasks_pack.rb
109
+ - lib/rails/metro/packs/markdown_pack.rb
110
+ - lib/rails/metro/packs/matomo_pack.rb
111
+ - lib/rails/metro/packs/meilisearch_pack.rb
112
+ - lib/rails/metro/packs/mixpanel_pack.rb
113
+ - lib/rails/metro/packs/mobility_pack.rb
114
+ - lib/rails/metro/packs/mollie_pack.rb
115
+ - lib/rails/metro/packs/multitenancy_pack.rb
116
+ - lib/rails/metro/packs/newrelic_pack.rb
117
+ - lib/rails/metro/packs/notifications_pack.rb
118
+ - lib/rails/metro/packs/omniauth_pack.rb
119
+ - lib/rails/metro/packs/paddle_pack.rb
120
+ - lib/rails/metro/packs/pagination_pack.rb
121
+ - lib/rails/metro/packs/passwordless_pack.rb
122
+ - lib/rails/metro/packs/payments_pack.rb
123
+ - lib/rails/metro/packs/paypal_pack.rb
124
+ - lib/rails/metro/packs/pdf_pack.rb
125
+ - lib/rails/metro/packs/performance_pack.rb
126
+ - lib/rails/metro/packs/pghero_pack.rb
127
+ - lib/rails/metro/packs/plausible_pack.rb
128
+ - lib/rails/metro/packs/posthog_pack.rb
129
+ - lib/rails/metro/packs/postmark_pack.rb
130
+ - lib/rails/metro/packs/pretender_pack.rb
131
+ - lib/rails/metro/packs/profiling_pack.rb
132
+ - lib/rails/metro/packs/pundit_pack.rb
133
+ - lib/rails/metro/packs/qr_code_pack.rb
134
+ - lib/rails/metro/packs/r2_storage_pack.rb
135
+ - lib/rails/metro/packs/rack_timeout_pack.rb
136
+ - lib/rails/metro/packs/rails_i18n_pack.rb
137
+ - lib/rails/metro/packs/ransack_pack.rb
138
+ - lib/rails/metro/packs/rate_limiting_pack.rb
139
+ - lib/rails/metro/packs/recaptcha_pack.rb
140
+ - lib/rails/metro/packs/resend_pack.rb
141
+ - lib/rails/metro/packs/revenuecat_pack.rb
142
+ - lib/rails/metro/packs/rolify_pack.rb
143
+ - lib/rails/metro/packs/rollbar_pack.rb
144
+ - lib/rails/metro/packs/s3_storage_pack.rb
145
+ - lib/rails/metro/packs/scenic_pack.rb
146
+ - lib/rails/metro/packs/scheduling_pack.rb
147
+ - lib/rails/metro/packs/search_pack.rb
148
+ - lib/rails/metro/packs/security_pack.rb
149
+ - lib/rails/metro/packs/sendgrid_pack.rb
150
+ - lib/rails/metro/packs/sent_dm_pack.rb
151
+ - lib/rails/metro/packs/seo_pack.rb
152
+ - lib/rails/metro/packs/shoulda_matchers_pack.rb
153
+ - lib/rails/metro/packs/sidekiq_pack.rb
154
+ - lib/rails/metro/packs/simple_calendar_pack.rb
155
+ - lib/rails/metro/packs/simple_form_pack.rb
156
+ - lib/rails/metro/packs/simplecov_pack.rb
157
+ - lib/rails/metro/packs/slack_notifier_pack.rb
158
+ - lib/rails/metro/packs/soft_deletes_pack.rb
159
+ - lib/rails/metro/packs/solidus_pack.rb
160
+ - lib/rails/metro/packs/spreadsheets_pack.rb
161
+ - lib/rails/metro/packs/statcounter_pack.rb
162
+ - lib/rails/metro/packs/stimulus_components_pack.rb
163
+ - lib/rails/metro/packs/storage_validations_pack.rb
164
+ - lib/rails/metro/packs/strong_migrations_pack.rb
165
+ - lib/rails/metro/packs/tagging_pack.rb
166
+ - lib/rails/metro/packs/test_mocking_pack.rb
167
+ - lib/rails/metro/packs/testing_pack.rb
168
+ - lib/rails/metro/packs/twilio_pack.rb
169
+ - lib/rails/metro/packs/vite_rails_pack.rb
170
+ - lib/rails/metro/packs/web_push_pack.rb
171
+ - lib/rails/metro/packs/webhooks_pack.rb
172
+ - lib/rails/metro/packs/websockets_pack.rb
173
+ - lib/rails/metro/template_compiler.rb
174
+ - lib/rails/metro/tui.rb
175
+ - lib/rails/metro/tui/app.rb
176
+ - lib/rails/metro/tui/steps/app_name_step.rb
177
+ - lib/rails/metro/tui/steps/database_step.rb
178
+ - lib/rails/metro/tui/steps/pack_step.rb
179
+ - lib/rails/metro/tui/steps/review_step.rb
180
+ - lib/rails/metro/tui/styles.rb
181
+ - lib/rails/metro/version.rb
182
+ homepage: https://railsmetro.com
183
+ licenses:
184
+ - MIT
185
+ metadata:
186
+ homepage_uri: https://railsmetro.com
187
+ source_code_uri: https://github.com/rish/rails-metro
188
+ changelog_uri: https://github.com/rish/rails-metro/blob/main/CHANGELOG.md
189
+ rdoc_options: []
190
+ require_paths:
191
+ - lib
192
+ required_ruby_version: !ruby/object:Gem::Requirement
193
+ requirements:
194
+ - - ">="
195
+ - !ruby/object:Gem::Version
196
+ version: '3.2'
197
+ required_rubygems_version: !ruby/object:Gem::Requirement
198
+ requirements:
199
+ - - ">="
200
+ - !ruby/object:Gem::Version
201
+ version: '0'
202
+ requirements: []
203
+ rubygems_version: 4.0.5
204
+ specification_version: 4
205
+ summary: Rails app generator with CLI, TUI, and web template output
206
+ test_files: []