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,249 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails/generators'
4
+ require 'rails/generators/rails/app/app_generator'
5
+ require_relative('../../actions')
6
+ require_relative('../../docker')
7
+ # https://github.com/rails/rails/blob/master/railties/lib/rails/generators/rails/app/app_generator.rb
8
+ # https://apidock.com/rails/Rails/Generators/AppGenerator
9
+ # https://www.rubydoc.info/gems/railties/5.0.0/Rails/Generators/AppGenerator#finish_template-instance_method
10
+ # https://doc.bccnsoft.com/docs/rails_3_2_22_api/classes/Rails/Generators/AppBase.html
11
+ # https://github.com/rails/rails/blob/master/guides/source/generators.md
12
+ # List of default rails options -> https://github.com/rails/rails/blob/master/railties/lib/rails/generators/app_base.rb#L27
13
+ module Kowl
14
+ module Overrides
15
+ class AppGenerator < Rails::Generators::AppGenerator
16
+ include Kowl::Actions
17
+ include Kowl::Docker
18
+ hide!
19
+ desc 'A gem for generating Rails applications and still be a step ahead'
20
+ ##################################################
21
+ # Options that accept parameters
22
+ ##################################################
23
+ class_option :database, type: :string, aliases: '-d', default: 'sqlite3',
24
+ desc: "Preconfigure for selected database (options: #{DATABASES.join('/')})"
25
+
26
+ class_option :framework, type: :string, default: 'bootstrap', enum: %w[bootstrap semantic none],
27
+ desc: 'Generate the application using a specific CSS Framework'
28
+
29
+ class_option :git_repo, type: :string, default: '',
30
+ desc: 'The remote git repo in which you would like to associate with.'
31
+
32
+ class_option :mailer, type: :string, default: 'sparkpost', enum: %w[postmark sparkpost],
33
+ desc: "Which transactional mailer you'd prefer your application to use."
34
+
35
+ class_option :template_engine, type: :string, default: 'erb', enum: %w[erb slim haml],
36
+ desc: 'The template_engine to use for generating the applications views (Erb, Slim, HAML)'
37
+
38
+ class_option :test_engine, type: :string, default: 'rspec', enum: %w[minitest rspec none],
39
+ desc: 'Which test framework would you like to use with the application'
40
+
41
+ ##################################################
42
+ # Options that are boolean and true if the flag is used
43
+ ##################################################
44
+ class_option :docker_distro, type: :string, default: 'alpine', enum: %w[alpine debian],
45
+ desc: 'Specify if you want your Docker base image to use Alpine or Debian'
46
+
47
+ class_option :encrypt, type: :boolean, default: false,
48
+ desc: 'Do you want user attribues encrypted? (For GDPR compliance, but breaks LIKE queries)'
49
+
50
+ class_option :noauth, type: :boolean, default: false,
51
+ desc: 'Skip adding Devise authentication to the application'
52
+
53
+ class_option :simpleform, type: :boolean, default: false,
54
+ desc: 'Do you want your application to use simpleform to generate forms'
55
+
56
+ class_option :skip_docker, type: :boolean, default: false,
57
+ desc: 'Skip adding basic Dockerfiles to the application'
58
+
59
+ class_option :skip_erd, type: :boolean, default: false,
60
+ desc: 'Skip adding the ERD components to the application'
61
+
62
+ class_option :skip_git, type: :boolean, default: false, aliases: '-G',
63
+ desc: 'Skip commiting the project to a git repo'
64
+
65
+ class_option :skip_javascript, type: :boolean, default: false,
66
+ desc: 'Skip adding javascript assets to the template'
67
+
68
+ class_option :skip_mailer, type: :boolean, default: false,
69
+ desc: 'Skip setting up rails SMTP mailer'
70
+
71
+ class_option :skip_pagination, type: :boolean, default: false,
72
+ desc: 'Do you want to application to skip adding pagination to the views?'
73
+
74
+ class_option :skip_pry, type: :boolean, default: false,
75
+ desc: 'Do you want your application to skip pass on using pry for the rails console?'
76
+
77
+ class_option :skip_sidekiq, type: :boolean, default: false,
78
+ desc: 'Skip adding sidekiq to the rails application'
79
+
80
+ class_option :skip_spring, type: :boolean, default: false,
81
+ desc: 'Do you want to skip'
82
+
83
+ # Skipping tests is a dangerous behavior to practice
84
+ class_option :skip_tests, type: :boolean, default: false, aliases: '-T',
85
+ desc: 'Determine if you would like to skip building tets for the application'
86
+
87
+ class_option :skip_turbolinks, type: :boolean, default: false,
88
+ desc: 'Determine if you want to skip having turbolinks included in your application'
89
+
90
+ # You'll want to set this as true, that way Oracle and/or SQLserver gems can be added to the gemfile
91
+ # Otherwise you'll get exceptione errors from Psych and Rails causing `rails new` to fail
92
+ class_option :skip_webpack_install, type: :boolean, default: true
93
+
94
+ class_option :uuid, type: :boolean, default: false,
95
+ desc: 'If database is set as PostgreSQL and UUID is enabled, all primary keys will be generated as UUIDs'
96
+
97
+ # If the person wants to use webpack in their application (vuew, react etc)
98
+ WEBPACKS = %w[react vue angular elm stimulus].freeze
99
+ class_option :webpack, type: :string, default: nil, aliases: '-W',
100
+ desc: "Preconfigure for app-like JavaScript with Webpack (options: #{WEBPACKS.join('/')})"
101
+
102
+ ### RAILS OVERRIDES
103
+ # Used to overwrite the the default rails behavior of bundling as soon as an application is generated
104
+ # => Otherwise the application generator will also do a bundle install after a custom Gemfile has been generated
105
+ class_option :skip_bundle, type: :boolean, aliases: '-B', default: true,
106
+ desc: "Don't set as true, this is a RAILS override to prevent extra bundle installs"
107
+
108
+ # Used with Rails5 template, or if javascript isn
109
+ # def finish_template
110
+ # invoke :kowl_run_generators
111
+ # # used to bundle install or run various bundle commands through the template
112
+ # super
113
+ # end
114
+
115
+ # Used with Rails6 v6, because this has the application generate.
116
+ # => We want it after the applicaton config and assets are generated, otherwise it generates a large number of errors
117
+ def run_after_bundle_callbacks
118
+ super
119
+ invoke :kowl_generators unless options[:skip_javascript]
120
+ end
121
+
122
+ ############################################################
123
+ # Custom generator actions for processing of the template
124
+ ############################################################
125
+
126
+ # Begin calling all the Kowl application generators to override the default rails application based on the options supplied
127
+ def kowl_generators
128
+ build :replace_gemfile
129
+ build :procfile
130
+ bundle_command 'install --jobs=4 --retry=3 --quiet'
131
+ bundle_command 'exec spring stop' unless options[:skip_spring]
132
+ invoke :install_webpack_assets
133
+ invoke :setup_staging # Ran afterwards webpack is setup for oracle, because it also createas a staging webpacker file
134
+
135
+ generate("kowl:config --database=#{options[:database]} --encrypt=#{options[:encrypt]} --framework=#{options[:framework]} --noauth=#{options[:noauth]} --skip_docker=#{options[:skip_docker]} --skip_erd=#{options[:skip_erd]} --skip_pagination=#{options[:skip_pagination]} --skip_sidekiq=#{options[:skip_sidekiq]} --skip_tests=#{options[:skip_tests]} --template_engine=#{options[:template_engine]} --simpleform=#{options[:simpleform]} --test_engine=#{options[:test_engine]} --uuid=#{options[:uuid]}")
136
+ generate('kowl:uuid') if options[:database] == 'postgresql' && options[:uuid]
137
+ generate("kowl:dotfiles --database=#{options[:database]} --encrypt=#{options[:encrypt]} --skip_docker=#{options[:skip_docker]} --skip_erd=#{options[:skip_erd]} --skip_javascript=#{options[:skip_javascript]} --skip_mailer=#{options[:skip_mailer]} --skip_pry=#{options[:skip_pry]} --skip_sidekiq=#{options[:skip_sidekiq]} --skip_tests=#{options[:skip_tests]} --test_engine=#{options[:test_engine]} --template_engine=#{options[:template_engine]} ")
138
+ generate("kowl:assets --framework=#{options[:framework]} --noauth=#{options[:noauth]} --skip_javascript=#{options[:skip_javascript]} --skip_mailer=#{options[:skip_mailer]} --skip_turbolinks=#{options[:skip_turbolinks]}")
139
+ generate("kowl:views_and_helpers --framework=#{options[:framework]} --noauth=#{options[:noauth]} --simpleform=#{options[:simpleform]} --skip_javascript=#{options[:skip_javascript]} --skip_pagination=#{options[:skip_pagination]} --skip_turbolinks=#{options[:skip_turbolinks]} --template_engine=#{options[:template_engine]}")
140
+ generate("kowl:users_and_auth --database=#{options[:database]} --encrypt=#{options[:encrypt]} --framework=#{options[:framework]} --skip_javascript=#{options[:skip_javascript]} --skip_mailer=#{options[:skip_mailer]} --skip_pagination=#{options[:skip_pagination]} --skip_sidekiq=#{options[:skip_sidekiq]} --template_engine=#{options[:template_engine]}") unless options[:noauth]
141
+ # tests are generated after users, because devise migrations tries to create empty minitest and rspec migration tests
142
+ generate("kowl:test --noauth=#{options[:noauth]} --test_engine=#{options[:test_engine]}") unless options[:test_engine] == :none || options[:skip_tests]
143
+ generate('kowl:staging') unless options[:database] == 'sqlite3'
144
+ generate("kowl:controller --noauth=#{options[:noauth]}")
145
+ generate("kowl:database --database=#{options[:database]} --noauth=#{options[:noauth]}")
146
+ generate("kowl:action --database=#{options[:database]} --simpleform=#{options[:simpleform]} --skip_javascript=#{options[:skip_javascript]}")
147
+ generate("kowl:mailer --noauth=#{options[:noauth]} --mailer=#{options[:mailer]}") unless options[:skip_mailer]
148
+ generate("kowl:sidekiq --database=#{options[:database]} --noauth=#{options[:noauth]}") unless options[:skip_sidekiq]
149
+ generate('kowl:misc') # Generator misc application directores such as serializers, services, workers, etc.
150
+ generate("kowl:decorators --noauth=#{options[:noauth]}")
151
+ generate("kowl:text_files --framework=#{options[:framework]} --noauth=#{options[:noauth]}")
152
+ generate("kowl:pages --framework=#{options[:framework]} --noauth=#{options[:noauth]} --template_engine=#{options[:template_engine]}") # Generate welcome pages and routes for the application
153
+ generate("kowl:routes --database=#{options[:database]} --noauth=#{options[:noauth]} --skip_mailer=#{options[:skip_mailer]} --skip_sidekiq=#{options[:skip_sidekiq]}")
154
+ generate('kowl:libs')
155
+
156
+ # Generate admin dashboard if user authentication is enabled
157
+ generate("kowl:docker --database=#{options[:database]} --docker_distro=#{options[:docker_distro]} --encrypt=#{options[:encrypt]} --skip_erd=#{options[:skip_erd]} --skip_javascript=#{options[:skip_javascript]} --skip_sidekiq=#{options[:skip_sidekiq]}") unless options[:skip_docker]
158
+
159
+ rake 'db:migrate' unless (options[:database] == 'postgresql' && options[:uuid]) || options[:noauth]
160
+ generate("kowl:admin --database=#{options[:database]} --skip_javascript=#{options[:skip_javascript]} --skip_turbolinks=#{options[:skip_turbolinks]} --uuid=#{options[:uuid]} ") unless options[:noauth]
161
+ invoke :add_uuids_to_migrations if options[:database] == 'postgresql' && options[:uuid]
162
+ invoke :remove_sqlite_yaml unless options[:database] == 'sqlite3'
163
+ invoke :setup_spring unless options[:skip_spring]
164
+
165
+ # Remove the kowl gem, it is initially required to run the rails generators
166
+ # => Removing the gem removes the generators from application
167
+ remove_gem('kowl')
168
+
169
+ # This should be ran last, thus there will only be 1 commit when application is started
170
+ # This is a method tather than a generate, because generations can't be called after the gem has been removed
171
+ invoke :initial_commit unless options[:skip_git]
172
+ end
173
+
174
+ # Setup a staging envirnment for application config and webpacker
175
+ def setup_staging
176
+ template 'config/environments/production.rb.tt', 'config/environments/staging.rb'
177
+ # Enable displaying error messages in staging
178
+ replace_string_in_file('config/environments/staging.rb',
179
+ '^[\s]*?(config.consider_all_requests_local)[\s]*= false[\s]?$',
180
+ ' config.consider_all_requests_local = true')
181
+ # create a webpacker staging environment
182
+ return if options[:skip_javascript]
183
+
184
+ dup_file('config/webpack/production.js', 'config/webpack/staging.js')
185
+ webpacker_str = <<~STAGING
186
+ staging:
187
+ <<: *default
188
+ # Production depends on precompilation of packs prior to booting for performance.
189
+ compile: false
190
+ # Extract and emit a css file
191
+ extract_css: true
192
+ # Cache manifest.json for performance
193
+ cache_manifest: true
194
+ # Compile staging packs to a separate directory
195
+ public_output_path: packs-staging
196
+ STAGING
197
+ append_to_file('config/webpacker.yml', "\n#{webpacker_str}")
198
+ end
199
+
200
+ # Create a git initial commit
201
+ def initial_commit
202
+ git :init
203
+ git add: '.'
204
+ git commit: "-aqm 'Initial Commit' --quiet"
205
+ end
206
+
207
+ # If UUIDs are to be used, add id: :uuid to all migrations
208
+ def add_uuids_to_migrations
209
+ return nil unless options[:database] == 'postgresql' && options[:uuid]
210
+
211
+ Dir.foreach('db/migrate/') do |migration|
212
+ next if %w[. ..].include?(migration) || migration.match(/_enable_pgcrypto_extension.rb$/)
213
+
214
+ inject_into_file("db/migrate/#{migration}", ', id: :uuid', after: /create_table \:[a-z\_]+/)
215
+ end
216
+ end
217
+
218
+ # While generating the application the config/database.yml is defaulted to using sqlite3.
219
+ # This is because we can't run migrations, and various tasks without a valid database.yml
220
+ # but this file should be remove and replace with the config/database[#{database_type}].yml file once the application is ready
221
+ def remove_sqlite_yaml
222
+ return nil if options[:database] == 'sqlite3'
223
+
224
+ db_file = "config/database[#{options[:database]}].yml"
225
+ remove_file('config/database.yml')
226
+ move_file(db_file, 'config/database.yml')
227
+ end
228
+
229
+ # Setup spring for the application unless specified otherwise
230
+ def setup_spring
231
+ say 'Springifying binstubs'
232
+ build :setup_spring unless options[:skip_spring]
233
+ end
234
+
235
+ # Rails6 has issues when genereting a new app using Oracle/sqlserver right away,
236
+ # this ensures webpack is installed if it previously failed because of the missing ruby-oci8/sqlserver gems
237
+ # In addition his also prevents a Psych error as the application is generated
238
+ def install_webpack_assets
239
+ rails_command('webpacker:install') unless options[:skip_javascript]
240
+ end
241
+
242
+ protected
243
+
244
+ def get_builder_class
245
+ AppBuilder
246
+ end
247
+ end
248
+ end
249
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails/generators'
4
+ require_relative 'base'
5
+
6
+ module Kowl
7
+ class PagesGenerator < Kowl::Generators::Base
8
+ hide!
9
+ source_root File.expand_path(File.join('..', 'templates', 'app', 'views'), File.dirname(__FILE__))
10
+ class_option :framework, type: :string, default: 'bootstrap', enum: %w[bootstrap semantic none]
11
+ class_option :noauth, type: :boolean, default: false
12
+ class_option :template_engine, type: :string, default: 'erb'
13
+
14
+ # Generate a basic welcome page for the application
15
+ def setup_welcome_page
16
+ generate('controller Pages welcome --skip')
17
+
18
+ # I don't want to skip or remove all tests created for pages, I just want to remove the generated controller test
19
+ remove_file('spec/requests/pages_request_spec.rb')
20
+ end
21
+
22
+ def make_controller_immuatable
23
+ inject_into_file 'app/controllers/pages_controller.rb', "# frozen_string_literal: true\n\n", before: "class PagesController < ApplicationController\n"
24
+ end
25
+
26
+ # Copy over a basic welcome page view dependant on the CSS framework and template engine specified for the application
27
+ def copy_welcome_pages
28
+ if %w[bootstrap semantic].include? options[:framework]
29
+ copy_file "pages/welcome/#{options[:framework]}.html.#{options[:template_engine]}", "app/views/pages/welcome.html.#{options[:template_engine]}", force: true
30
+ else
31
+ copy_file "pages/welcome/default.html.#{options[:template_engine]}", "app/views/pages/welcome.html.#{options[:template_engine]}", force: true
32
+ end
33
+ end
34
+
35
+ # Add a skip_before_action for the welcome page if authentication is being used with the application
36
+ def disable_auth
37
+ action_str = <<~STR
38
+ # Allow pages to be displayed without requiring authentication
39
+ skip_before_action :authenticate_user!
40
+
41
+ STR
42
+
43
+ inject_into_file 'app/controllers/pages_controller.rb', optimize_indentation(action_str, 2), after: "class PagesController < ApplicationController\n" unless options[:noauth]
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails/generators'
4
+ require_relative 'base'
5
+
6
+ module Kowl
7
+ class RoutesGenerator < Kowl::Generators::Base
8
+ hide!
9
+ source_root File.expand_path(File.join('..', 'templates', 'config'), File.dirname(__FILE__))
10
+ class_option :database, type: :string, default: 'sqlite3'
11
+ class_option :noauth, type: :boolean, default: false
12
+ class_option :skip_mailer, type: :boolean, default: false
13
+ class_option :skip_sidekiq, type: :boolean, default: false
14
+
15
+ # Generate the applications routes.rb file based on the applications options
16
+ def setup_routes
17
+ template('routes.rb.tt', 'config/routes.rb', force: true)
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails/generators'
4
+ require_relative 'base'
5
+
6
+ module Kowl
7
+ class SidekiqGenerator < Kowl::Generators::Base
8
+ hide!
9
+ source_root File.expand_path(File.join('..', 'templates'), File.dirname(__FILE__))
10
+ class_option :database, type: :string, default: 'sqlite3'
11
+ class_option :noauth, type: :boolean, default: false
12
+
13
+ # Copy over a basic sidekiq config and sidekiq initializer
14
+ def copy_config
15
+ template 'config/sidekiq.yml.tt', 'config/sidekiq.yml'
16
+ copy_file 'config/initializers/sidekiq.rb', 'config/initializers/sidekiq.rb'
17
+ end
18
+
19
+ # Setup pghero scheduled job, if application will be running with postgresql
20
+ def pghero_worker
21
+ copy_file('app/workers/scheduler/pghero_scheduler.rb', 'app/workers/scheduler/pghero_scheduler.rb') if options[:database] == 'postgresql'
22
+ end
23
+
24
+ # Setup the application to use redis as a cache_store
25
+ def set_redis_as_cache_storage
26
+ # https://blog.appsignal.com/2018/04/17/rails-built-in-cache-stores.html
27
+ # https://www.engineyard.com/blog/rails-5-2-redis-cache-store
28
+ # config.cache_storage = :redis_cache_store, { driver: :hiredis } # , url: "redis://redis:6379/0" }
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails/generators'
4
+ require_relative 'base'
5
+
6
+ # This generator is used to create a staging environment
7
+ # => It generates a staging.rb file in the config/environments/ (uses the production environment as a base)
8
+ # => It adds a staging database to the bottom of your config/database.yml file (inherits from &default)
9
+ # https://api.rubyonrails.org/v5.2/classes/Rails/Generators/Base.html#method-c-base_root
10
+ module Kowl
11
+ class StagingGenerator < Kowl::Generators::Base
12
+ hide!
13
+ end
14
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails/generators'
4
+ require_relative 'base'
5
+
6
+ module Kowl
7
+ class TestGenerator < Kowl::Generators::Base
8
+ hide!
9
+ source_root File.expand_path(File.join('..', 'templates', 'tests'), File.dirname(__FILE__))
10
+ class_option :noauth, type: :boolean, default: false
11
+ class_option :test_engine, type: :string, default: 'rspec'
12
+
13
+ # Remove default generate4d test and spec files
14
+ def remove_old_tests
15
+ remove_dir('test')
16
+ remove_dir('spec')
17
+ end
18
+
19
+ # If using minitest copy over a few basic tests and support files
20
+ def copy_minitest_files
21
+ directory('minitest', 'test') if options[:test_engine] == 'minitest'
22
+ end
23
+
24
+ # If using rspec copy over a few basic tests and support files
25
+ def copy_rspec_files
26
+ directory('rspec', 'spec') if options[:test_engine] == 'rspec'
27
+ end
28
+
29
+ # Copy over basic factory bot files
30
+ def copy_factories
31
+ directory 'factories', "#{(options[:test_engine] == 'rspec' ? 'spec' : 'test')}/factories", force: true
32
+ end
33
+
34
+ # If noauth is specified, remove the policies tests
35
+ def remove_if_no_auth_required
36
+ return unless options[:noauth]
37
+
38
+ remove_dir('spec/policies') if options[:test_engine] == 'rspec'
39
+ remove_dir('test/policies') if options[:test_engine] == 'minitest'
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails/generators'
4
+ require_relative 'base'
5
+
6
+ # Used to generate various markdown textfiles such as README and changelog
7
+ module Kowl
8
+ class TextFilesGenerator < Kowl::Generators::Base
9
+ hide!
10
+ source_root File.expand_path(File.join('..', 'templates', 'text_files'), File.dirname(__FILE__))
11
+ class_option :framework, type: :string, default: 'bootstrap'
12
+ class_option :noauth, type: :boolean, default: false
13
+
14
+ # Generate a changelog file for project developers
15
+ def changelog
16
+ # Add a changelog file to the project
17
+ template 'CHANGELOG.md.tt', 'CHANGELOG.md'
18
+ end
19
+
20
+ # Generarte numerous project markdown files
21
+ def copy_markdown_files
22
+ %w[AUTHORS.md CODE_OF_CONDUCT.md TODO.md].map { |f| copy_file(f, f) }
23
+ end
24
+
25
+ # Generate a project version file
26
+ def version
27
+ copy_file('VERSION', 'VERSION')
28
+ end
29
+
30
+ # Generate a security.txt file for application security contact information
31
+ def copy_securitytxt
32
+ copy_file('security.txt', 'public/.well-known/security.txt')
33
+ end
34
+
35
+ # Generate human.txt and robots.txt files for human readable project information
36
+ def public_txt_files
37
+ template 'humans.txt.tt', 'public/humans.txt'
38
+ template 'robots.txt.tt', 'public/robots.txt', force: true
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,143 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails/generators'
4
+ require_relative 'base'
5
+
6
+ module Kowl
7
+ class UsersAndAuthGenerator < Kowl::Generators::Base
8
+ hide!
9
+ source_root File.expand_path(File.join('..', 'templates'), File.dirname(__FILE__))
10
+ class_option :database, type: :string, aliases: '-d', default: 'sqlite3'
11
+ class_option :encrypt, type: :boolean, default: false
12
+ class_option :framework, type: :string, default: 'bootstrap'
13
+ class_option :skip_javascript, type: :boolean, default: false
14
+ class_option :skip_mailer, type: :boolean, default: false
15
+ class_option :skip_pagination, type: :boolean, default: false
16
+ class_option :skip_sidekiq, type: :boolean, default: false
17
+ class_option :template_engine, type: :string, default: 'erb'
18
+
19
+ # Run devise generators unless you don't want authentication allowed in the application
20
+ def generate_devise
21
+ # generate devise config
22
+ generate('devise:install')
23
+
24
+ # Generate devise users models
25
+ generate('devise User role:integer')
26
+
27
+ # Generate additional Devise security practices
28
+ generate('devise_security:install')
29
+ # Copy initializer for ensure a more secure devise application setup
30
+ copy_file('config/initializers/devise-security.rb', 'config/initializers/devise-security.rb', force: true) unless options[:noauth]
31
+
32
+ # Generate devise authentication log
33
+ generate('authtrail:install')
34
+ end
35
+
36
+ # Generate Pundit policies for basic authentication policies
37
+ def generate_and_copy_policies
38
+ # Begin setting up pundit
39
+ generate('pundit:install')
40
+ # these are generated, so they'll also create tests policies
41
+ generate('pundit:policy user')
42
+ generate('pundit:policy login_activity')
43
+
44
+ # Remove policies and replace with a base policy build
45
+ remove_dir('app/policies')
46
+ directory('app/policies', 'app/policies')
47
+ end
48
+
49
+ # Override user model with devise specific settings
50
+ def overrider_devise_config
51
+ template 'app/models/user.rb.tt', 'app/models/user.rb', force: true
52
+ end
53
+
54
+ # Update the devise migration to enable trackable and lockable attributes
55
+ def adjust_devise_migration
56
+ # Fetch the devise migration file
57
+ Dir.glob('db/migrate/**_devise_create_users.rb').select { |e| update_devise_migration(e) }
58
+ end
59
+
60
+ # This is because we encrypt certain values being logged into the LoginActivity table
61
+ # No not all data is plain text readable in the database
62
+ def replace_logins_activity_migration
63
+ Dir.glob('db/migrate/**_create_login_activities.rb').select { |e| update_login_activities_migration(e) }
64
+ end
65
+
66
+ # Change devise lock_strategy
67
+ def adjust_lock_stragety
68
+ devise_initialzier = 'config/initializers/devise.rb'
69
+ content = File.read(devise_initialzier).gsub(/\s?\#\s(config.lock_strategy = :failed_attempts)\n?/i, optimize_indentation('config.lock_strategy = :failed_attempts', 2))
70
+ File.open(devise_initialzier, 'wb') { |file| file.write(content) }
71
+ end
72
+
73
+ # Update devise/User notificationss
74
+ def adjust_devise_notifications
75
+ inject_into_file('config/initializers/devise.rb', optimize_indentation("config.send_email_changed_notification = true\n", 2), after: " # config.send_email_changed_notification = false\n")
76
+ inject_into_file('config/initializers/devise.rb', optimize_indentation("config.send_password_change_notification = true\n", 2), after: " # config.send_password_change_notification = false\n")
77
+ end
78
+
79
+ # Update devise initializer to be paranoid, to prevent credential stuffing with password resets
80
+ def set_devise_as_paranoid
81
+ # This displays the visitor with a confirmation even if the user does or doesn't exist
82
+ gsub_file('config/initializers/devise.rb', '# config.paranoid = true', 'config.paranoid = true')
83
+ end
84
+
85
+ # Generate a model for monitoring user login activity
86
+ def copy_login_activity_model
87
+ template 'app/models/login_activity.rb.tt', 'app/models/login_activity.rb', force: true
88
+ end
89
+
90
+ # Generate and copy a Users controller
91
+ def generate_users_controller
92
+ generate('controller Users') # copied mainly for testing purposes
93
+ copy_file 'app/controllers/users_controller.rb', 'app/controllers/users_controller.rb', force: true
94
+ end
95
+
96
+ # Generate administrate viewss
97
+ def generate_dashboard_views_and_assets
98
+ # The main reason these are generated, before copying over is some tests may rely on theses generators
99
+ generate('administrate:views:index User --quiet')
100
+ generate('administrate:views:edit User --quiet')
101
+ generate('administrate:assets:stylesheets --quiet')
102
+ generate('administrate:views:navigation --quiet')
103
+ end
104
+
105
+ # Copy over admin views and layouts
106
+ def setup_user_dashboard_views
107
+ remove_dir('app/views/admin')
108
+ directory('app/views/admin/views', 'app/views/admin')
109
+ template('app/views/admin/templates/navigation.erb.tt', 'app/views/admin/application/_navigation.html.erb')
110
+ end
111
+
112
+ # Copy over administrate SCSS stylesheet files
113
+ def setup_dashboard_stylesheets
114
+ copy_file('app/assets/stylesheets/administrate/application.scss', 'app/assets/stylesheets/administrate/application.scss', force: true)
115
+ end
116
+
117
+ # Add flattpickr to administrate for datetime picker fields
118
+ def setup_dashbord_javascript
119
+ return nil if options[:skip_javascript]
120
+
121
+ # flatpicker is required for date/time selection components
122
+ add_package('flatpickr')
123
+ end
124
+
125
+ private
126
+
127
+ def update_devise_migration(migration_file)
128
+ return false unless file_exists?(migration_file)
129
+
130
+ # override migration file to enable :trackable && :lockable
131
+ # copy_file 'db/migrations/devise.rb', migration_file, force: true
132
+ template 'db/migrations/devise.rb.tt', migration_file, force: true
133
+ end
134
+
135
+ def update_login_activities_migration(migration_file)
136
+ return false unless file_exists?(migration_file)
137
+
138
+ # Override the default migration file to enable :trackable && :lockable
139
+ # copy_file 'db/migrations/login_activities.rb', migration_file, force: true
140
+ template 'db/migrations/login_activities.rb.tt', migration_file, force: true
141
+ end
142
+ end
143
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails/generators'
4
+ require_relative 'base'
5
+
6
+ # https://github.com/rails/rails/blob/master/guides/source/active_record_postgresql.md
7
+ # This generator sets postgres to use UUIDs at the primary keys for your objects
8
+ module Kowl
9
+ class UuidGenerator < Kowl::Generators::Base
10
+ hide!
11
+ source_root File.expand_path(File.join('..', 'templates', 'db'), File.dirname(__FILE__))
12
+
13
+ # Generate migration to add pgcrypto_extension to the database
14
+ def generate_migration
15
+ generate('migration enable_pgcrypto_extension')
16
+ end
17
+
18
+ # Update pgcrypto migration file to include enable tjhe pgcrypt extension for postgres
19
+ def add_to_migration
20
+ Dir.glob('db/migrate/**_enable_pgcrypto_extension.rb').select { |e| update_uuid_migration(e) }
21
+ end
22
+
23
+ private
24
+
25
+ # Update the pgcrypto migration file
26
+ # @param migration_file [String] - The specified migration file for enabling the extension ie: 1234567890_enable_pgcrypto_extension.rb
27
+ def update_uuid_migration(migration_file)
28
+ return false unless file_exists?(migration_file)
29
+
30
+ uuid_migration_str = <<~UUID_STR
31
+ if ActiveRecord::Base.connection.adapter_name.downcase.to_sym == :postgresql
32
+ enable_extension 'pgcrypto' unless extension_enabled?('pgcrypto')
33
+ end
34
+ UUID_STR
35
+
36
+ insert_into_file migration_file, optimize_indentation(uuid_migration_str, 4), after: /\s+\S+\schange\s?\n/
37
+ end
38
+ end
39
+ end