hephaestus 0.8.11 → 0.8.12.1

Sign up to get free protection for your applications and to get access to all the features.
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