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.
- checksums.yaml +7 -0
- data/LICENSE +7 -0
- data/README.md +383 -0
- data/bin/console +14 -0
- data/bin/kowl +106 -0
- data/bin/setup +13 -0
- data/lib/kowl/actions.rb +240 -0
- data/lib/kowl/docker.rb +447 -0
- data/lib/kowl/generators/README.md +5 -0
- data/lib/kowl/generators/action_generator.rb +113 -0
- data/lib/kowl/generators/admin_generator.rb +114 -0
- data/lib/kowl/generators/assets_generator.rb +188 -0
- data/lib/kowl/generators/base.rb +40 -0
- data/lib/kowl/generators/circleci_generator.rb +11 -0
- data/lib/kowl/generators/config_generator.rb +180 -0
- data/lib/kowl/generators/controller_generator.rb +64 -0
- data/lib/kowl/generators/database_generator.rb +42 -0
- data/lib/kowl/generators/decorators_generator.rb +16 -0
- data/lib/kowl/generators/docker_generator.rb +40 -0
- data/lib/kowl/generators/dotfiles_generator.rb +73 -0
- data/lib/kowl/generators/libs_generator.rb +19 -0
- data/lib/kowl/generators/mailer_generator.rb +58 -0
- data/lib/kowl/generators/misc_generator.rb +20 -0
- data/lib/kowl/generators/overrides/app_base.rb +15 -0
- data/lib/kowl/generators/overrides/app_builder.rb +58 -0
- data/lib/kowl/generators/overrides/app_generator.rb +249 -0
- data/lib/kowl/generators/pages_generator.rb +46 -0
- data/lib/kowl/generators/routes_generator.rb +20 -0
- data/lib/kowl/generators/sidekiq_generator.rb +31 -0
- data/lib/kowl/generators/staging_generator.rb +14 -0
- data/lib/kowl/generators/test_generator.rb +42 -0
- data/lib/kowl/generators/text_files_generator.rb +41 -0
- data/lib/kowl/generators/users_and_auth_generator.rb +143 -0
- data/lib/kowl/generators/uuid_generator.rb +39 -0
- data/lib/kowl/generators/views_and_helpers_generator.rb +104 -0
- data/lib/kowl/geodb.rb +96 -0
- data/lib/kowl/helpers.rb +139 -0
- data/lib/kowl/templates/Gemfile.erb.tt +253 -0
- data/lib/kowl/templates/README.md.erb +33 -0
- data/lib/kowl/templates/app/assets/javascripts/semantic.js.tt +26 -0
- data/lib/kowl/templates/app/assets/stylesheets/administrate/application.scss +44 -0
- data/lib/kowl/templates/app/assets/stylesheets/bootstrap/_custom_styling.scss +38 -0
- data/lib/kowl/templates/app/assets/stylesheets/bootstrap/application-mailer.scss +1 -0
- data/lib/kowl/templates/app/assets/stylesheets/bootstrap/application.scss +14 -0
- data/lib/kowl/templates/app/assets/stylesheets/bootstrap/components/_alerts.scss +7 -0
- data/lib/kowl/templates/app/assets/stylesheets/bootstrap/components/_errors.scss +28 -0
- data/lib/kowl/templates/app/assets/stylesheets/bootstrap/components/_navbar.scss +17 -0
- data/lib/kowl/templates/app/assets/stylesheets/bootstrap/variables.scss +6 -0
- data/lib/kowl/templates/app/assets/stylesheets/semantic/_custom_styling.scss +20 -0
- data/lib/kowl/templates/app/assets/stylesheets/semantic/application.scss +24 -0
- data/lib/kowl/templates/app/controllers/admin/application_controller.rb +29 -0
- data/lib/kowl/templates/app/controllers/admin/login_activities_controller.rb +29 -0
- data/lib/kowl/templates/app/controllers/admin/users_controller.rb +37 -0
- data/lib/kowl/templates/app/controllers/concerns/auth/authentication.rb +18 -0
- data/lib/kowl/templates/app/controllers/concerns/auth/authorization.rb +20 -0
- data/lib/kowl/templates/app/controllers/concerns/auth/error_handlers.rb +27 -0
- data/lib/kowl/templates/app/controllers/concerns/noauth/error_handlers.rb +25 -0
- data/lib/kowl/templates/app/controllers/users_controller.rb +17 -0
- data/lib/kowl/templates/app/dashboards/login_activity_dashboard.rb.tt +59 -0
- data/lib/kowl/templates/app/dashboards/rich_text_body_dashboard.rb.tt +17 -0
- data/lib/kowl/templates/app/dashboards/user_dashboard.rb.tt +60 -0
- data/lib/kowl/templates/app/fields/gravatar_field.rb +10 -0
- data/lib/kowl/templates/app/fields/rich_text_area_field.rb +8 -0
- data/lib/kowl/templates/app/inputs/rich_text_area_input.rb +11 -0
- data/lib/kowl/templates/app/javascript/administrate/components/date_time_picker.js.tt +32 -0
- data/lib/kowl/templates/app/javascript/administrate/components/table.js.tt +49 -0
- data/lib/kowl/templates/app/javascript/administrate/index.js +3 -0
- data/lib/kowl/templates/app/javascript/packs/administrate.js.tt +21 -0
- data/lib/kowl/templates/app/javascript/packs/semantic.js +11 -0
- data/lib/kowl/templates/app/mailers/application_mailer.rb +7 -0
- data/lib/kowl/templates/app/mailers/devise_mailer.rb +5 -0
- data/lib/kowl/templates/app/models/login_activity.rb.tt +29 -0
- data/lib/kowl/templates/app/models/user.rb.tt +72 -0
- data/lib/kowl/templates/app/policies/application_policy.rb +38 -0
- data/lib/kowl/templates/app/policies/login_activity_policy.rb +35 -0
- data/lib/kowl/templates/app/policies/user_policy.rb +43 -0
- data/lib/kowl/templates/app/views/admin/templates/navigation.erb.tt +23 -0
- data/lib/kowl/templates/app/views/admin/views/application/_javascript.html.erb +21 -0
- data/lib/kowl/templates/app/views/admin/views/users/_collection.html.erb +102 -0
- data/lib/kowl/templates/app/views/admin/views/users/_form.html.erb +46 -0
- data/lib/kowl/templates/app/views/admin/views/users/edit.html.erb +36 -0
- data/lib/kowl/templates/app/views/admin/views/users/index.html.erb +66 -0
- data/lib/kowl/templates/app/views/fields/gravatar_field/_form.html.erb +6 -0
- data/lib/kowl/templates/app/views/fields/gravatar_field/_index.html.erb +1 -0
- data/lib/kowl/templates/app/views/fields/gravatar_field/_show.html.erb +1 -0
- data/lib/kowl/templates/app/views/fields/rich_text_area_field/_form.html.erb +6 -0
- data/lib/kowl/templates/app/views/fields/rich_text_area_field/_index.html.erb +1 -0
- data/lib/kowl/templates/app/views/fields/rich_text_area_field/_show.html.erb +1 -0
- data/lib/kowl/templates/app/views/layouts/admin.html.erb.tt +47 -0
- data/lib/kowl/templates/app/views/layouts/devise_mailer.html.erb +14 -0
- data/lib/kowl/templates/app/views/pages/welcome/bootstrap.html.erb +18 -0
- data/lib/kowl/templates/app/views/pages/welcome/bootstrap.html.haml +17 -0
- data/lib/kowl/templates/app/views/pages/welcome/bootstrap.html.slim +17 -0
- data/lib/kowl/templates/app/views/pages/welcome/default.html.erb +0 -0
- data/lib/kowl/templates/app/views/pages/welcome/default.html.haml +0 -0
- data/lib/kowl/templates/app/views/pages/welcome/default.html.slim +0 -0
- data/lib/kowl/templates/app/views/pages/welcome/semantic.html.erb +20 -0
- data/lib/kowl/templates/app/views/pages/welcome/semantic.html.haml +17 -0
- data/lib/kowl/templates/app/views/pages/welcome/semantic.html.slim +17 -0
- data/lib/kowl/templates/app/views/shared/footer/bootstrap.html.erb.tt +5 -0
- data/lib/kowl/templates/app/views/shared/footer/bootstrap.html.haml.tt +3 -0
- data/lib/kowl/templates/app/views/shared/footer/bootstrap.html.slim.tt +3 -0
- data/lib/kowl/templates/app/views/shared/footer/semantic.html.erb.tt +7 -0
- data/lib/kowl/templates/app/views/shared/footer/semantic.html.haml.tt +5 -0
- data/lib/kowl/templates/app/views/shared/footer/semantic.html.slim.tt +5 -0
- data/lib/kowl/templates/app/views/shared/navigation/bootstrap.html.erb.tt +51 -0
- data/lib/kowl/templates/app/views/shared/navigation/bootstrap.html.haml.tt +36 -0
- data/lib/kowl/templates/app/views/shared/navigation/bootstrap.html.slim.tt +36 -0
- data/lib/kowl/templates/app/views/shared/navigation/semantic.html.erb.tt +48 -0
- data/lib/kowl/templates/app/views/shared/navigation/semantic.html.haml.tt +36 -0
- data/lib/kowl/templates/app/views/shared/navigation/semantic.html.slim.tt +36 -0
- data/lib/kowl/templates/app/workers/scheduler/pghero_scheduler.rb +11 -0
- data/lib/kowl/templates/config/autoprefixer.yml +4 -0
- data/lib/kowl/templates/config/db/mysql.yml.tt +43 -0
- data/lib/kowl/templates/config/db/oracle.yml.tt +29 -0
- data/lib/kowl/templates/config/db/postgresql.yml.tt +37 -0
- data/lib/kowl/templates/config/db/sqlite3.yml.tt +20 -0
- data/lib/kowl/templates/config/db/sqlserver.yml.tt +28 -0
- data/lib/kowl/templates/config/initializers/administrate.rb.tt +9 -0
- data/lib/kowl/templates/config/initializers/bullet.rb +21 -0
- data/lib/kowl/templates/config/initializers/devise-security.rb +44 -0
- data/lib/kowl/templates/config/initializers/devise_argon2.rb +29 -0
- data/lib/kowl/templates/config/initializers/faker.rb +6 -0
- data/lib/kowl/templates/config/initializers/generators.rb.tt +31 -0
- data/lib/kowl/templates/config/initializers/geocoder.rb +10 -0
- data/lib/kowl/templates/config/initializers/letter_opener.rb +13 -0
- data/lib/kowl/templates/config/initializers/lockbox.rb +11 -0
- data/lib/kowl/templates/config/initializers/logging.rb +6 -0
- data/lib/kowl/templates/config/initializers/lograge.rb +7 -0
- data/lib/kowl/templates/config/initializers/logstop.rb +4 -0
- data/lib/kowl/templates/config/initializers/middleware.rb +9 -0
- data/lib/kowl/templates/config/initializers/oj.rb +7 -0
- data/lib/kowl/templates/config/initializers/pagy.rb.tt +16 -0
- data/lib/kowl/templates/config/initializers/postmark.rb +8 -0
- data/lib/kowl/templates/config/initializers/rack_attack.rb.tt +71 -0
- data/lib/kowl/templates/config/initializers/sass.rb +5 -0
- data/lib/kowl/templates/config/initializers/sidekiq.rb +11 -0
- data/lib/kowl/templates/config/initializers/simpleform/semantic.rb +225 -0
- data/lib/kowl/templates/config/initializers/slim.rb +6 -0
- data/lib/kowl/templates/config/initializers/sparkpost.rb +13 -0
- data/lib/kowl/templates/config/routes.rb.tt +28 -0
- data/lib/kowl/templates/config/sidekiq.yml.tt +17 -0
- data/lib/kowl/templates/db/migrations/create_action_text_tables.action_text.rb.tt +16 -0
- data/lib/kowl/templates/db/migrations/create_active_storage_tables.active_storage.rb.tt +29 -0
- data/lib/kowl/templates/db/migrations/devise.rb.tt +59 -0
- data/lib/kowl/templates/db/migrations/login_activities.rb.tt +41 -0
- data/lib/kowl/templates/db/seeds.rb.tt +14 -0
- data/lib/kowl/templates/docker/Dockerfile.alpine.tt +92 -0
- data/lib/kowl/templates/docker/Dockerfile.debian.tt +133 -0
- data/lib/kowl/templates/docker/docker-compose.yml.tt +55 -0
- data/lib/kowl/templates/docker/mysql/Dockerfile.tt +15 -0
- data/lib/kowl/templates/dotfiles/Aptfile.tt +34 -0
- data/lib/kowl/templates/dotfiles/Brewfile.tt +49 -0
- data/lib/kowl/templates/dotfiles/Procfile.tt +12 -0
- data/lib/kowl/templates/dotfiles/codeclimate.yml +76 -0
- data/lib/kowl/templates/dotfiles/coffeelint.json +10 -0
- data/lib/kowl/templates/dotfiles/coffeelintignore +15 -0
- data/lib/kowl/templates/dotfiles/dockerignore +23 -0
- data/lib/kowl/templates/dotfiles/editorconfig +13 -0
- data/lib/kowl/templates/dotfiles/env.tt +58 -0
- data/lib/kowl/templates/dotfiles/erb-lint.yml +10 -0
- data/lib/kowl/templates/dotfiles/erdconfig.tt +24 -0
- data/lib/kowl/templates/dotfiles/eslintignore +20 -0
- data/lib/kowl/templates/dotfiles/eslintrc.js +31 -0
- data/lib/kowl/templates/dotfiles/fasterer.yml +14 -0
- data/lib/kowl/templates/dotfiles/foreman +1 -0
- data/lib/kowl/templates/dotfiles/gitattributes +15 -0
- data/lib/kowl/templates/dotfiles/gitignore +69 -0
- data/lib/kowl/templates/dotfiles/haml-lint.yml +23 -0
- data/lib/kowl/templates/dotfiles/jsbeautifyrc +15 -0
- data/lib/kowl/templates/dotfiles/jshintrc +3 -0
- data/lib/kowl/templates/dotfiles/mailmap +3 -0
- data/lib/kowl/templates/dotfiles/nvmrc +1 -0
- data/lib/kowl/templates/dotfiles/prettierignore +21 -0
- data/lib/kowl/templates/dotfiles/prettierrc.js +62 -0
- data/lib/kowl/templates/dotfiles/pryrc +7 -0
- data/lib/kowl/templates/dotfiles/rspec +3 -0
- data/lib/kowl/templates/dotfiles/rubocop.yml.tt +78 -0
- data/lib/kowl/templates/dotfiles/scss-lint.yml +132 -0
- data/lib/kowl/templates/dotfiles/simplecov +19 -0
- data/lib/kowl/templates/dotfiles/slim-lint.yml +23 -0
- data/lib/kowl/templates/dotfiles/slugignore +10 -0
- data/lib/kowl/templates/dotfiles/yamllint +7 -0
- data/lib/kowl/templates/dotfiles/yarnclean +46 -0
- data/lib/kowl/templates/lib/tasks/stats.rake +42 -0
- data/lib/kowl/templates/tests/factories/README.md +0 -0
- data/lib/kowl/templates/tests/factories/login_activity.rb +11 -0
- data/lib/kowl/templates/tests/factories/user.rb +11 -0
- data/lib/kowl/templates/tests/minitest/README.md +3 -0
- data/lib/kowl/templates/tests/minitest/application_system_test_case.rb +7 -0
- data/lib/kowl/templates/tests/minitest/controllers/pages_controller_test.rb +10 -0
- data/lib/kowl/templates/tests/minitest/models/login_activity_test.rb +8 -0
- data/lib/kowl/templates/tests/minitest/models/user_test.rb +15 -0
- data/lib/kowl/templates/tests/minitest/policies/login_activity_policy_test.rb +7 -0
- data/lib/kowl/templates/tests/minitest/policies/user_policy_test.rb +7 -0
- data/lib/kowl/templates/tests/minitest/support/capybara.rb +38 -0
- data/lib/kowl/templates/tests/minitest/support/database_cleaner.rb +20 -0
- data/lib/kowl/templates/tests/minitest/support/database_cleaner_support.rb +15 -0
- data/lib/kowl/templates/tests/minitest/support/deferred_garbage_collection.rb +21 -0
- data/lib/kowl/templates/tests/minitest/support/devise.rb +16 -0
- data/lib/kowl/templates/tests/minitest/support/factories.rb +6 -0
- data/lib/kowl/templates/tests/minitest/support/formulaic.rb +8 -0
- data/lib/kowl/templates/tests/minitest/support/helpers/devise_helper.rb +57 -0
- data/lib/kowl/templates/tests/minitest/support/papertrail.rb +17 -0
- data/lib/kowl/templates/tests/minitest/support/pundit.rb +0 -0
- data/lib/kowl/templates/tests/minitest/support/shoulda.rb +11 -0
- data/lib/kowl/templates/tests/minitest/support/simplecov.rb +8 -0
- data/lib/kowl/templates/tests/minitest/test_helper.rb +17 -0
- data/lib/kowl/templates/tests/rspec/README.md +9 -0
- data/lib/kowl/templates/tests/rspec/controllers/admin/application_controller_spec.rb +12 -0
- data/lib/kowl/templates/tests/rspec/controllers/admin/users_controller_spec.rb +14 -0
- data/lib/kowl/templates/tests/rspec/controllers/pages_controller_spec.rb +10 -0
- data/lib/kowl/templates/tests/rspec/features/README.md +15 -0
- data/lib/kowl/templates/tests/rspec/features/visitor_sign_up_spec.rb +25 -0
- data/lib/kowl/templates/tests/rspec/helpers/application_helper_spec.rb +7 -0
- data/lib/kowl/templates/tests/rspec/helpers/pages_helper_spec.rb +15 -0
- data/lib/kowl/templates/tests/rspec/models/login_activity_spec.rb +11 -0
- data/lib/kowl/templates/tests/rspec/models/user_spec.rb +21 -0
- data/lib/kowl/templates/tests/rspec/policies/login_activity_policy_spec.rb +59 -0
- data/lib/kowl/templates/tests/rspec/policies/user_policy_spec.rb +56 -0
- data/lib/kowl/templates/tests/rspec/rails_helper.rb +72 -0
- data/lib/kowl/templates/tests/rspec/requests/pages_spec.rb +11 -0
- data/lib/kowl/templates/tests/rspec/spec_helper.rb +96 -0
- data/lib/kowl/templates/tests/rspec/support/bullet.rb +17 -0
- data/lib/kowl/templates/tests/rspec/support/capybara.rb +37 -0
- data/lib/kowl/templates/tests/rspec/support/controller_testing.rb +10 -0
- data/lib/kowl/templates/tests/rspec/support/database_cleaner.rb +55 -0
- data/lib/kowl/templates/tests/rspec/support/deferred_garbage_collection.rb +32 -0
- data/lib/kowl/templates/tests/rspec/support/devise.rb +21 -0
- data/lib/kowl/templates/tests/rspec/support/factories.rb +5 -0
- data/lib/kowl/templates/tests/rspec/support/formulaic.rb +8 -0
- data/lib/kowl/templates/tests/rspec/support/helpers/devise_helpers.rb +56 -0
- data/lib/kowl/templates/tests/rspec/support/papertrail.rb +5 -0
- data/lib/kowl/templates/tests/rspec/support/pi_ci.rb +6 -0
- data/lib/kowl/templates/tests/rspec/support/pundit.rb +6 -0
- data/lib/kowl/templates/tests/rspec/support/shoulda.rb +10 -0
- data/lib/kowl/templates/tests/rspec/support/sidekiq.rb +10 -0
- data/lib/kowl/templates/tests/rspec/support/simplecov.rb +7 -0
- data/lib/kowl/templates/tests/rspec/support/warden.rb +8 -0
- data/lib/kowl/templates/text_files/AUTHORS.md +4 -0
- data/lib/kowl/templates/text_files/CHANGELOG.md.tt +12 -0
- data/lib/kowl/templates/text_files/CODE_OF_CONDUCT.md +76 -0
- data/lib/kowl/templates/text_files/TODO.md +7 -0
- data/lib/kowl/templates/text_files/VERSION +1 -0
- data/lib/kowl/templates/text_files/humans.txt.tt +15 -0
- data/lib/kowl/templates/text_files/robots.txt.tt +6 -0
- data/lib/kowl/templates/text_files/security.txt +6 -0
- data/lib/kowl/version.rb +9 -0
- data/lib/kowl.rb +18 -0
- 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
|