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,38 @@
1
+ module Rails
2
+ module Metro
3
+ module Packs
4
+ class ApiSerializationPack < FeaturePack
5
+ pack_name "api_serialization"
6
+ description "Alba for fast, flexible JSON serialization"
7
+ category "api"
8
+
9
+ def gems
10
+ [
11
+ {name: "alba", version: "~> 3.0"}
12
+ ]
13
+ end
14
+
15
+ def template_lines
16
+ [
17
+ 'create_file "config/initializers/alba.rb", <<~RUBY',
18
+ " Alba.backend = :oj",
19
+ "RUBY",
20
+ "",
21
+ 'create_file "app/resources/application_resource.rb", <<~RUBY',
22
+ " class ApplicationResource",
23
+ " include Alba::Resource",
24
+ " end",
25
+ "RUBY"
26
+ ]
27
+ end
28
+
29
+ def post_install_notes
30
+ [
31
+ "Alba: Create resources in app/resources/ inheriting from ApplicationResource",
32
+ "Alba: Use `UserResource.new(user).serialize` to generate JSON"
33
+ ]
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,35 @@
1
+ module Rails
2
+ module Metro
3
+ module Packs
4
+ class AppLintingPack < FeaturePack
5
+ pack_name "app_linting"
6
+ description "Standard Ruby + ERB Lint for code and template linting"
7
+ category "ops"
8
+
9
+ def gems
10
+ [
11
+ {name: "standard", group: :development},
12
+ {name: "erb_lint", group: :development}
13
+ ]
14
+ end
15
+
16
+ def template_lines
17
+ [
18
+ 'create_file ".standard.yml", <<~YML',
19
+ " # Standard Ruby configuration",
20
+ " # See: https://github.com/standardrb/standard",
21
+ "YML"
22
+ ]
23
+ end
24
+
25
+ def post_install_notes
26
+ [
27
+ "Linting: Run `bundle exec standardrb` to check Ruby code",
28
+ "Linting: Run `bundle exec standardrb --fix` to auto-fix",
29
+ "Linting: Run `bundle exec erblint --lint-all` to check ERB templates"
30
+ ]
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,31 @@
1
+ module Rails
2
+ module Metro
3
+ module Packs
4
+ class AuditTrailPack < FeaturePack
5
+ pack_name "audit_trail"
6
+ description "PaperTrail for model versioning and audit trail"
7
+ category "data"
8
+
9
+ def gems
10
+ [
11
+ {name: "paper_trail", version: "~> 16.0"}
12
+ ]
13
+ end
14
+
15
+ def template_lines
16
+ [
17
+ 'rails_command "generate paper_trail:install"'
18
+ ]
19
+ end
20
+
21
+ def post_install_notes
22
+ [
23
+ "PaperTrail: Run `bin/rails db:migrate` to create versions table",
24
+ "PaperTrail: Add `has_paper_trail` to models you want to track",
25
+ "PaperTrail: Access history with `record.versions` and `record.paper_trail.previous_version`"
26
+ ]
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,31 @@
1
+ module Rails
2
+ module Metro
3
+ module Packs
4
+ class AuthenticationPack < FeaturePack
5
+ pack_name "authentication"
6
+ description "authentication-zero (generates code you own, 2FA, recovery codes)"
7
+ category "core"
8
+ conflicts_with "devise", "passwordless"
9
+
10
+ def gems
11
+ [
12
+ {name: "authentication-zero"}
13
+ ]
14
+ end
15
+
16
+ def template_lines
17
+ [
18
+ 'rails_command "generate authentication"'
19
+ ]
20
+ end
21
+
22
+ def post_install_notes
23
+ [
24
+ "Authentication: Run `bin/rails db:migrate` to create auth tables",
25
+ "Authentication: See app/controllers/sessions_controller.rb to customize login flow"
26
+ ]
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,31 @@
1
+ module Rails
2
+ module Metro
3
+ module Packs
4
+ class AuthorizationPack < FeaturePack
5
+ pack_name "authorization"
6
+ description "Action Policy for authorization (Rails-idiomatic, scoping, caching)"
7
+ category "core"
8
+ conflicts_with "pundit"
9
+
10
+ def gems
11
+ [
12
+ {name: "action_policy", version: "~> 0.7"}
13
+ ]
14
+ end
15
+
16
+ def template_lines
17
+ [
18
+ 'rails_command "generate action_policy:install"'
19
+ ]
20
+ end
21
+
22
+ def post_install_notes
23
+ [
24
+ "Authorization: Generate policies with `bin/rails g action_policy:policy User`",
25
+ "Authorization: See https://actionpolicy.evilmartians.io for docs"
26
+ ]
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,32 @@
1
+ module Rails
2
+ module Metro
3
+ module Packs
4
+ class AvoPack < FeaturePack
5
+ pack_name "avo"
6
+ description "Avo -- modern, customizable admin panel framework"
7
+ category "admin"
8
+ conflicts_with "administrate", "activeadmin", "madmin"
9
+
10
+ def gems
11
+ [
12
+ {name: "avo"}
13
+ ]
14
+ end
15
+
16
+ def template_lines
17
+ [
18
+ 'rails_command "generate avo:install"'
19
+ ]
20
+ end
21
+
22
+ def post_install_notes
23
+ [
24
+ "Avo: Run `bin/rails db:migrate` to create Avo tables",
25
+ "Avo: Access admin at /avo",
26
+ "Avo: Generate resources with `bin/rails g avo:resource User`"
27
+ ]
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,45 @@
1
+ module Rails
2
+ module Metro
3
+ module Packs
4
+ class AwsSesPack < FeaturePack
5
+ pack_name "aws_ses"
6
+ description "Amazon SES for high-volume email delivery"
7
+ category "notifications"
8
+
9
+ def gems
10
+ [
11
+ {name: "aws-sdk-sesv2"}
12
+ ]
13
+ end
14
+
15
+ def template_lines
16
+ [
17
+ 'create_file "config/initializers/aws_ses.rb", <<~RUBY',
18
+ " ActionMailer::Base.smtp_settings = {",
19
+ ' address: "email-smtp.\#{Rails.application.credentials.dig(:aws_ses, :region) || ENV["AWS_REGION"] || "us-east-1"}.amazonaws.com",',
20
+ " port: 587,",
21
+ ' user_name: Rails.application.credentials.dig(:aws_ses, :smtp_username) || ENV["AWS_SES_SMTP_USERNAME"],',
22
+ ' password: Rails.application.credentials.dig(:aws_ses, :smtp_password) || ENV["AWS_SES_SMTP_PASSWORD"],',
23
+ " authentication: :plain,",
24
+ " enable_starttls_auto: true",
25
+ " }",
26
+ "RUBY",
27
+ "",
28
+ 'environment "config.action_mailer.delivery_method = :smtp", env: "production"'
29
+ ]
30
+ end
31
+
32
+ def post_install_notes
33
+ [
34
+ "AWS SES: Add your SMTP credentials with `bin/rails credentials:edit`:",
35
+ " aws_ses:",
36
+ " smtp_username: your_smtp_username",
37
+ " smtp_password: your_smtp_password",
38
+ " region: us-east-1",
39
+ "AWS SES: Verify your sending domain/email in the AWS SES console"
40
+ ]
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,34 @@
1
+ module Rails
2
+ module Metro
3
+ module Packs
4
+ class BackgroundJobsPack < FeaturePack
5
+ pack_name "background_jobs"
6
+ description "Solid Queue + Mission Control Jobs (Rails 8 default, no Redis)"
7
+ category "core"
8
+ conflicts_with "sidekiq", "good_job"
9
+
10
+ def gems
11
+ [
12
+ {name: "solid_queue"},
13
+ {name: "mission_control-jobs"}
14
+ ]
15
+ end
16
+
17
+ def template_lines
18
+ [
19
+ 'rails_command "solid_queue:install"',
20
+ 'route "mount MissionControl::Jobs::Engine, at: \\"/jobs\\""'
21
+ ]
22
+ end
23
+
24
+ def post_install_notes
25
+ [
26
+ "Background Jobs: Run `bin/rails db:migrate` to create Solid Queue tables",
27
+ "Background Jobs: Monitor jobs at /jobs",
28
+ "Background Jobs: Start the worker with `bin/jobs`"
29
+ ]
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,62 @@
1
+ module Rails
2
+ module Metro
3
+ module Packs
4
+ class BlazerPack < FeaturePack
5
+ pack_name "blazer"
6
+ description "SQL analytics dashboards with Blazer"
7
+ category "analytics"
8
+
9
+ def gems
10
+ [
11
+ {name: "blazer", version: "~> 3.0"}
12
+ ]
13
+ end
14
+
15
+ def template_lines
16
+ [
17
+ generator_lines,
18
+ route_lines,
19
+ auth_initializer_lines
20
+ ].flatten
21
+ end
22
+
23
+ def post_install_notes
24
+ [
25
+ "Blazer: Run `bin/rails db:migrate` to create Blazer tables",
26
+ "Blazer: Access dashboards at /blazer",
27
+ "Blazer: For production, set BLAZER_DATABASE_URL to a read-only database connection"
28
+ ]
29
+ end
30
+
31
+ private
32
+
33
+ def generator_lines
34
+ [
35
+ 'rails_command "generate blazer:install"'
36
+ ]
37
+ end
38
+
39
+ def route_lines
40
+ [
41
+ 'route "mount Blazer::Engine, at: \\"blazer\\""'
42
+ ]
43
+ end
44
+
45
+ def auth_initializer_lines
46
+ [
47
+ 'create_file "config/initializers/blazer.rb", <<~RUBY',
48
+ " # Blazer authentication",
49
+ " # For production, replace with your app's authentication:",
50
+ " # authenticate :user, ->(u) { u.admin? } do",
51
+ " # mount Blazer::Engine, at: \"blazer\"",
52
+ " # end",
53
+ " #",
54
+ " # Or set ENV[\"BLAZER_USERNAME\"] and ENV[\"BLAZER_PASSWORD\"] for basic auth",
55
+ " ENV[\"BLAZER_DATABASE_URL\"] ||= ENV[\"DATABASE_URL\"]",
56
+ "RUBY"
57
+ ]
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,31 @@
1
+ module Rails
2
+ module Metro
3
+ module Packs
4
+ class BreadcrumbsPack < FeaturePack
5
+ pack_name "breadcrumbs"
6
+ description "Gretel for flexible breadcrumb navigation"
7
+ category "ui"
8
+
9
+ def gems
10
+ [
11
+ {name: "gretel"}
12
+ ]
13
+ end
14
+
15
+ def template_lines
16
+ [
17
+ 'rails_command "generate gretel:install"'
18
+ ]
19
+ end
20
+
21
+ def post_install_notes
22
+ [
23
+ "Breadcrumbs: Define breadcrumbs in config/breadcrumbs.rb",
24
+ "Breadcrumbs: Set in controllers with `breadcrumb :home, root_path`",
25
+ "Breadcrumbs: Render with `<%= breadcrumbs %>` in layouts"
26
+ ]
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,30 @@
1
+ module Rails
2
+ module Metro
3
+ module Packs
4
+ class CachingPack < FeaturePack
5
+ pack_name "caching"
6
+ description "Solid Cache (Rails 8 default, database-backed caching)"
7
+ category "core"
8
+
9
+ def gems
10
+ [
11
+ {name: "solid_cache"}
12
+ ]
13
+ end
14
+
15
+ def template_lines
16
+ [
17
+ 'rails_command "solid_cache:install"'
18
+ ]
19
+ end
20
+
21
+ def post_install_notes
22
+ [
23
+ "Caching: Run `bin/rails db:migrate` to create Solid Cache tables",
24
+ "Caching: Already configured as the default cache store in production"
25
+ ]
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,67 @@
1
+ module Rails
2
+ module Metro
3
+ module Packs
4
+ class ChartingPack < FeaturePack
5
+ pack_name "charting"
6
+ description "Chartkick + Groupdate for charts and time-series visualization"
7
+ category "ui"
8
+
9
+ def gems
10
+ [
11
+ {name: "chartkick", version: "~> 5.2"},
12
+ {name: "groupdate", version: "~> 6.0"}
13
+ ]
14
+ end
15
+
16
+ def template_lines
17
+ [
18
+ importmap_lines,
19
+ layout_js_lines,
20
+ sample_partial_lines
21
+ ].flatten
22
+ end
23
+
24
+ def post_install_notes
25
+ [
26
+ "Charting: Use `<%= line_chart User.group_by_day(:created_at).count %>` in views",
27
+ "Charting: Groupdate adds `.group_by_day`, `.group_by_week`, etc. to ActiveRecord",
28
+ "Charting: See https://chartkick.com for full documentation"
29
+ ]
30
+ end
31
+
32
+ private
33
+
34
+ def importmap_lines
35
+ [
36
+ "# Pin Chartkick JS for importmap-rails",
37
+ 'append_to_file "config/importmap.rb", <<~RUBY',
38
+ ' pin "chartkick", to: "chartkick.js"',
39
+ ' pin "Chart.bundle", to: "Chart.bundle.js"',
40
+ "RUBY"
41
+ ]
42
+ end
43
+
44
+ def layout_js_lines
45
+ [
46
+ 'inject_into_file "app/views/layouts/application.html.erb", before: "</head>" do',
47
+ ' " <%= javascript_include_tag \\"chartkick\\" %>\\n"',
48
+ "end"
49
+ ]
50
+ end
51
+
52
+ def sample_partial_lines
53
+ [
54
+ 'create_file "app/views/shared/_sample_chart.html.erb", <<~ERB',
55
+ " <%# Example charts -- remove or customize %>",
56
+ " <div class=\"charts\">",
57
+ " <h2>Sample Charts</h2>",
58
+ ' <%%= line_chart({"Jan" => 100, "Feb" => 150, "Mar" => 200}, title: "Monthly Growth") %>',
59
+ ' <%%= pie_chart({"Ruby" => 40, "JavaScript" => 30, "Python" => 20, "Other" => 10}, title: "Languages") %>',
60
+ " </div>",
61
+ "ERB"
62
+ ]
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,34 @@
1
+ module Rails
2
+ module Metro
3
+ module Packs
4
+ class CircuitBreakerPack < FeaturePack
5
+ pack_name "circuit_breaker"
6
+ description "Circuitbox for circuit breaking on external service calls"
7
+ category "ops"
8
+
9
+ def gems
10
+ [
11
+ {name: "circuitbox"}
12
+ ]
13
+ end
14
+
15
+ def template_lines
16
+ [
17
+ 'create_file "config/initializers/circuitbox.rb", <<~RUBY',
18
+ " Circuitbox.configure do |config|",
19
+ " config.default_circuit_store = Circuitbox::MemoryStore.new",
20
+ " end",
21
+ "RUBY"
22
+ ]
23
+ end
24
+
25
+ def post_install_notes
26
+ [
27
+ "Circuitbox: Wrap external calls with `Circuitbox.circuit(:my_service, exceptions: [Timeout::Error]) { call }`",
28
+ "Circuitbox: Circuit opens after repeated failures, preventing cascade failures"
29
+ ]
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,37 @@
1
+ module Rails
2
+ module Metro
3
+ module Packs
4
+ class ClickyPack < FeaturePack
5
+ pack_name "clicky"
6
+ description "Clicky for real-time web analytics"
7
+ category "analytics"
8
+
9
+ def gems
10
+ []
11
+ end
12
+
13
+ def template_lines
14
+ [
15
+ 'create_file "app/views/layouts/_clicky.html.erb", <<~ERB',
16
+ " <script>var clicky_site_ids = clicky_site_ids || []; clicky_site_ids.push(<%%= Rails.application.credentials.dig(:clicky, :site_id) || ENV[\"CLICKY_SITE_ID\"] %>);</script>",
17
+ ' <script async src="//static.getclicky.com/js"></script>',
18
+ ' <noscript><p><img alt="Clicky" width="1" height="1" src="//in.getclicky.com/<%%= Rails.application.credentials.dig(:clicky, :site_id) || ENV["CLICKY_SITE_ID"] %>ns.gif" /></p></noscript>',
19
+ "ERB",
20
+ "",
21
+ 'inject_into_file "app/views/layouts/application.html.erb", before: "</body>" do',
22
+ ' " <%= render \\"layouts/clicky\\" %>\\n"',
23
+ "end"
24
+ ]
25
+ end
26
+
27
+ def post_install_notes
28
+ [
29
+ "Clicky: Add your site ID with `bin/rails credentials:edit`:",
30
+ " clicky:",
31
+ " site_id: 123456"
32
+ ]
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,42 @@
1
+ module Rails
2
+ module Metro
3
+ module Packs
4
+ class CloudinaryPack < FeaturePack
5
+ pack_name "cloudinary"
6
+ description "Cloudinary for cloud image and video management"
7
+ category "ui"
8
+
9
+ def gems
10
+ [
11
+ {name: "cloudinary"},
12
+ {name: "activestorage-cloudinary-service"}
13
+ ]
14
+ end
15
+
16
+ def template_lines
17
+ [
18
+ 'create_file "config/initializers/cloudinary.rb", <<~RUBY',
19
+ " Cloudinary.config do |config|",
20
+ ' config.cloud_name = Rails.application.credentials.dig(:cloudinary, :cloud_name) || ENV["CLOUDINARY_CLOUD_NAME"]',
21
+ ' config.api_key = Rails.application.credentials.dig(:cloudinary, :api_key) || ENV["CLOUDINARY_API_KEY"]',
22
+ ' config.api_secret = Rails.application.credentials.dig(:cloudinary, :api_secret) || ENV["CLOUDINARY_API_SECRET"]',
23
+ " config.secure = true",
24
+ " end",
25
+ "RUBY"
26
+ ]
27
+ end
28
+
29
+ def post_install_notes
30
+ [
31
+ "Cloudinary: Add your credentials with `bin/rails credentials:edit`:",
32
+ " cloudinary:",
33
+ " cloud_name: your_cloud_name",
34
+ " api_key: your_api_key",
35
+ " api_secret: your_api_secret",
36
+ "Cloudinary: Use as Active Storage service by setting `service: Cloudinary` in storage.yml"
37
+ ]
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,30 @@
1
+ module Rails
2
+ module Metro
3
+ module Packs
4
+ class ComponentsPack < FeaturePack
5
+ pack_name "components"
6
+ description "ViewComponent for component-based views"
7
+ category "ui"
8
+
9
+ def gems
10
+ [
11
+ {name: "view_component", version: "~> 3.0"}
12
+ ]
13
+ end
14
+
15
+ def template_lines
16
+ [
17
+ 'rails_command "generate component Example title --stimulus"'
18
+ ]
19
+ end
20
+
21
+ def post_install_notes
22
+ [
23
+ "Components: Generate with `bin/rails g component MyComponent`",
24
+ "Components: See https://viewcomponent.org for docs"
25
+ ]
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,29 @@
1
+ module Rails
2
+ module Metro
3
+ module Packs
4
+ class CounterCulturePack < FeaturePack
5
+ pack_name "counter_culture"
6
+ description "Counter Culture for turbo-charged counter caches"
7
+ category "data"
8
+
9
+ def gems
10
+ [
11
+ {name: "counter_culture"}
12
+ ]
13
+ end
14
+
15
+ def template_lines
16
+ []
17
+ end
18
+
19
+ def post_install_notes
20
+ [
21
+ "Counter Culture: Add `counter_culture :category` to models",
22
+ "Counter Culture: Supports conditional counters, multi-level, and custom columns",
23
+ "Counter Culture: Fix counts with `Model.counter_culture_fix_counts`"
24
+ ]
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,29 @@
1
+ module Rails
2
+ module Metro
3
+ module Packs
4
+ class DataMigratePack < FeaturePack
5
+ pack_name "data_migrate"
6
+ description "Data Migrate for separating data migrations from schema migrations"
7
+ category "data"
8
+
9
+ def gems
10
+ [
11
+ {name: "data_migrate"}
12
+ ]
13
+ end
14
+
15
+ def template_lines
16
+ []
17
+ end
18
+
19
+ def post_install_notes
20
+ [
21
+ "Data Migrate: Generate with `bin/rails g data_migration backfill_users`",
22
+ "Data Migrate: Run with `bin/rails data:migrate`",
23
+ "Data Migrate: Data migrations live in db/data/ separate from schema migrations"
24
+ ]
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end