hephaestus 0.8.11 → 0.8.12.1

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 (127) hide show
  1. checksums.yaml +4 -4
  2. data/.ruby-version +1 -1
  3. data/CHANGELOG.md +12 -0
  4. data/README.md +3 -1
  5. data/bin/hephaestus +37 -19
  6. data/lib/hephaestus/app_builder.rb +23 -145
  7. data/lib/hephaestus/app_name.rb +33 -0
  8. data/lib/hephaestus/generators/app_generator.rb +79 -75
  9. data/lib/hephaestus/generators/base.rb +0 -1
  10. data/lib/hephaestus/generators/config_generator.rb +3 -114
  11. data/lib/hephaestus/generators/core_generator.rb +18 -58
  12. data/lib/hephaestus/generators/db_generator.rb +12 -0
  13. data/lib/hephaestus/generators/deployment_generator.rb +3 -8
  14. data/lib/hephaestus/generators/lib_generator.rb +0 -10
  15. data/lib/hephaestus/generators/license_generator.rb +4 -1
  16. data/lib/hephaestus/generators/rubocop_generator.rb +1 -1
  17. data/lib/hephaestus/version.rb +1 -1
  18. data/lib/hephaestus.rb +2 -1
  19. data/templates/Dockerfile +7 -75
  20. data/templates/Gemfile +73 -0
  21. data/templates/Procfile +2 -0
  22. data/templates/app/controllers/app_controller.rb.tt +35 -0
  23. data/templates/app/controllers/application_controller.rb +1 -7
  24. data/templates/app/controllers/concerns/authable.rb.tt +50 -0
  25. data/templates/app/controllers/settings_controller.rb +5 -28
  26. data/templates/app/controllers/yetto_controller.rb +9 -10
  27. data/templates/app/lib/body_parameter/yetto_parameters.rb +8 -29
  28. data/templates/app/lib/{constants/app.rb → constants.rb} +1 -3
  29. data/templates/app/services/{http_service.rb → app_service.rb.tt} +6 -6
  30. data/templates/app/views/settings/new.json.jbuilder.tt +18 -0
  31. data/templates/bin/bundle +115 -0
  32. data/templates/bin/docker-entrypoint +20 -10
  33. data/templates/bin/foreman +27 -0
  34. data/templates/bin/jobs +7 -0
  35. data/templates/bin/rails +6 -0
  36. data/templates/bin/rake +6 -0
  37. data/templates/bin/setup +28 -0
  38. data/templates/bin/tapioca +27 -0
  39. data/templates/config/application.rb.tt +36 -0
  40. data/templates/config/boot.rb +7 -0
  41. data/templates/config/environment.rb +8 -0
  42. data/templates/config/environments/blank.rb +7 -0
  43. data/templates/config/initializers/environment.rb +2 -36
  44. data/templates/config/locales/en.yml +5 -31
  45. data/templates/config/puma.rb +5 -0
  46. data/templates/config/routes.rb.tt +28 -0
  47. data/templates/config.ru +9 -0
  48. data/templates/db/queue_schema.rb +132 -0
  49. data/templates/db/schema.rb +17 -0
  50. data/templates/hephaestus_env.sample +12 -0
  51. data/templates/hephaestus_github/dependabot.yml +27 -0
  52. data/templates/hephaestus_github/workflows/automerge.yml +14 -0
  53. data/templates/hephaestus_github/workflows/deploy.yml +30 -0
  54. data/templates/hephaestus_github/workflows/licenses.yml +17 -0
  55. data/templates/hephaestus_github/workflows/lint.yml +17 -0
  56. data/templates/hephaestus_github/workflows/security.yml +19 -0
  57. data/templates/hephaestus_github/workflows/sorbet.yml +19 -0
  58. data/templates/hephaestus_github/workflows/test.yml.tt +21 -0
  59. data/templates/hephaestus_github/workflows/updater.yml +18 -0
  60. data/templates/hephaestus_vscode/extensions.json +9 -0
  61. data/templates/hephaestus_vscode/launch.json +13 -0
  62. data/templates/hephaestus_vscode/settings.json +58 -0
  63. data/templates/lib/schemas/api/2023-03-06/components/parameters/headers/yetto.json +42 -0
  64. data/templates/lib/schemas/api/2023-03-06/components/parameters/plugInstallation.json +12 -0
  65. data/templates/lib/schemas/api/2023-03-06/components/schemas/plug.json +9 -0
  66. data/templates/lib/schemas/api/2023-03-06/components/schemas/responses.json +64 -0
  67. data/templates/lib/schemas/api/2023-03-06/components/schemas/yetto.json +116 -0
  68. data/templates/lib/schemas/api/2023-03-06/openapi.json +30 -0
  69. data/templates/lib/schemas/api/2023-03-06/paths/app.json +90 -0
  70. data/templates/lib/schemas/api/2023-03-06/paths/yetto/message_created.json +51 -0
  71. data/templates/lib/schemas/api/2023-03-06/paths/yetto/plug_installation_created.json +51 -0
  72. data/templates/script/docker-build-prod.tt +11 -0
  73. data/templates/script/docker-run.tt +8 -0
  74. data/templates/script/edit-credentials +12 -3
  75. data/templates/script/hmac_text +1 -1
  76. data/templates/script/ngrok.tt +7 -0
  77. data/templates/script/server +6 -45
  78. data/templates/test/controllers/app_controller_test.rb.tt +188 -0
  79. data/templates/test/controllers/settings_controller_test.rb.tt +125 -0
  80. data/templates/test/controllers/yetto_controller_test.rb +100 -71
  81. data/templates/test/fixtures/files/plug_installation_settings/valid.json +1 -1
  82. data/templates/test/support/rails.rb +16 -36
  83. data/templates/test/support/webmocks/app_webmock.rb.tt +29 -0
  84. data/templates/test/test_helper.rb +1 -31
  85. data/templates/vendor/fly/{fly-production.toml → fly-production.toml.tt} +24 -11
  86. data/templates/vendor/fly/{fly-staging.toml → fly-staging.toml.tt} +18 -15
  87. metadata +59 -72
  88. data/lib/hephaestus/exit_on_failure.rb +0 -22
  89. data/templates/Gemfile.erb +0 -120
  90. data/templates/Procfile.debug +0 -2
  91. data/templates/Procfile.dev +0 -2
  92. data/templates/app/controllers/app_controller.rb +0 -72
  93. data/templates/app/controllers/concerns/authable.rb +0 -50
  94. data/templates/app/controllers/staff_controller.rb +0 -15
  95. data/templates/app/jobs/update_yetto_job.rb +0 -26
  96. data/templates/app/lib/headers/yetto.rb +0 -19
  97. data/templates/app/lib/headers.rb +0 -5
  98. data/templates/app/lib/path_parameter/settings_parameters.rb +0 -22
  99. data/templates/app/lib/path_parameter/yetto_parameters.rb +0 -28
  100. data/templates/app/lib/path_parameter.rb +0 -8
  101. data/templates/app/lib/plug_app/http.rb +0 -37
  102. data/templates/app/lib/plug_app/middleware/malformed_request.rb +0 -110
  103. data/templates/app/lib/plug_app/middleware/openapi_validation.rb +0 -83
  104. data/templates/app/lib/plug_app/middleware/tracing_attributes.rb +0 -46
  105. data/templates/app/lib/query_parameter.rb +0 -6
  106. data/templates/app/serializers/error_serializer.rb +0 -16
  107. data/templates/app/services/yetto_service.rb +0 -51
  108. data/templates/app/views/settings/new.json.jbuilder +0 -21
  109. data/templates/compose.yml +0 -5
  110. data/templates/config/initializers/000-oj.rb +0 -6
  111. data/templates/config/initializers/cors.rb +0 -19
  112. data/templates/config/initializers/filter_parameter_logging.rb +0 -25
  113. data/templates/config/initializers/inflections.rb +0 -20
  114. data/templates/config/initializers/lograge.rb +0 -25
  115. data/templates/config/initializers/opentelemetry.rb +0 -32
  116. data/templates/config/initializers/sidekiq.rb +0 -11
  117. data/templates/config/initializers/slack_webhook_logger.rb +0 -17
  118. data/templates/config/sidekiq.yml +0 -20
  119. data/templates/script/ngrok +0 -5
  120. data/templates/test/controllers/settings_controller_test.rb +0 -27
  121. data/templates/test/fixtures/plug_installation_settings/invalid.json +0 -3
  122. data/templates/test/fixtures/plug_installation_settings/valid.json +0 -3
  123. data/templates/test/jobs/update_yetto_job_test.rb +0 -26
  124. data/templates/test/support/api.rb +0 -76
  125. data/templates/test/support/webmocks/slack_webmock.rb +0 -24
  126. data/templates/test/support/webmocks/yetto_webmock.rb +0 -119
  127. data/templates/test/support/webmocks.rb +0 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8fd5c6432d34e4e2eb90d9973085cd3f5c35a2e8782d5f606c1034216c38f2e4
4
- data.tar.gz: 248400d20b246514c39493ae7c7f8431c684094681031f05d366e66e73ad9fb8
3
+ metadata.gz: 89c0585bf79ff89a4a35d183a6bdec69ec180effa6c5254aec22467093efeefa
4
+ data.tar.gz: 0aefd45fc0dd8549a845f49b510ba9ec7fbe991c85af3f7c9e65e79ed613c9ca
5
5
  SHA512:
6
- metadata.gz: 1838be4d97e454204df1799da18b27f39ab071641e0750836eddd6e9855c9e94545ea790a566aecb73a8b108a9935d835f2b4e056a8f6d5c56321e4a6dd9284b
7
- data.tar.gz: 30e903eefb0ceeee367ca1b07d7cdc07586b4cbc34a2500e54e5c9987c6f11e1412880f81d758cb5f095939ab2114e9c1c3f3f4a2fdb3173de87e7711fe9fd4a
6
+ metadata.gz: 1dcf277f2074215cbf3b207d99534f5bdcf2fd6deb9ed62d6c10e3c87680da8184a30a7e5cfce6ce58e05df6173fb1d808e1fc48edb45f4f1ee4627af2bf2054
7
+ data.tar.gz: 96c5fbb95236e5fe15fd538742c89010e6d9a581b2cfbf3ce70677b7412a1a48301c8f58a68521b7f0b0d45a79f253ca0f5eb31f2475049584d322c491b6214a
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 3.3.0
1
+ 3.3.6
data/CHANGELOG.md CHANGED
@@ -1,3 +1,15 @@
1
+ # [v0.8.12.1] - 16-12-2024
2
+ ## What's Changed
3
+ * general updates by @gjtorikian in https://github.com/yettoapp/hephaestus/pull/95
4
+
5
+
6
+ **Full Changelog**: https://github.com/yettoapp/hephaestus/compare/v0.8.12...v0.8.12.1
7
+ # [v0.8.12] - 16-12-2024
8
+ ## What's Changed
9
+ * Update template generator by @gjtorikian in https://github.com/yettoapp/hephaestus/pull/93
10
+
11
+
12
+ **Full Changelog**: https://github.com/yettoapp/hephaestus/compare/v0.8.11...v0.8.12
1
13
  # [v0.8.11] - 11-12-2024
2
14
  **Full Changelog**: https://github.com/yettoapp/hephaestus/compare/v0.8.10...v0.8.11
3
15
  # [v0.8.10] - 10-12-2024
data/README.md CHANGED
@@ -26,11 +26,13 @@ Where `app` represents the name of the platform you'd like to interact with, lik
26
26
  If you're working on updating/testing this gem locally, you may also try:
27
27
 
28
28
  ```
29
- rm -rf plug-app && DEBUG=1 hephaestus/bin/hephaestus plug-app
29
+ rm -rf plug-app && DEBUG=1 bundle exec bin/hephaestus plug-app
30
30
  ```
31
31
 
32
32
  This way you can wipe the dir and quickly iterate on new changes.
33
33
 
34
+ If you're having trouble connecting to the Internet, you can set `HEPHAESTUS_NO_EXTERNAL=1`.
35
+
34
36
  ## Building upon the base
35
37
 
36
38
  Most of the files which Hephaestus creates for you shouldn't need much modification. The information below is part-informative, part-guidelines on how to extend the generated code for your specific plug.
data/bin/hephaestus CHANGED
@@ -34,25 +34,6 @@ if (str = ARGV.first)
34
34
  end
35
35
  end
36
36
 
37
- puts Rainbow("Checking to see if Hephaestus is the latest and greatest...").green
38
- require "net/http"
39
- begin
40
- Net::HTTP.get(URI("https://www.yetto.app"))
41
- rescue Socket::ResolutionError
42
- puts Rainbow("Unable to check for updates. Are you connected to the internet?").red
43
- exit(1)
44
- end
45
-
46
- %x(gem outdated).split("\n").each do |line|
47
- if line.include?("hephaestus")
48
- puts Rainbow("There is a new version of Hephaestus available (`#{line}`). Please run 'gem update hephaestus' to update.").red
49
- exit(1)
50
- end
51
- end
52
-
53
- require "rails"
54
- require "hephaestus/engine"
55
-
56
37
  if ARGV.empty?
57
38
  puts "Please provide a path for the new application"
58
39
  puts
@@ -63,6 +44,31 @@ elsif ["-v", "--version"].include?(ARGV[0])
63
44
  exit 0
64
45
  end
65
46
 
47
+ if ENV.fetch("HEPHAESTUS_NO_EXTERNAL", "0") == "1"
48
+ puts Rainbow("Skipping Hephaestus check...").yellow
49
+ else
50
+ puts Rainbow("Checking to see if Hephaestus is the latest and greatest...").green
51
+ require "net/http"
52
+ begin
53
+ Net::HTTP.get(URI("https://www.yetto.app"))
54
+ rescue Socket::ResolutionError
55
+ puts Rainbow("Unable to check for updates. Are you connected to the internet?").red
56
+ puts Rainbow("You can also set `HEPHAESTUS_NO_EXTERNAL=1` to skip this.").red
57
+ exit(1)
58
+ end
59
+ end
60
+
61
+ if ENV.fetch("HEPHAESTUS_NO_EXTERNAL", "0") != "1"
62
+ %x(gem outdated).split("\n").each do |line|
63
+ if line.include?("hephaestus")
64
+ puts Rainbow("There is a new version of Hephaestus available (`#{line}`). Please run 'gem update hephaestus' to update.").red
65
+ exit(1)
66
+ end
67
+ end
68
+ end
69
+
70
+ puts Rainbow("Looking good! Proceeding...").blue
71
+
66
72
  path = ARGV.first
67
73
  if File.exist?(path)
68
74
  puts Rainbow("\nError: The directory #{path} already exists.").red
@@ -79,6 +85,17 @@ if path.split("-").length < 2
79
85
  exit 1
80
86
  end
81
87
 
88
+ ENGINE_ROOT = File.expand_path("..", __dir__)
89
+ ENGINE_PATH = File.expand_path("../lib/hephaestus/engine", __dir__)
90
+ APP_PATH = File.expand_path("../test/dummy/config/application", __dir__)
91
+
92
+ # Set up gems listed in the Gemfile.
93
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
94
+ require "bundler/setup" if File.exist?(ENV["BUNDLE_GEMFILE"])
95
+
96
+ require "rails/all"
97
+ require "hephaestus"
98
+
82
99
  templates_root = File.expand_path(File.join("..", "templates"), File.dirname(__FILE__))
83
100
  Hephaestus::AppGenerator.source_root(templates_root)
84
101
  Hephaestus::AppGenerator.source_paths << Rails::Generators::AppGenerator.source_root << templates_root
@@ -88,5 +105,6 @@ ARGV.push("--no-skip-active-job")
88
105
  ARGV.push("--skip-asset-pipeline")
89
106
  ARGV.push("--skip-active-record")
90
107
  ARGV.push("--skip-docker")
108
+ ARGV.push("--skip_bundle")
91
109
 
92
110
  Hephaestus::AppGenerator.start
@@ -17,17 +17,8 @@ module Hephaestus
17
17
  copy_file("hephaestus_gitignore", ".gitignore")
18
18
  end
19
19
 
20
- # it is, apparently, extraordinarly important to keep this as an erb
21
- def gemfile
22
- template("Gemfile.erb", "Gemfile")
23
- end
24
-
25
- def raise_on_delivery_errors
26
- replace_in_file(
27
- "config/environments/development.rb",
28
- "raise_delivery_errors = false",
29
- "raise_delivery_errors = true",
30
- )
20
+ def setup_dev_environment
21
+ copy_file("config/environments/blank.rb", "config/environments/development.rb", force: true)
31
22
  end
32
23
 
33
24
  def copy_setup_scripts
@@ -35,151 +26,48 @@ module Hephaestus
35
26
  Dir.glob("script/**/*").each do |file|
36
27
  next if File.directory?(file)
37
28
 
38
- chmod(file, 0o755)
39
- end
40
- end
41
-
42
- def configure_dev_hosting
43
- config = <<~EOD
44
- # Let dev server run on GitHub Codespaces
45
- config.hosts << /[a-z0-9-]+.githubpreview.dev/
46
-
47
- # Let dev server run on ngrok domains
48
- config.hosts << /[a-z0-9-]+.ngrok.io/
49
- EOD
50
-
51
- configure_environment("development", config)
52
- end
53
-
54
- def setup_asset_host
55
- config = <<~EOD
56
- config.public_file_server.headers = {
57
- "Cache-Control" => "public, max-age=31557600",
58
- }
59
- EOD
60
-
61
- configure_environment("production", config)
62
- end
63
-
64
- def setup_background_worker
65
- config = <<~EOD
66
- # Use a real queuing backend for Active Job (and separate queues per environment).
67
- config.active_job.queue_adapter = :sidekiq
68
- EOD
69
- configure_environment("production", config)
70
- configure_environment("staging", config)
71
- end
72
-
73
- def setup_slack_logger
74
- config = <<~EOD
75
- config.after_initialize do
76
- Rails.logger.broadcast_to(SlackWebhookLogger.logger)
29
+ # Rails adds this
30
+ if file == ".keep"
31
+ remove_file(file)
32
+ next
77
33
  end
78
- EOD
79
- configure_environment("production", config)
80
- configure_environment("staging", config)
81
- configure_environment("test", config)
82
- end
83
34
 
84
- def setup_ssl
85
- ssl = <<~SSL
86
- config.force_ssl = true
87
- config.ssl_options = { hsts: { subdomains: true, preload: true, expires: 1.year } }
88
- SSL
89
-
90
- replace_in_file(
91
- "config/environments/production.rb",
92
- "# config.force_ssl = true",
93
- ssl,
94
- )
35
+ # this is because we might have *.tt templates, which aren't executable,
36
+ # so we gotta re-execute-em all
37
+ chmod(file, 0o755)
38
+ end
95
39
  end
96
40
 
97
41
  def setup_staging_environment
98
- FileUtils.cp(File.join(destination_root, "config/environments/production.rb"), File.join(destination_root, "config/environments/staging.rb"))
42
+ copy_file("config/environments/blank.rb", "config/environments/staging.rb", force: true)
99
43
  end
100
44
 
101
- def replace_gemfile
102
- template("Gemfile.erb", "Gemfile", force: true) do |content|
103
- if development_env?
104
- content.gsub(/gem .hephaestus./) { |s| %(#{s}, path: "#{root_path}") }
105
- else
106
- content
107
- end
108
- end
45
+ def setup_production_environment
46
+ copy_file("config/environments/blank.rb", "config/environments/production.rb", force: true)
109
47
  end
110
48
 
111
- def restore_gemfile
112
- replace_in_file("Gemfile", /gem "hephaestus".+/, "gem \"hephaestus\"")
49
+ def setup_test_environment
50
+ copy_file("config/environments/blank.rb", "config/environments/test.rb", force: true)
113
51
  end
114
52
 
115
53
  def ruby_version
116
54
  create_file(".ruby-version", "#{Hephaestus::RUBY_VERSION}\n")
117
55
  end
118
56
 
119
- def configure_time_formats
120
- replace_in_file("config/application.rb", /# config.time_zone = .*/, "config.time_zone = \"UTC\"")
121
- end
122
-
123
- def create_github_repo(repo_name)
124
- run("gh repo create #{repo_name}", exit_on_failure: false)
125
- end
126
-
127
- def remove_config_comment_lines
128
- config_files = [
129
- "application.rb",
130
- "environment.rb",
131
- "environments/development.rb",
132
- "environments/production.rb",
133
- "environments/test.rb",
134
- ]
135
-
136
- config_files.each do |config_file|
137
- path = Pathname(destination_root).join("config", config_file)
138
- source = Actions::StripCommentsAction.call(path.read)
139
-
140
- path.write(source)
141
- end
142
- end
57
+ def replace_generic_variables
58
+ say(set_color("Replacing generic file names...", :cyan))
143
59
 
144
- def remove_routes_comment_lines
145
- replace_in_file(
146
- "config/routes.rb",
147
- /Rails\.application\.routes\.draw do.*end/m,
148
- "Rails.application.routes.draw do\nend",
149
- )
150
- end
60
+ File.rename(File.join(destination_root, "app", "controllers", "app_controller.rb"), File.join(destination_root, "app", "controllers", "#{plug_name}_controller.rb"))
61
+ File.rename(File.join(destination_root, "app", "services", "app_service.rb"), File.join(destination_root, "app", "services", "#{plug_name}_service.rb"))
62
+ File.rename(File.join(destination_root, "test", "controllers", "app_controller_test.rb"), File.join(destination_root, "test", "controllers", "#{plug_name}_controller_test.rb"))
63
+ File.rename(File.join(destination_root, "test", "support", "webmocks", "app_webmock.rb"), File.join(destination_root, "test", "support", "webmocks", "#{plug_name}_webmock.rb"))
151
64
 
152
- def setup_test_environment
153
- remove_dir("test")
154
- source = File.join(Hephaestus::AppGenerator.source_root, "test")
155
- directory(source, "test")
156
- end
157
-
158
- def replace_generic_variables
159
- say(set_color("Replacing generic variable names...", :cyan))
160
- replace_in_files(destination_root, /App(?!lication)/, short_app_name.capitalize)
161
-
162
- replace_in_files(destination_root, %r{(?<!yetto|sw|plugs\.yetto\.)app(?!lication|/|roximate)}, short_app_name.downcase)
163
- replace_in_file("test/support/api.rb", "/app/", "/#{short_app_name.downcase}/")
164
-
165
- replace_in_files(destination_root, "PlugApp", app_name.underscore.camelcase)
166
- replace_in_files(destination_root, "plug-app", app_name.dasherize)
167
- replace_in_files("#{destination_root}/.github/workflows", "plug-app", app_name.dasherize)
168
- replace_in_files(destination_root, "PLUG_APP", app_name.underscore.upcase)
169
- replace_in_files(destination_root, "plug_app", app_name.underscore)
170
-
171
- # these are erroneously changed
172
- replace_in_file("script/server", "/usr/src/#{short_app_name.downcase}", "/usr/src/app")
173
- replace_in_file("vendor/fly/fly-production.toml", "#{short_app_name.downcase} = ", "app = ")
174
- replace_in_file("vendor/fly/fly-staging.toml", "#{short_app_name.downcase} = ", "app =")
65
+ replace_in_file(File.join("lib", "schemas", "api", "2023-03-06", "openapi.json"), %r{app/paths.json}, "#{plug_name}/paths.json")
66
+ File.rename(File.join(destination_root, "lib", "schemas", "api", "2023-03-06", "paths", "app.json"), File.join(destination_root, "lib", "schemas", "api", "2023-03-06", "paths", "#{plug_name}.json"))
175
67
  end
176
68
 
177
69
  private
178
70
 
179
- def short_app_name
180
- app_name.split("_").last
181
- end
182
-
183
71
  def root_path
184
72
  @root_path ||= Pathname(__dir__).join("..", "..").expand_path
185
73
  end
@@ -187,15 +75,5 @@ module Hephaestus
187
75
  def development_env?
188
76
  root_path.join("hephaestus.gemspec").exist?
189
77
  end
190
-
191
- def raise_on_missing_translations_in(environment)
192
- config = "config.i18n.raise_on_missing_translations = true"
193
-
194
- uncomment_lines("config/environments/#{environment}.rb", config)
195
- end
196
-
197
- def heroku_adapter
198
- @heroku_adapter ||= Adapters::Heroku.new(self)
199
- end
200
78
  end
201
79
  end
@@ -0,0 +1,33 @@
1
+ # typed: false
2
+ # frozen_string_literal: true
3
+
4
+ module Hephaestus
5
+ module AppName
6
+ # like, `plug-slack`
7
+ def app_name
8
+ send(:original_app_name)
9
+ rescue NoMethodError # we're in the context of Rails, so we can't call the generator method
10
+ "plug-#{Rails.application.class.module_parent.name.underscore[5..-1]}"
11
+ end
12
+
13
+ # like, `slack`
14
+ def plug_name
15
+ app_name.split("-", 2).last
16
+ end
17
+
18
+ # like, `Slack`, or `html_proofer => HtmlProofer`
19
+ def capital_plug_name
20
+ plug_name.camelcase
21
+ end
22
+
23
+ # like, `SLACK`
24
+ def upcase_plug_name
25
+ plug_name.upcase
26
+ end
27
+
28
+ # like, `slack`, or `HTMLProofer => html_proofer``
29
+ def underscore_plug_name
30
+ plug_name.underscore
31
+ end
32
+ end
33
+ end
@@ -5,9 +5,10 @@ require "rails/generators"
5
5
  require "rails/generators/rails/app/app_generator"
6
6
  require "tempfile"
7
7
 
8
+ require "hephaestus/app_name"
8
9
  module Hephaestus
9
10
  class AppGenerator < Rails::Generators::AppGenerator
10
- include ExitOnFailure
11
+ include Hephaestus::AppName
11
12
 
12
13
  hide!
13
14
 
@@ -24,14 +25,14 @@ module Hephaestus
24
25
  desc: "Show this help message and quit"
25
26
 
26
27
  def finish_template
27
- invoke(:hephaestus_customization)
28
- super
28
+ invoke(:hephaestus_initialize)
29
+ # super
29
30
  end
30
31
 
31
- def hephaestus_customization
32
+ def hephaestus_initialize
32
33
  say(set_color("Invoking Hephaestus customizations...", :cyan))
33
34
 
34
- run("rails app:update:bin")
35
+ invoke(:init_git)
35
36
  invoke(:customize_gemfile)
36
37
 
37
38
  invoke(:copy_github_actions)
@@ -41,20 +42,30 @@ module Hephaestus
41
42
  invoke(:setup_production_environment)
42
43
  invoke(:setup_staging_environment)
43
44
  invoke(:setup_test_environment)
44
- invoke(:setup_shared_environment_logic)
45
45
 
46
46
  invoke(:configure_app)
47
- invoke(:create_github_repo)
47
+ invoke(:leftovers)
48
+ end
49
+
50
+ def init_git
51
+ run("git remote add origin https://github.com/yettoapp/#{app_name}.git")
52
+ run("git branch -m production")
48
53
  end
49
54
 
50
55
  def customize_gemfile
51
56
  say(set_color("Customizing Gemfile...", :cyan))
52
- build(:replace_gemfile)
53
- capture_stdout do
54
- bundle_command("install")
55
- bundle_command("update")
56
- bundle_command("binstub foreman")
57
- bundle_command("lock --add-platform x86_64-linux")
57
+ template("Gemfile", "Gemfile", force: true)
58
+ # FIXME: unsure why, but when the generators are called, Rails expects Gemfiles in these locations?
59
+ copy_file("Gemfile", File.join(Hephaestus::AppGenerator.source_root, "Gemfile"))
60
+ copy_file("Gemfile", File.join(Hephaestus::AppGenerator.source_root, "..", "Gemfile"))
61
+ replace_in_files(Hephaestus::AppGenerator.source_root, %|ruby File.read(".ruby-version").strip|, %|ruby "#{Hephaestus::RUBY_VERSION}"|)
62
+
63
+ unless ENV.fetch("HEPHAESTUS_NO_EXTERNAL", "0") == "1"
64
+ capture_stdout do
65
+ run("BUNDLE_GEMFILE=\"#{destination_root}/Gemfile\" bundle install", abort_on_failure: false)
66
+ run("BUNDLE_GEMFILE=\"#{destination_root}/Gemfile\" bundle update")
67
+ run("BUNDLE_GEMFILE=\"#{destination_root}/Gemfile\" bundle lock --add-platform x86_64-linux")
68
+ end
58
69
  end
59
70
  end
60
71
 
@@ -62,7 +73,7 @@ module Hephaestus
62
73
  say(set_color("Copying GitHub Actions...", :cyan))
63
74
 
64
75
  capture_stdout do
65
- directory(Hephaestus.source_path(".github"), ".github")
76
+ directory("hephaestus_github", ".github", force: true)
66
77
  end
67
78
  end
68
79
 
@@ -70,67 +81,71 @@ module Hephaestus
70
81
  say(set_color("Copying .vscode/...", :cyan))
71
82
 
72
83
  capture_stdout do
73
- directory(Hephaestus.source_path(".vscode"), ".vscode")
84
+ directory("hephaestus_vscode", ".vscode")
74
85
  end
75
86
  end
76
87
 
77
88
  def setup_development_environment
78
89
  say(set_color("Setting up the development environment...", :cyan))
90
+ build(:setup_dev_environment)
79
91
  capture_stdout do
80
- build(:raise_on_delivery_errors)
81
- build(:configure_dev_hosting)
82
92
  build(:copy_setup_scripts)
83
93
  end
84
94
  end
85
95
 
86
- def setup_production_environment
87
- say(set_color("Setting up the production environment...", :cyan))
96
+ def setup_staging_environment
97
+ say(set_color("Setting up the staging environment...", :cyan))
98
+ build(:setup_staging_environment)
88
99
  capture_stdout do
89
- build(:setup_asset_host)
90
- build(:setup_ssl)
91
100
  end
92
101
  end
93
102
 
94
- def setup_staging_environment
95
- say(set_color("Setting up the staging environment...", :cyan))
103
+ def setup_production_environment
104
+ say(set_color("Setting up the production environment...", :cyan))
105
+ build(:setup_production_environment)
96
106
  capture_stdout do
97
- build(:setup_staging_environment)
98
107
  end
99
108
  end
100
109
 
101
110
  def setup_test_environment
102
111
  say(set_color("Setting up the test environment...", :cyan))
103
- capture_stdout do
104
- build(:setup_test_environment)
105
- end
112
+ build(:setup_test_environment)
106
113
  end
107
114
 
108
- def setup_shared_environment_logic
115
+ def configure_app
116
+ say(set_color("Configuring app...", :cyan))
117
+
109
118
  capture_stdout do
110
- build(:setup_background_worker)
111
- build(:setup_slack_logger)
119
+ remove_dir("bin")
120
+ remove_dir("app/helpers")
121
+ remove_dir("app/models")
122
+ remove_dir("app/views/layouts")
123
+ remove_dir("lib/assets")
124
+ remove_file("lib/tasks/.keep")
112
125
  end
113
- end
114
126
 
115
- def configure_app
116
- say(set_color("Configuring app...", :cyan))
127
+ # This must be here, rather than a generator, because generators are run in a Rails environment,
128
+ # and the bootup process requires the fake PEM key file to be present.
129
+ # we do this to specify the template source, otherwise the generator wants to use its own `test` dir
130
+ source = File.join(Hephaestus::AppGenerator.source_root, "test")
131
+ directory(source, "test", force: true)
117
132
 
118
- remove_dir("app/assets")
119
- remove_dir("app/helpers")
120
- remove_dir("app/models")
121
- remove_dir("app/views/layouts")
122
- remove_dir("lib/assets")
123
- remove_dir("lib/tasks/.keep")
124
- remove_dir("test/helpers")
125
- remove_dir("test/channels")
126
- remove_dir("test/models")
133
+ # This must be here, rather than a generator, because generators are run in a Rails environment,
134
+ # and the OpenAPI middleware, which is loaded when the app boots, requires the schema files to be present.
135
+ capture_stdout do
136
+ directory("lib/schemas/api/2023-03-06", "lib/schemas/api/2023-03-06")
137
+ end
127
138
 
128
- build(:configure_time_formats)
139
+ # we do this to specify the template source, otherwise the generator wants to use Rails own `bin` dir
140
+ source = File.join(Hephaestus::Engine.root, "templates", "bin")
141
+ directory(source, "bin", force: true)
129
142
 
130
- bundle_command("binstubs bundler")
143
+ say(set_color("\n*** All these upcoming `HEAD` errors are okay to ignore! ***\n", :cyan))
131
144
 
132
145
  capture_stdout do
133
146
  generate("hephaestus:core")
147
+
148
+ generate("hephaestus:db")
134
149
  generate("hephaestus:deployment")
135
150
  generate("hephaestus:lib")
136
151
 
@@ -139,16 +154,10 @@ module Hephaestus
139
154
  end
140
155
  end
141
156
 
142
- def create_github_repo
143
- if !options[:skip_git] && options[:github]
144
- say(set_color("Creating repository via `gh repo`...", :cyan))
145
- build(:create_github_repo, options[:github])
146
- end
147
- end
148
-
149
- # NOTE: this function name is important as it overrides
150
- # a Rails function of the same name (that function performs work
151
- # that we don't want to do)
157
+ # NOTE: this function name is important as it matches
158
+ # a Rails function of the same name (that performs work
159
+ # that we don't want to do). Think of this as the final step in the process
160
+ # started by `finish_template`.
152
161
  def leftovers
153
162
  build(:replace_generic_variables)
154
163
 
@@ -156,20 +165,25 @@ module Hephaestus
156
165
  capture_stdout do
157
166
  generate("hephaestus:license")
158
167
  end
168
+
159
169
  say(set_color("Generating `hephaestus:rubocop`...", :cyan))
160
170
  capture_stdout do
161
171
  generate("hephaestus:rubocop")
162
172
  end
163
- say(set_color("Generating `hephaestus:sorbet`...", :cyan))
164
- capture_stdout do
165
- generate("hephaestus:sorbet")
166
- end
173
+
174
+ # say(set_color("Generating `hephaestus:sorbet`...", :cyan))
175
+ # capture_stdout do
176
+ # generate("hephaestus:sorbet")
177
+ # end
178
+
179
+ replace_in_file(File.join("lib", "schemas", "api", "2023-03-06", "openapi.json"), %r{app/paths.json}, "#{plug_name}/paths.json")
180
+ File.rename(File.join(destination_root, "lib", "schemas", "api", "2023-03-06", "paths", "app.json"), File.join(destination_root, "lib", "schemas", "api", "2023-03-06", "paths", "#{plug_name}.json"))
181
+
167
182
  say(set_color("Creating first commit...", :cyan))
168
183
  capture_stdout do
169
184
  invoke(:commit)
170
185
  end
171
186
 
172
- build(:restore_gemfile)
173
187
  invoke(:outro)
174
188
  end
175
189
 
@@ -195,7 +209,7 @@ module Hephaestus
195
209
 
196
210
  Store this in 1Password too; you don't need the .env file for staging/production.
197
211
 
198
- For `SIGNING_SECRET` and `YETTO_PLUG_ID`, you'll need to generate those values yourself.
212
+ For `YETTO_SIGNING_SECRET` and `YETTO_PLUG_ID`, you'll need to generate those values yourself.
199
213
 
200
214
  Then, try running `bin/rails c` to ensure that everything was set up correctly.
201
215
  Running `rake test` is also a good idea.
@@ -232,22 +246,12 @@ module Hephaestus
232
246
  end
233
247
 
234
248
  private def capture_stdout
235
- # stream = "stdout"
236
- # captured_stream = Tempfile.new(stream)
237
- # stream_io = eval("$#{stream}", binding, __FILE__, __LINE__)
238
- # origin_stream = stream_io.dup
239
- # stream_io.reopen(captured_stream)
240
-
249
+ out = StringIO.new
250
+ $stdout = out
241
251
  yield
242
-
243
- # stream_io.rewind
244
- # captured_stream.read
245
-
246
- # unless captured_stream.nil?
247
- # captured_stream.close
248
- # captured_stream.unlink
249
- # end
250
- # stream_io.reopen(origin_stream) unless stream_io.nil?
252
+ out.string
253
+ ensure
254
+ $stdout = STDOUT
251
255
  end
252
256
  end
253
257
  end
@@ -8,7 +8,6 @@ module Hephaestus
8
8
  module Generators
9
9
  class Base < Rails::Generators::Base
10
10
  include Hephaestus::Actions
11
- include ExitOnFailure
12
11
 
13
12
  class << self
14
13
  def default_source_root