kowl 0.0.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 (250) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +7 -0
  3. data/README.md +383 -0
  4. data/bin/console +14 -0
  5. data/bin/kowl +106 -0
  6. data/bin/setup +13 -0
  7. data/lib/kowl/actions.rb +240 -0
  8. data/lib/kowl/docker.rb +447 -0
  9. data/lib/kowl/generators/README.md +5 -0
  10. data/lib/kowl/generators/action_generator.rb +113 -0
  11. data/lib/kowl/generators/admin_generator.rb +114 -0
  12. data/lib/kowl/generators/assets_generator.rb +188 -0
  13. data/lib/kowl/generators/base.rb +40 -0
  14. data/lib/kowl/generators/circleci_generator.rb +11 -0
  15. data/lib/kowl/generators/config_generator.rb +180 -0
  16. data/lib/kowl/generators/controller_generator.rb +64 -0
  17. data/lib/kowl/generators/database_generator.rb +42 -0
  18. data/lib/kowl/generators/decorators_generator.rb +16 -0
  19. data/lib/kowl/generators/docker_generator.rb +40 -0
  20. data/lib/kowl/generators/dotfiles_generator.rb +73 -0
  21. data/lib/kowl/generators/libs_generator.rb +19 -0
  22. data/lib/kowl/generators/mailer_generator.rb +58 -0
  23. data/lib/kowl/generators/misc_generator.rb +20 -0
  24. data/lib/kowl/generators/overrides/app_base.rb +15 -0
  25. data/lib/kowl/generators/overrides/app_builder.rb +58 -0
  26. data/lib/kowl/generators/overrides/app_generator.rb +249 -0
  27. data/lib/kowl/generators/pages_generator.rb +46 -0
  28. data/lib/kowl/generators/routes_generator.rb +20 -0
  29. data/lib/kowl/generators/sidekiq_generator.rb +31 -0
  30. data/lib/kowl/generators/staging_generator.rb +14 -0
  31. data/lib/kowl/generators/test_generator.rb +42 -0
  32. data/lib/kowl/generators/text_files_generator.rb +41 -0
  33. data/lib/kowl/generators/users_and_auth_generator.rb +143 -0
  34. data/lib/kowl/generators/uuid_generator.rb +39 -0
  35. data/lib/kowl/generators/views_and_helpers_generator.rb +104 -0
  36. data/lib/kowl/geodb.rb +96 -0
  37. data/lib/kowl/helpers.rb +139 -0
  38. data/lib/kowl/templates/Gemfile.erb.tt +253 -0
  39. data/lib/kowl/templates/README.md.erb +33 -0
  40. data/lib/kowl/templates/app/assets/javascripts/semantic.js.tt +26 -0
  41. data/lib/kowl/templates/app/assets/stylesheets/administrate/application.scss +44 -0
  42. data/lib/kowl/templates/app/assets/stylesheets/bootstrap/_custom_styling.scss +38 -0
  43. data/lib/kowl/templates/app/assets/stylesheets/bootstrap/application-mailer.scss +1 -0
  44. data/lib/kowl/templates/app/assets/stylesheets/bootstrap/application.scss +14 -0
  45. data/lib/kowl/templates/app/assets/stylesheets/bootstrap/components/_alerts.scss +7 -0
  46. data/lib/kowl/templates/app/assets/stylesheets/bootstrap/components/_errors.scss +28 -0
  47. data/lib/kowl/templates/app/assets/stylesheets/bootstrap/components/_navbar.scss +17 -0
  48. data/lib/kowl/templates/app/assets/stylesheets/bootstrap/variables.scss +6 -0
  49. data/lib/kowl/templates/app/assets/stylesheets/semantic/_custom_styling.scss +20 -0
  50. data/lib/kowl/templates/app/assets/stylesheets/semantic/application.scss +24 -0
  51. data/lib/kowl/templates/app/controllers/admin/application_controller.rb +29 -0
  52. data/lib/kowl/templates/app/controllers/admin/login_activities_controller.rb +29 -0
  53. data/lib/kowl/templates/app/controllers/admin/users_controller.rb +37 -0
  54. data/lib/kowl/templates/app/controllers/concerns/auth/authentication.rb +18 -0
  55. data/lib/kowl/templates/app/controllers/concerns/auth/authorization.rb +20 -0
  56. data/lib/kowl/templates/app/controllers/concerns/auth/error_handlers.rb +27 -0
  57. data/lib/kowl/templates/app/controllers/concerns/noauth/error_handlers.rb +25 -0
  58. data/lib/kowl/templates/app/controllers/users_controller.rb +17 -0
  59. data/lib/kowl/templates/app/dashboards/login_activity_dashboard.rb.tt +59 -0
  60. data/lib/kowl/templates/app/dashboards/rich_text_body_dashboard.rb.tt +17 -0
  61. data/lib/kowl/templates/app/dashboards/user_dashboard.rb.tt +60 -0
  62. data/lib/kowl/templates/app/fields/gravatar_field.rb +10 -0
  63. data/lib/kowl/templates/app/fields/rich_text_area_field.rb +8 -0
  64. data/lib/kowl/templates/app/inputs/rich_text_area_input.rb +11 -0
  65. data/lib/kowl/templates/app/javascript/administrate/components/date_time_picker.js.tt +32 -0
  66. data/lib/kowl/templates/app/javascript/administrate/components/table.js.tt +49 -0
  67. data/lib/kowl/templates/app/javascript/administrate/index.js +3 -0
  68. data/lib/kowl/templates/app/javascript/packs/administrate.js.tt +21 -0
  69. data/lib/kowl/templates/app/javascript/packs/semantic.js +11 -0
  70. data/lib/kowl/templates/app/mailers/application_mailer.rb +7 -0
  71. data/lib/kowl/templates/app/mailers/devise_mailer.rb +5 -0
  72. data/lib/kowl/templates/app/models/login_activity.rb.tt +29 -0
  73. data/lib/kowl/templates/app/models/user.rb.tt +72 -0
  74. data/lib/kowl/templates/app/policies/application_policy.rb +38 -0
  75. data/lib/kowl/templates/app/policies/login_activity_policy.rb +35 -0
  76. data/lib/kowl/templates/app/policies/user_policy.rb +43 -0
  77. data/lib/kowl/templates/app/views/admin/templates/navigation.erb.tt +23 -0
  78. data/lib/kowl/templates/app/views/admin/views/application/_javascript.html.erb +21 -0
  79. data/lib/kowl/templates/app/views/admin/views/users/_collection.html.erb +102 -0
  80. data/lib/kowl/templates/app/views/admin/views/users/_form.html.erb +46 -0
  81. data/lib/kowl/templates/app/views/admin/views/users/edit.html.erb +36 -0
  82. data/lib/kowl/templates/app/views/admin/views/users/index.html.erb +66 -0
  83. data/lib/kowl/templates/app/views/fields/gravatar_field/_form.html.erb +6 -0
  84. data/lib/kowl/templates/app/views/fields/gravatar_field/_index.html.erb +1 -0
  85. data/lib/kowl/templates/app/views/fields/gravatar_field/_show.html.erb +1 -0
  86. data/lib/kowl/templates/app/views/fields/rich_text_area_field/_form.html.erb +6 -0
  87. data/lib/kowl/templates/app/views/fields/rich_text_area_field/_index.html.erb +1 -0
  88. data/lib/kowl/templates/app/views/fields/rich_text_area_field/_show.html.erb +1 -0
  89. data/lib/kowl/templates/app/views/layouts/admin.html.erb.tt +47 -0
  90. data/lib/kowl/templates/app/views/layouts/devise_mailer.html.erb +14 -0
  91. data/lib/kowl/templates/app/views/pages/welcome/bootstrap.html.erb +18 -0
  92. data/lib/kowl/templates/app/views/pages/welcome/bootstrap.html.haml +17 -0
  93. data/lib/kowl/templates/app/views/pages/welcome/bootstrap.html.slim +17 -0
  94. data/lib/kowl/templates/app/views/pages/welcome/default.html.erb +0 -0
  95. data/lib/kowl/templates/app/views/pages/welcome/default.html.haml +0 -0
  96. data/lib/kowl/templates/app/views/pages/welcome/default.html.slim +0 -0
  97. data/lib/kowl/templates/app/views/pages/welcome/semantic.html.erb +20 -0
  98. data/lib/kowl/templates/app/views/pages/welcome/semantic.html.haml +17 -0
  99. data/lib/kowl/templates/app/views/pages/welcome/semantic.html.slim +17 -0
  100. data/lib/kowl/templates/app/views/shared/footer/bootstrap.html.erb.tt +5 -0
  101. data/lib/kowl/templates/app/views/shared/footer/bootstrap.html.haml.tt +3 -0
  102. data/lib/kowl/templates/app/views/shared/footer/bootstrap.html.slim.tt +3 -0
  103. data/lib/kowl/templates/app/views/shared/footer/semantic.html.erb.tt +7 -0
  104. data/lib/kowl/templates/app/views/shared/footer/semantic.html.haml.tt +5 -0
  105. data/lib/kowl/templates/app/views/shared/footer/semantic.html.slim.tt +5 -0
  106. data/lib/kowl/templates/app/views/shared/navigation/bootstrap.html.erb.tt +51 -0
  107. data/lib/kowl/templates/app/views/shared/navigation/bootstrap.html.haml.tt +36 -0
  108. data/lib/kowl/templates/app/views/shared/navigation/bootstrap.html.slim.tt +36 -0
  109. data/lib/kowl/templates/app/views/shared/navigation/semantic.html.erb.tt +48 -0
  110. data/lib/kowl/templates/app/views/shared/navigation/semantic.html.haml.tt +36 -0
  111. data/lib/kowl/templates/app/views/shared/navigation/semantic.html.slim.tt +36 -0
  112. data/lib/kowl/templates/app/workers/scheduler/pghero_scheduler.rb +11 -0
  113. data/lib/kowl/templates/config/autoprefixer.yml +4 -0
  114. data/lib/kowl/templates/config/db/mysql.yml.tt +43 -0
  115. data/lib/kowl/templates/config/db/oracle.yml.tt +29 -0
  116. data/lib/kowl/templates/config/db/postgresql.yml.tt +37 -0
  117. data/lib/kowl/templates/config/db/sqlite3.yml.tt +20 -0
  118. data/lib/kowl/templates/config/db/sqlserver.yml.tt +28 -0
  119. data/lib/kowl/templates/config/initializers/administrate.rb.tt +9 -0
  120. data/lib/kowl/templates/config/initializers/bullet.rb +21 -0
  121. data/lib/kowl/templates/config/initializers/devise-security.rb +44 -0
  122. data/lib/kowl/templates/config/initializers/devise_argon2.rb +29 -0
  123. data/lib/kowl/templates/config/initializers/faker.rb +6 -0
  124. data/lib/kowl/templates/config/initializers/generators.rb.tt +31 -0
  125. data/lib/kowl/templates/config/initializers/geocoder.rb +10 -0
  126. data/lib/kowl/templates/config/initializers/letter_opener.rb +13 -0
  127. data/lib/kowl/templates/config/initializers/lockbox.rb +11 -0
  128. data/lib/kowl/templates/config/initializers/logging.rb +6 -0
  129. data/lib/kowl/templates/config/initializers/lograge.rb +7 -0
  130. data/lib/kowl/templates/config/initializers/logstop.rb +4 -0
  131. data/lib/kowl/templates/config/initializers/middleware.rb +9 -0
  132. data/lib/kowl/templates/config/initializers/oj.rb +7 -0
  133. data/lib/kowl/templates/config/initializers/pagy.rb.tt +16 -0
  134. data/lib/kowl/templates/config/initializers/postmark.rb +8 -0
  135. data/lib/kowl/templates/config/initializers/rack_attack.rb.tt +71 -0
  136. data/lib/kowl/templates/config/initializers/sass.rb +5 -0
  137. data/lib/kowl/templates/config/initializers/sidekiq.rb +11 -0
  138. data/lib/kowl/templates/config/initializers/simpleform/semantic.rb +225 -0
  139. data/lib/kowl/templates/config/initializers/slim.rb +6 -0
  140. data/lib/kowl/templates/config/initializers/sparkpost.rb +13 -0
  141. data/lib/kowl/templates/config/routes.rb.tt +28 -0
  142. data/lib/kowl/templates/config/sidekiq.yml.tt +17 -0
  143. data/lib/kowl/templates/db/migrations/create_action_text_tables.action_text.rb.tt +16 -0
  144. data/lib/kowl/templates/db/migrations/create_active_storage_tables.active_storage.rb.tt +29 -0
  145. data/lib/kowl/templates/db/migrations/devise.rb.tt +59 -0
  146. data/lib/kowl/templates/db/migrations/login_activities.rb.tt +41 -0
  147. data/lib/kowl/templates/db/seeds.rb.tt +14 -0
  148. data/lib/kowl/templates/docker/Dockerfile.alpine.tt +92 -0
  149. data/lib/kowl/templates/docker/Dockerfile.debian.tt +133 -0
  150. data/lib/kowl/templates/docker/docker-compose.yml.tt +55 -0
  151. data/lib/kowl/templates/docker/mysql/Dockerfile.tt +15 -0
  152. data/lib/kowl/templates/dotfiles/Aptfile.tt +34 -0
  153. data/lib/kowl/templates/dotfiles/Brewfile.tt +49 -0
  154. data/lib/kowl/templates/dotfiles/Procfile.tt +12 -0
  155. data/lib/kowl/templates/dotfiles/codeclimate.yml +76 -0
  156. data/lib/kowl/templates/dotfiles/coffeelint.json +10 -0
  157. data/lib/kowl/templates/dotfiles/coffeelintignore +15 -0
  158. data/lib/kowl/templates/dotfiles/dockerignore +23 -0
  159. data/lib/kowl/templates/dotfiles/editorconfig +13 -0
  160. data/lib/kowl/templates/dotfiles/env.tt +58 -0
  161. data/lib/kowl/templates/dotfiles/erb-lint.yml +10 -0
  162. data/lib/kowl/templates/dotfiles/erdconfig.tt +24 -0
  163. data/lib/kowl/templates/dotfiles/eslintignore +20 -0
  164. data/lib/kowl/templates/dotfiles/eslintrc.js +31 -0
  165. data/lib/kowl/templates/dotfiles/fasterer.yml +14 -0
  166. data/lib/kowl/templates/dotfiles/foreman +1 -0
  167. data/lib/kowl/templates/dotfiles/gitattributes +15 -0
  168. data/lib/kowl/templates/dotfiles/gitignore +69 -0
  169. data/lib/kowl/templates/dotfiles/haml-lint.yml +23 -0
  170. data/lib/kowl/templates/dotfiles/jsbeautifyrc +15 -0
  171. data/lib/kowl/templates/dotfiles/jshintrc +3 -0
  172. data/lib/kowl/templates/dotfiles/mailmap +3 -0
  173. data/lib/kowl/templates/dotfiles/nvmrc +1 -0
  174. data/lib/kowl/templates/dotfiles/prettierignore +21 -0
  175. data/lib/kowl/templates/dotfiles/prettierrc.js +62 -0
  176. data/lib/kowl/templates/dotfiles/pryrc +7 -0
  177. data/lib/kowl/templates/dotfiles/rspec +3 -0
  178. data/lib/kowl/templates/dotfiles/rubocop.yml.tt +78 -0
  179. data/lib/kowl/templates/dotfiles/scss-lint.yml +132 -0
  180. data/lib/kowl/templates/dotfiles/simplecov +19 -0
  181. data/lib/kowl/templates/dotfiles/slim-lint.yml +23 -0
  182. data/lib/kowl/templates/dotfiles/slugignore +10 -0
  183. data/lib/kowl/templates/dotfiles/yamllint +7 -0
  184. data/lib/kowl/templates/dotfiles/yarnclean +46 -0
  185. data/lib/kowl/templates/lib/tasks/stats.rake +42 -0
  186. data/lib/kowl/templates/tests/factories/README.md +0 -0
  187. data/lib/kowl/templates/tests/factories/login_activity.rb +11 -0
  188. data/lib/kowl/templates/tests/factories/user.rb +11 -0
  189. data/lib/kowl/templates/tests/minitest/README.md +3 -0
  190. data/lib/kowl/templates/tests/minitest/application_system_test_case.rb +7 -0
  191. data/lib/kowl/templates/tests/minitest/controllers/pages_controller_test.rb +10 -0
  192. data/lib/kowl/templates/tests/minitest/models/login_activity_test.rb +8 -0
  193. data/lib/kowl/templates/tests/minitest/models/user_test.rb +15 -0
  194. data/lib/kowl/templates/tests/minitest/policies/login_activity_policy_test.rb +7 -0
  195. data/lib/kowl/templates/tests/minitest/policies/user_policy_test.rb +7 -0
  196. data/lib/kowl/templates/tests/minitest/support/capybara.rb +38 -0
  197. data/lib/kowl/templates/tests/minitest/support/database_cleaner.rb +20 -0
  198. data/lib/kowl/templates/tests/minitest/support/database_cleaner_support.rb +15 -0
  199. data/lib/kowl/templates/tests/minitest/support/deferred_garbage_collection.rb +21 -0
  200. data/lib/kowl/templates/tests/minitest/support/devise.rb +16 -0
  201. data/lib/kowl/templates/tests/minitest/support/factories.rb +6 -0
  202. data/lib/kowl/templates/tests/minitest/support/formulaic.rb +8 -0
  203. data/lib/kowl/templates/tests/minitest/support/helpers/devise_helper.rb +57 -0
  204. data/lib/kowl/templates/tests/minitest/support/papertrail.rb +17 -0
  205. data/lib/kowl/templates/tests/minitest/support/pundit.rb +0 -0
  206. data/lib/kowl/templates/tests/minitest/support/shoulda.rb +11 -0
  207. data/lib/kowl/templates/tests/minitest/support/simplecov.rb +8 -0
  208. data/lib/kowl/templates/tests/minitest/test_helper.rb +17 -0
  209. data/lib/kowl/templates/tests/rspec/README.md +9 -0
  210. data/lib/kowl/templates/tests/rspec/controllers/admin/application_controller_spec.rb +12 -0
  211. data/lib/kowl/templates/tests/rspec/controllers/admin/users_controller_spec.rb +14 -0
  212. data/lib/kowl/templates/tests/rspec/controllers/pages_controller_spec.rb +10 -0
  213. data/lib/kowl/templates/tests/rspec/features/README.md +15 -0
  214. data/lib/kowl/templates/tests/rspec/features/visitor_sign_up_spec.rb +25 -0
  215. data/lib/kowl/templates/tests/rspec/helpers/application_helper_spec.rb +7 -0
  216. data/lib/kowl/templates/tests/rspec/helpers/pages_helper_spec.rb +15 -0
  217. data/lib/kowl/templates/tests/rspec/models/login_activity_spec.rb +11 -0
  218. data/lib/kowl/templates/tests/rspec/models/user_spec.rb +21 -0
  219. data/lib/kowl/templates/tests/rspec/policies/login_activity_policy_spec.rb +59 -0
  220. data/lib/kowl/templates/tests/rspec/policies/user_policy_spec.rb +56 -0
  221. data/lib/kowl/templates/tests/rspec/rails_helper.rb +72 -0
  222. data/lib/kowl/templates/tests/rspec/requests/pages_spec.rb +11 -0
  223. data/lib/kowl/templates/tests/rspec/spec_helper.rb +96 -0
  224. data/lib/kowl/templates/tests/rspec/support/bullet.rb +17 -0
  225. data/lib/kowl/templates/tests/rspec/support/capybara.rb +37 -0
  226. data/lib/kowl/templates/tests/rspec/support/controller_testing.rb +10 -0
  227. data/lib/kowl/templates/tests/rspec/support/database_cleaner.rb +55 -0
  228. data/lib/kowl/templates/tests/rspec/support/deferred_garbage_collection.rb +32 -0
  229. data/lib/kowl/templates/tests/rspec/support/devise.rb +21 -0
  230. data/lib/kowl/templates/tests/rspec/support/factories.rb +5 -0
  231. data/lib/kowl/templates/tests/rspec/support/formulaic.rb +8 -0
  232. data/lib/kowl/templates/tests/rspec/support/helpers/devise_helpers.rb +56 -0
  233. data/lib/kowl/templates/tests/rspec/support/papertrail.rb +5 -0
  234. data/lib/kowl/templates/tests/rspec/support/pi_ci.rb +6 -0
  235. data/lib/kowl/templates/tests/rspec/support/pundit.rb +6 -0
  236. data/lib/kowl/templates/tests/rspec/support/shoulda.rb +10 -0
  237. data/lib/kowl/templates/tests/rspec/support/sidekiq.rb +10 -0
  238. data/lib/kowl/templates/tests/rspec/support/simplecov.rb +7 -0
  239. data/lib/kowl/templates/tests/rspec/support/warden.rb +8 -0
  240. data/lib/kowl/templates/text_files/AUTHORS.md +4 -0
  241. data/lib/kowl/templates/text_files/CHANGELOG.md.tt +12 -0
  242. data/lib/kowl/templates/text_files/CODE_OF_CONDUCT.md +76 -0
  243. data/lib/kowl/templates/text_files/TODO.md +7 -0
  244. data/lib/kowl/templates/text_files/VERSION +1 -0
  245. data/lib/kowl/templates/text_files/humans.txt.tt +15 -0
  246. data/lib/kowl/templates/text_files/robots.txt.tt +6 -0
  247. data/lib/kowl/templates/text_files/security.txt +6 -0
  248. data/lib/kowl/version.rb +9 -0
  249. data/lib/kowl.rb +18 -0
  250. metadata +404 -0
@@ -0,0 +1,240 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'fileutils'
4
+ require 'active_support'
5
+ require 'rails/generators/base'
6
+
7
+ # https://github.com/rails/rails/blob/66cabeda2c46c582d19738e1318be8d59584cc5b/railties/lib/rails/generators/actions.rb
8
+ module Kowl
9
+ module Actions
10
+ # Used to call a rails system command
11
+ # @param cmd [String] The rails command that will be executed, ie: db:migrate
12
+ # @return [Boolean] if the rails command was succcessfully executed or not
13
+ def rails_cmd(cmd = '')
14
+ return nil if cmd.blank?
15
+
16
+ system("bin/rails #{cmd}")
17
+ end
18
+
19
+ # Used to install yarn package is NPM/Yarn is available
20
+ # @param pkg [String] The Yarn/npm package in which to install with the Rails Application
21
+ # @return [Boolean] if the yarn package was successfully installed or not
22
+ def add_package(pkg = '')
23
+ return false if pkg.blank?
24
+
25
+ system("bin/yarn add #{pkg}")
26
+ end
27
+
28
+ # Append a string to the end of a specied file
29
+ # @param file [String] Filename to append the string to
30
+ # @param str [String] String to add to the specified file
31
+ # @return [Boolean] if the string was appended to the file or not
32
+ def append_to_file(file, str)
33
+ File.open(file, 'a+') { |f| f << str }
34
+ end
35
+
36
+ # Validate if a specified file exists
37
+ # @param file [String] Filename to validate against
38
+ # @return [Boolean] Returns whether if the file exists or not
39
+ def file_exists?(file)
40
+ File.file? file
41
+ end
42
+
43
+ # Dupliate a specified file (make a copy)
44
+ # @param source [String] The originating file in which you wish to duplicate
45
+ # @param destination [String] The destination of the file in which you are duplicating to
46
+ # @return [Boolean, nil] Returns nil if the source or destination where not specified. Otherwise if should return true/false if the file was actually duplicated
47
+ def dup_file(source, destination)
48
+ return nil if source.blank? || destination.blank?
49
+
50
+ FileUtils.cp(source, destination) if file_exists?(source)
51
+ end
52
+
53
+ # Create a specific directory
54
+ # @param path [String] The path in which you wish to create
55
+ # @return [Boolean] if the filepath was created or not
56
+ def mk_dir(path)
57
+ FileUtils.mkdir_p(path) unless File.directory?(path)
58
+ end
59
+
60
+ # Delete a specific directory path
61
+ # src: https://github.com/solidusio/solidus/blob/master/core/lib/generators/spree/dummy/dummy_generator.rb#L128
62
+ # @param path [String] The specifc directory which you wish to remove
63
+ # @return [Boolean] if the FileDir was removed or not
64
+ def remove_dir(path)
65
+ FileUtils.remove_dir(path) if File.directory?(path)
66
+ end
67
+
68
+ # Delete a specific file from the projects directory structure
69
+ # @param file [String] The specific file in which you wish to delete
70
+ # @return [Boolean, nil] Returns nil if the filename is blank, otherwise it should return true/false if the file was properly removed
71
+ def remove_file(file)
72
+ return nil if file.blank?
73
+
74
+ FileUtils.rm(file, force: true) if file_exists?(file)
75
+ end
76
+
77
+ # Move a file to a specified location
78
+ # @param file [String] The original file location in which you want to move the file from
79
+ # @param destination [String] The destintion location of where you would like to move this file to
80
+ # @return [Boolean, nil] Return nil if the file or destrination are blank. Otherwise it will return true/false if the file was successfully moved
81
+ def move_file(file, destination)
82
+ return nil if file.blank? || destination.blank?
83
+
84
+ FileUtils.mv(file, destination, force: true) if file_exists?(file)
85
+ end
86
+
87
+ # Used to remove a gem from the Gemfile and bundle installs afterwards
88
+ # @param gem [String] The Gem name which you would like to remove from the gemfile
89
+ # @return [nil] Returns nil if the the method is called without a gem specified
90
+ def remove_gem(gem)
91
+ return nil if gem.blank?
92
+
93
+ # Used to match if the user used double & single quotes ("|') around the gem and a variable amount of space
94
+ # used to match the following string variations
95
+ # gem 'puma'
96
+ # gem "puma"
97
+ # gem "puma", '~> 3.7'
98
+ # gem 'puma', github: 'puma/puma'
99
+ replace_string_in_file('Gemfile', "^[\s]?gem\s?[\'\"](#{gem})[\'\"](.+?)*[\s]?", '')
100
+ # Because we're removing a gem from the gemfile we need to bundle again
101
+ run 'bundle install --quiet'
102
+ end
103
+
104
+ # Replace a matching string within a specific file
105
+ # @param filename [String] The file in which you would like to change it's contents
106
+ # @param regex [String] The regular expression you would like to run against the line of text within the file
107
+ # @param replacement [String] The string in which you would like to replace any matches against
108
+ # @return [Boolean] if the string was successfully replaced in the specified file
109
+ def replace_string_in_file(filename, regex, replacement = '')
110
+ content = File.read(filename).gsub(/#{regex}$/i, replacement)
111
+ File.open(filename, 'wb') { |file| file.write(content) }
112
+ end
113
+
114
+ ##################################################
115
+ # Template Stuff
116
+ ##################################################
117
+
118
+ # Add config to the development environment
119
+ # @param str [String] A heredoc containing configuration changes for the development environment
120
+ # @return [Boolean] if the string was successfully injected into the development config file
121
+ def dev_config(str)
122
+ inject_into_file('config/environments/development.rb', optimize_indentation(str, 2), after: "config.assets.quiet = true\n")
123
+ end
124
+
125
+ ##################################################
126
+ # Routes
127
+ ##################################################
128
+ # Adds a development only route to access LetterOpener when developmenting the application
129
+ # @param skip_mailer [Boolean] A flag to determine if you want to skip using a mailer
130
+ # @return [String] the LetterOpener mount path (unless you have specied to skip_mailer)
131
+ def mailer_route(skip_mailer)
132
+ return '' if skip_mailer
133
+
134
+ " mount LetterOpenerWeb::Engine, at: \"/letter_opener\" if Rails.env.development?\n"
135
+ end
136
+
137
+ # Add PgHero engine mount to the routes if the database iss postgresql
138
+ # @param database [String] A string containing the applications defined database adapater
139
+ # @return [String] the pghero dashboard mount path, if postgresql will be used
140
+ def database_route(database = 'sqlite3')
141
+ return '' unless database.to_s == 'postgresql'
142
+
143
+ " mount PgHero::Engine, at: \"pghero\"\n"
144
+ end
145
+
146
+ # Unless specified the function will add a Sidekiq engine route to access in the routes
147
+ # @param options [Hash] A flag to determine if you would like the generators to skip adding sidekiq to the applicatiion
148
+ # @return [String] the sidekiq mount path
149
+ def sidekiq_route(options)
150
+ return '' if options[:skip_sidekiq]
151
+
152
+ " mount Sidekiq::Web => '/sidekiq'\n"
153
+ end
154
+
155
+ # Unless all extensions are skipped [mailer && sidekiq], will will add their mounts depending on if the add requires auth or not
156
+ # @param options [Hash] The entire generators options passed to it
157
+ # @return [String] the applications extensions mount paths for routes file
158
+ def add_extension_routes(options)
159
+ ext_routes = "#{database_route(options[:database])}#{mailer_route(options[:skip_mailer])}#{sidekiq_route(options)}"
160
+ routes_str = if options[:noauth]
161
+ <<~ROUTES
162
+ # If authentication has not been used; only allow this routes to be used in development to prevent authorized access
163
+ if Rails.env.development?
164
+ #{ext_routes.squeeze("\n").strip}
165
+ end
166
+ ROUTES
167
+ else
168
+ <<~ROUTES
169
+ # Require the person hitting this page ot be an application admin
170
+ authenticate :user, -> (user) { user.admin? } do
171
+ #{ext_routes.squeeze("\n").strip}
172
+ end
173
+ ROUTES
174
+ end
175
+ optimize_indentation(routes_str, 2)
176
+ end
177
+
178
+ ##################################################
179
+ # Gemfile specific functions
180
+ ##################################################
181
+ # Adds the specified mailer gem to the application
182
+ # @param mailer [String] Specfic mailer in which you would like to use
183
+ # @return [String] the applications mailer gem that will be added to the Gemfile
184
+ def mailer_gems(mailer = 'sparkpost')
185
+ if mailer.to_s == 'postmark'
186
+ "gem 'postmark-rails'"
187
+ else
188
+ "gem 'sparkpost_rails'"
189
+ end
190
+ end
191
+
192
+ # Outputs a set of Gemfile entries for the application developer to use pry in the rails console
193
+ # @param skip_pry [Boolean] if the developer wants to skip using pry with their application
194
+ # @return [nil, String] return the string to be added to the applications Gemfile
195
+ def pry_gems(skip_pry = false)
196
+ return nil if skip_pry
197
+
198
+ gems = <<~PRY
199
+ # Pry to cleanup the rails console
200
+ gem 'pry', '0.12.2'
201
+ gem 'pry-rails' # pry console output
202
+ gem 'spirit_hands' # A combination of pry, awesome_print, hirb, and numerous other console extensions
203
+ PRY
204
+ optimize_indentation(gems, 2)
205
+ end
206
+
207
+ # Determine which linter should be used for the aplication
208
+ # @param engine [String] The specified applications templating engine (erb, hal, or slim)
209
+ # @return [String] An gem line that will be added to the gemfile
210
+ def template_linter_gems(engine)
211
+ return '' if engine.blank?
212
+
213
+ case engine.to_s
214
+ when 'haml'
215
+ "gem 'haml_lint'#{gemfile_requirement('haml_lint')}, require: false"
216
+ when 'slim'
217
+ "gem 'slim_lint'#{gemfile_requirement('slim_lint')}, require: false"
218
+ else
219
+ "gem 'erb_lint', github: 'Shopify/erb-lint', require: false"
220
+ end
221
+ end
222
+
223
+ # Determine which rubcop gem should be used (dependant on the requested test suite)
224
+ # @param test_engine [String] The specified application test suite requested
225
+ # @param skip_tests [Boolean] if you would like skip using tests with the application
226
+ # @return [String] The gemfile rubocop gem entry based on the applications test suite
227
+ def robocop_test_engine(test_engine = '', skip_tests = false)
228
+ return '' if test_engine.blank? || skip_tests
229
+
230
+ case test_engine.to_s
231
+ when 'minitest'
232
+ "gem 'rubocop-minitest', require: false"
233
+ when 'rspec'
234
+ "gem 'rubocop-rspec', require: false"
235
+ else
236
+ ''
237
+ end
238
+ end
239
+ end
240
+ end
@@ -0,0 +1,447 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support'
4
+ require 'rails/generators/base'
5
+
6
+ # https://github.com/rails/rails/blob/66cabeda2c46c582d19738e1318be8d59584cc5b/railties/lib/rails/generators/actions.rb
7
+ # This class contains snips for dumping components into the applications Dockerfile and docker-compose files
8
+ module Kowl
9
+ module Docker
10
+ # Add the applications database commands to the Dockerfile
11
+ # @param database [String] a string containing the containers database type
12
+ # @return [String] the database commands you want to generate in the Dockerfile
13
+ def dockerfile_migration_snip(database = '')
14
+ return '' if database.blank?
15
+
16
+ if database == 'sqlite3'
17
+ ' && rails db:migrate db:seed'
18
+ else
19
+ <<~DB_MIGRATION_STR
20
+
21
+ # Uncomment if you want to have your database setup when the container is running
22
+ # => Note your database should generally be setup own it's own, but this can be used if running such as docker-compose
23
+ # => where the database is another Docker container
24
+ # RUN rails db:create db:migrate
25
+ # RUN ["bin/rails", "db:seed"]
26
+ DB_MIGRATION_STR
27
+ end
28
+ end
29
+
30
+ # This is required, during built; because ENV variables are passed from the docker-compose file using env_file
31
+ # These variables aren't picked up by the container unless they are specified as ARGS and ENV values in the dockerfile
32
+ # they are assigned as args in case the user wwants to dynamically change the database credentials the container connects to.
33
+ # @return [String] list of docker database arguements and env variables
34
+ def dockerfile_database_args
35
+ <<~DB_VARIABLES
36
+ # Database Arguements passed when docker image is building
37
+ ARG DB_HOST
38
+ ARG DB_PASSWORD
39
+ ARG DB_USER
40
+ ENV DB_HOST=$DB_HOST \\
41
+ DB_PASSWORD=$DB_PASSWORD \\
42
+ DB_USER=$DB_USER
43
+ DB_VARIABLES
44
+ end
45
+
46
+ # For generating the docker services depends_on tag for all services it requires in order to run
47
+ # @param options [Hash] the specified options for the docker service your are including
48
+ # @return [String] the depends_on string and the docker services required services (in order to run)
49
+ def docker_depends_on(options = {})
50
+ database = options.fetch(:database) { 'sqlite3' }
51
+ skip_sidekiq = options.fetch(:skip_sidekiq) { false }
52
+ indention = options.fetch(:indention) { 4 }
53
+ requires_base = options.fetch(:requires_base) { false }
54
+ spaces = options.fetch(:spaces) { 4 }
55
+ return nil if requires_base == false && database == 'sqlite3' && skip_sidekiq
56
+
57
+ base_str = (requires_base ? optimize_indentation("- base\n", indention) : '')
58
+ db_str = optimize_indentation("- db\n", indention) unless database == 'sqlite3'
59
+ redis_str = optimize_indentation("- redis\n", indention) unless skip_sidekiq
60
+ spaces_str = (' ' * spaces)
61
+ depends_on = <<~DEPENDS_ON
62
+ #{spaces_str}depends_on:
63
+ #{base_str}#{db_str}#{redis_str}
64
+ DEPENDS_ON
65
+ # Used to strip off additional trailing \n in cause both components aren't used
66
+ depends_on.chomp
67
+ end
68
+
69
+ # Used to generate and return a string for adding a Redis docker service to the docker-compose file
70
+ # @return [String] returns a string containg the entire redis service config for the docker-compose filee
71
+ def docker_redis_service
72
+ <<-REDIS_SERVICE
73
+ redis:
74
+ image: redis:alpine
75
+ ports:
76
+ - 6379:6379
77
+ networks:
78
+ - internal_network
79
+ volumes:
80
+ - redis:/data
81
+ healthcheck:
82
+ test: redis-cli ping
83
+ interval: 1s
84
+ timeout: 3s
85
+ retries: 30
86
+ sysctls:
87
+ # https://github.com/docker-library/redis/issues/35
88
+ net.core.somaxconn: '511'
89
+ REDIS_SERVICE
90
+ end
91
+
92
+ # Generate and return the sidekiq service for the applicatio
93
+ # @param database [String] a string containing the containers database type
94
+ # @return [String] a string containing the sidekiq service for the docker-compose filee
95
+ def docker_sidekiq_service(database = 'sqlite3')
96
+ cmd_str = "#{docker_port_watcher(database, false)}rm -rf /app/.local >/dev/null 2>&1 &&\nbundle exec sidekiq"
97
+ cmd_str = optimize_indentation(cmd_str, 13).strip
98
+
99
+ <<-SIDEKIQ_SERVICE
100
+ sidekiq:
101
+ <<: *x-app_base
102
+ image: #{app_name}_base:latest
103
+ command: >
104
+ sh -c "#{cmd_str}"
105
+ depends_on:
106
+ - base
107
+ SIDEKIQ_SERVICE
108
+ end
109
+
110
+ # Generate a string containing the applications webpacker service (for recompiling new assets)
111
+ # @param options [Hash] applications options for the application generator (ie: skip_javascript)
112
+ # @return [String] a string containing the docker-compose webpacker entry
113
+ def docker_webpacker_service(options)
114
+ return '' if options[:skip_javascript]
115
+
116
+ webpacker_str = <<-WEBPACKER
117
+ webpacker:
118
+ <<: *x-app_base
119
+ image: #{app_name}_base:latest
120
+ command: ./bin/webpack-dev-server
121
+ ports:
122
+ - '3035:3035'
123
+ environment:
124
+ WEBPACKER_DEV_SERVER_HOST: 0.0.0.0
125
+ depends_on:
126
+ - base
127
+ WEBPACKER
128
+ webpacker_str.chomp
129
+ end
130
+
131
+ # If a database is to be used (other than sqlite3) thiss creates the docker-compose service
132
+ # @param database [String] the specific database the application will be running on
133
+ # @return [String] returns a string containing the database service entry for the docker-compose file
134
+ def docker_databases(database)
135
+ return nil if database.blank? || database == 'sqlite3'
136
+
137
+ case database.to_s
138
+ when 'mysql'
139
+ db_service = <<-DB_SERVICE
140
+ # https://hub.docker.com/_/mysql
141
+ image: mysql:latest
142
+ container_name: mysql
143
+ environment:
144
+ - MYSQL_DATABASE=#{app_name}_development
145
+ - MYSQL_USER=${DB_USER}
146
+ - MYSQL_PASSWORD=${DB_PASSWORD}
147
+ - MYSQL_RANDOM_ROOT_PASSWORD=true
148
+ volumes:
149
+ - mysqldata:/var/lib/mysql
150
+ healthcheck:
151
+ test: "/usr/bin/mysql --user=${DB_USER} --password=${DB_PASSWORD} --execute \\"SHOW DATABASES;\\""
152
+ interval: 3s
153
+ timeout: 45s
154
+ retries: 10
155
+ ports:
156
+ - 3306:3306
157
+ DB_SERVICE
158
+ when 'oracle'
159
+ db_service = <<-DB_SERVICE
160
+ image: wnameless/oracle-xe-11g-r2
161
+ environment:
162
+ # Disable the disk asynch IO (improves performance)
163
+ - ORACLE_DISABLE_ASYNCH_IO=true
164
+ - ORACLE_ALLOW_REMOTE=true
165
+ ports:
166
+ - 1521:1521
167
+ DB_SERVICE
168
+ when 'postgresql'
169
+ db_service = <<-DB_SERVICE
170
+ # https://hub.docker.com/_/postgres
171
+ image: postgres:12-alpine
172
+ environment:
173
+ - PSQL_HISTFILE=/root/log/.psql_history
174
+ - POSTGRES_USER=${DB_USER}
175
+ - POSTGRES_PASSWORD=${DB_PASSWORD}
176
+ - POSTGRES_NON_DURABLE_SETTINGS=1
177
+ # https://gilgamezh.me/en/posts/postgres-non-durable-options-docker-container/
178
+ volumes:
179
+ # - ./tmp/db:/var/lib/postgresql/data
180
+ - postgresdata:/var/lib/postgresql/data
181
+ - postgresconfig:/etc/postgresql
182
+ - postgreslog:/var/log/postgresql
183
+ healthcheck:
184
+ test: ["CMD", "pg_isready", "-U", "${DB_USER}"]
185
+ timeout: 45s
186
+ interval: 5s
187
+ retries: 10
188
+ ports:
189
+ - 5432:5432
190
+ DB_SERVICE
191
+ when 'sqlserver'
192
+ db_service = <<-DB_SERVICE
193
+ # https://hub.docker.com/_/microsoft-mssql-server
194
+ image: mcr.microsoft.com/mssql/server:2017-latest
195
+ environment:
196
+ - ACCEPT_EULA=Y
197
+ - SA_PASSWORD=${DB_PASSWORD}
198
+ ports:
199
+ - 1433:1433
200
+ DB_SERVICE
201
+ end
202
+
203
+ db_str = <<-DOCKER_COMPOSE_DATABASE
204
+ db:
205
+ #{db_service.strip}
206
+ env_file: .env
207
+ stdin_open: true
208
+ tty: true
209
+ restart: always
210
+ networks:
211
+ - internal_network
212
+ DOCKER_COMPOSE_DATABASE
213
+ db_str
214
+ end
215
+
216
+ # Returns a command for the docker-compose app service
217
+ # @param database [String] database to use for the application
218
+ # @return [String] a bundle exec command for the docker-compose app service
219
+ def docker_compose_database_string(database)
220
+ case database.to_s
221
+ when 'mysql', 'oracle', 'sqlite3'
222
+ "bundle exec rails db:migrate db:seed >/dev/null 2>&1 &&\n"
223
+ when 'sqlserver'
224
+ "bundle exec rails db:setup >/dev/null 2>&1 &&\n"
225
+ when 'postgresql'
226
+ "bundle exec rails db:setup db:test:prepare db:seed >/dev/null 2>&1 &&\n"
227
+ else
228
+ ''
229
+ end
230
+ end
231
+
232
+ # Generate the command for the application service in the applications docker-compose file
233
+ # @param database [String] the specific database the application will be running on
234
+ # @param skip_sidekiq [Boolean] if the application will skip using sidekiq
235
+ # @return [String] the CMD entry for applications service entry in the docker-compose file
236
+ def docker_app_command(database, skip_sidekiq = false)
237
+ db_str = docker_compose_database_string(database)
238
+ joined_cmd_str = "#{docker_port_watcher(database, skip_sidekiq)}#{db_str}".strip
239
+ # This is used in case the app is generated with --database=sqlite && --skip_sidekiq
240
+ # => Thus meaning it doesn't to wait on a database and redis to connect to container before running it
241
+ joined_cmd_str = joined_cmd_str.blank? ? '' : joined_cmd_str
242
+
243
+ cmd_str = <<~CMD_STR
244
+ #{joined_cmd_str}
245
+ rm -rf /app/tmp/pids/server.pid /app/.local >/dev/null 2>&1 &&
246
+ bundle exec rails s -p 3000 -b 0.0.0.0
247
+ CMD_STR
248
+ optimize_indentation(cmd_str, 13).strip
249
+ end
250
+
251
+ # Create a CMD entry for services to watch before firing up the specific application
252
+ # @param database [String] the specific database the application will be running on
253
+ # @param skip_sidekiq [Boolean] if the application will skip using sidekiq
254
+ # @return [String] a list of services and posts to watch before running the new command
255
+ def docker_port_watcher(database, skip_sidekiq = false)
256
+ return '' if database == 'sqlite3' && skip_sidekiq
257
+
258
+ db_port = if database == 'mysql'
259
+ '3306'
260
+ elsif database == 'oracle'
261
+ '1521'
262
+ elsif database == 'postgresql'
263
+ '5432'
264
+ elsif database == 'sqlserver'
265
+ '1433'
266
+ else
267
+ ''
268
+ end
269
+ return '' if db_port.blank? && skip_sidekiq
270
+
271
+ service_list = []
272
+ service_list << "-wait tcp://db:#{db_port}" unless db_port.blank? || database == 'sqlite3'
273
+ service_list << '-wait tcp://redis:6379' unless skip_sidekiq
274
+ service_watcher_str = service_list.empty? ? '' : "dockerize #{service_list.join(' ')}"
275
+ "#{service_watcher_str.strip} -timeout 60m &&\n"
276
+ end
277
+
278
+ # Create a list of variables and values for the docker-compose file depending on requirements
279
+ # @param options [Hash] the generators options and flags for the application you are generating
280
+ # @return [String] a string containing a list of variables for the docker-compose filee
281
+ def docker_variables(options)
282
+ vars_str = "BINDING: 0.0.0.0\n"
283
+ vars_str += "COMPOSE_HTTP_TIMEOUT: 300\n"
284
+ vars_str += "DB_HOST: db\n" unless options[:database] == 'sqlite3'
285
+ vars_str += "RAILS_ENV: ${RAILS_ENV:-development}\n"
286
+ vars_str += "REDIS_URL: redis://redis:6379/0\n" unless options[:skip_sidekiq]
287
+ vars_str += "WEBPACKER_DEV_SERVER_HOST: webpacker\n" unless options[:skip_javascript]
288
+ vars_str += "WEB_CONCURRENCY: 1\n"
289
+
290
+ optimize_indentation(vars_str.strip, 4)
291
+ end
292
+
293
+ ##################################################
294
+ # Docker-compose volumes
295
+ ##################################################
296
+ # Used when generating docker-compose to determine what volumes will be created for the application
297
+ # @param options [Hash] the generators options and flags for the application you are generating
298
+ # @return [String] a list of volumes for the apps docker-compose file depending on the apps requirements
299
+ def docker_volumes(options)
300
+ volume_str = <<~VOLUME_STR
301
+ bundle:
302
+ rails_cache:
303
+ #{db_volumes(options[:database]).strip}
304
+ #{js_volumes(options[:skip_javascript]).strip}
305
+ #{redis_volumes(options[:skip_sidekiq]).strip}
306
+ VOLUME_STR
307
+ optimize_indentation(volume_str.squeeze("\n").strip, 2)
308
+ end
309
+
310
+ # List of JS volumes to use for the apps docker-compose filees
311
+ # @return [String] a list of volumes for the apps node_modules and js builds
312
+ def app_js_volumes
313
+ <<~JS_VOLUMES
314
+ - node_modules:/app/node_modules
315
+ - packs:/app/public/packs
316
+ JS_VOLUMES
317
+ end
318
+
319
+ # Generate a list of volumes to attach to the applications docker-compose service
320
+ # @param skip_javascript [Boolean] to determine if dependencies need to be taken into account for
321
+ # @param indention [Integer] number spaces to indent in the docker-compose.yml file
322
+ # @return [String] a list of volumes for the application yaml file
323
+ def app_volumes(skip_javascript = false, indention = 2)
324
+ js_volumes_str = app_js_volumes unless skip_javascript
325
+ volumes_str = <<~VOLUMES
326
+ - .:/app:cached
327
+ - bundle:/app/vendor/cache
328
+ #{js_volumes_str}
329
+ - rails_cache:/app/tmp/cache
330
+ VOLUMES
331
+ optimize_indentation(volumes_str.squeeze("\n").strip, indention)
332
+ end
333
+
334
+ # Return volumes for docker-compose database services
335
+ # @param database [String] the applications required database adapter
336
+ # @return [String] volumes for specific database containers
337
+ def db_volumes(database)
338
+ return '' unless %w[mysql postgresql].include?(database)
339
+
340
+ case database
341
+ when 'mysql'
342
+ mysql_volumes
343
+ when 'postgresql'
344
+ postgresql_volumes
345
+ else
346
+ ''
347
+ end
348
+ end
349
+
350
+ # Return a list of JS volumes for the application
351
+ # @param skip_javascript [Boolean] if JS/node will be used with the application or not
352
+ # @return [String] a list of js specific volumes for the application
353
+ def js_volumes(skip_javascript = false)
354
+ return '' if skip_javascript
355
+
356
+ <<~JS_VOLUMES
357
+ node_modules:
358
+ packs:
359
+ JS_VOLUMES
360
+ end
361
+
362
+ # Return a list of volumes for the mysql database service in the docker-compose.yml file
363
+ # @return [String] an entry for the mysql volume name
364
+ def mysql_volumes
365
+ <<~DB_STR
366
+ mysqldata:
367
+ DB_STR
368
+ end
369
+
370
+ # Return a list of volume names for the postgresql database service in the docker-compose.yml file
371
+ # @return [String] a list of volume names for the postgresql database
372
+ def postgresql_volumes
373
+ <<~DB_STR
374
+ postgresconfig:
375
+ postgresdata:
376
+ postgreslog:
377
+ DB_STR
378
+ end
379
+
380
+ # Return a volume name for the redis service in the docker-compose.yml file
381
+ # @param skip_sidekiq [Boolean] a flag if the application will be using sidekiq or not
382
+ # @return [String] the redis service volume
383
+ def redis_volumes(skip_sidekiq = false)
384
+ skip_sidekiq ? '' : 'redis:'
385
+ end
386
+
387
+ # Used to generate a dependencies list in the dockerfile based on the applications requirements
388
+ # @param options [Hash] the applications specified options
389
+ # @return [String] an apk string for installing dependencies in the dockerfile
390
+ def alpine_docker_dependencies(options = {})
391
+ # core dependencies
392
+ dependencies = %w[brotli dumb-init git sqlite sqlite-dev tzdata vips vips-dev yarn]
393
+ # optional dependencies
394
+ dependencies << 'graphviz' unless options[:skip_erd]
395
+ dependencies << 'libsodium-dev' if options[:encrypt]
396
+
397
+ # database dependencies
398
+ case options[:database]
399
+ when 'mysql'
400
+ dependencies << 'mysql-dev'
401
+ when 'postgresql'
402
+ dependencies << 'postgresql-dev'
403
+ when 'sqlserver'
404
+ dependencies << 'freetds-dev'
405
+ end
406
+ return '' if dependencies.empty?
407
+
408
+ dep_str = "apk add #{dependencies.sort.join(' ')} >/dev/null 2>&1 && \\\n"
409
+ optimize_indentation(dep_str, 4)
410
+ end
411
+
412
+ # Return a list of dependencies to inject into the applications Dockerfile (if they are using Debian)
413
+ # @param options [Hash] a list of the applictions specific options to determine what all dependencies are required
414
+ # @return [String] an `apt-get install` with a list of all the applications dependencies listed
415
+ def debian_docker_dependencies(options = {})
416
+ dependencies = %w[brotli curl git libjemalloc-dev libsqlite3-dev libvips sqlite3 wget]
417
+
418
+ # optional dependencies
419
+ dependencies << 'graphviz' unless options[:skip_erd]
420
+ dependencies << 'libsodium23' if options[:encrypt]
421
+ # database dependencies
422
+ dependencies << debian_database_dependencies(options[:database]) if %w[mysql oracle postgresql sqlserver].include?(options[:database])
423
+ return '' if dependencies.empty?
424
+
425
+ dep_str = "apt-get install -qq --no-install-recommends #{dependencies.sort.join(' ')} 2>/dev/null && \\\n"
426
+ optimize_indentation(dep_str, 4)
427
+ end
428
+
429
+ # Return a list of apt packages to install for Debian docker image
430
+ # @param database [String] the applications specific database adapter that will be used
431
+ # @return [String] a list of dependencies to install depending on the applications specific database
432
+ def debian_database_dependencies(database)
433
+ return '' if database.blank?
434
+
435
+ case database
436
+ when 'mysql'
437
+ 'mysql-client'
438
+ when 'oracle'
439
+ 'alien libaio1'
440
+ when 'postgresql'
441
+ 'postgresql-client libpq-dev'
442
+ when 'sqlserver'
443
+ 'libpq-dev libc6-dev'
444
+ end
445
+ end
446
+ end
447
+ end
@@ -0,0 +1,5 @@
1
+ https://github.com/rails/rails/blob/master/guides/source/generators.md
2
+
3
+
4
+ Thor Options:
5
+ https://github.com/erikhuda/thor/wiki/Method-Options