kowl 0.0.1

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