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