khusnetdinov/kazan

View on GitHub
lib/kazan/app_builder.rb

Summary

Maintainability
D
1 day
Test Coverage
# frozen_string_literal: true

module Kazan
  # This class build new project
  class AppBuilder < Rails::AppBuilder
    include Kazan::Actions

    def readme
      template 'README.md.erb', 'README.md'
    end

    def gitignore
      copy_file 'project_gitignore', '.gitignore', force: true
    end

    def gemfile
      template 'Gemfile.erb', 'Gemfile'
    end

    def gemfile_api
      template 'Gemfile.api.erb', 'Gemfile', force: true
    end

    def ruby_version
      create_file '.ruby-version', "#{Kazan::RUBY_PROJECT_VERSION}\n"
    end

    def simple_form_config
      bundle_command 'exec rails generate simple_form:install'
    end

    def init_meta_tags
      bundle_command 'exec rails generate meta_tags:install'
    end

    def rack_mini_profiler_config
      copy_file 'rack_mini_profiler.rb', 'config/initializers/rack_mini_profiler.rb'
    end

    def puma_config
      copy_file 'puma.rb', 'config/puma.rb', force: true
    end

    def postgres_config
      template 'database.yml.erb', 'config/database.yml', force: true
      template 'database.yml.erb', 'config/database.yml.example'
    end

    def database_tables
      bundle_command 'exec rake db:create db:migrate'
    end

    def shared_views_directory
      empty_directory 'app/views/layouts/shared'
    end

    def shared_flash
      copy_file '_flashes.html.erb', 'app/views/layouts/shared/_flashes.html.erb'
      copy_file 'flashes_helper.rb', 'app/helpers/flashes_helper.rb'
    end

    def shared_javascript
      copy_file '_javascript.html.erb', 'app/views/layouts/shared/_javascript.html.erb'
    end

    def shared_styles
      copy_file '_styles.html.erb', 'app/views/layouts/shared/_styles.html.erb'
    end

    def shared_layout
      copy_file '_application.html.erb', 'app/views/layouts/application.html.erb', force: true
    end

    def assets_config
      copy_file 'errors.rb', 'config/initializers/errors.rb'
      copy_file 'json_encoding.rb', 'config/initializers/json_encoding.rb'
    end

    def dotenvs
      directory 'envs', '.'
    end

    def settings
      template 'settings.yml.erb', 'config/settings.yml'
    end

    def exception_on_delivery_errors
      replace_in_file 'config/environments/development.rb',
                      'raise_delivery_errors = false',
                      'raise_delivery_errors = true'
    end

    def exception_on_unpermitted_parameters
      config = <<-RUBY
    config.action_controller.action_on_unpermitted_parameters = :raise

      RUBY

      inject_into_class 'config/application.rb', 'Application', config
    end

    def exception_on_missing_translations
      exception_on_missing_translations_in 'development'
      exception_on_missing_translations_in 'test'
    end

    def letter_opener_config
      letter_opener_settings = <<-RUBY
  # Letter opener settings
  config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
  config.action_mailer.delivery_method = :letter_opener
      RUBY

      configure_environment 'development', letter_opener_settings
    end

    def bullet_config
      template 'bullet.rb', 'config/initializers/bullet.rb'
    end

    def quiet_assets_config
      config = <<-RUBY
    config.assets.quiet = true

      RUBY

      inject_into_class 'config/application.rb', 'Application', config
    end

    def foreman_config
      template 'Procfile.erb', 'Procfile'
    end

    def rails_generators_config
      config = <<-RUBY
    config.autoload_paths += %W[
      \#{Rails.root}/app/utilities/*
    ]

    config.generators do |generate|
      generate.helper false
      generate.javascript_engine false
      generate.request_specs false
      generate.routing_specs false
      generate.stylesheets false
      generate.test_framework :rspec
      generate.view_specs false
    end

      RUBY

      inject_into_class 'config/application.rb', 'Application', config
    end

    def remove_turbolinks
      replace_in_file 'app/assets/javascripts/application.js',
                      '//= require turbolinks',
                      ''
    end

    def stylesheets_gems
      gems = <<-RUBY
      RUBY

      inject_into_file 'Gemfile',
                       gems,
                       after: "gem 'sass-rails', '~> 5.0'\n"
      Bundler.with_clean_env { run 'bundle install' }
    end

    def stylesheets_manifest
      remove_file 'app/assets/stylesheets/application.css'
      copy_file 'application.scss',
                'app/assets/stylesheets/application.scss',
                force: true
    end

    def static_pages
      meta_tags = <<-META
    <meta charset='utf-8' />
    <meta name='ROBOTS' content='NOODP' />
    <meta name='viewport' content='initial-scale=1' />
      META

      %w[500 404 422].each do |page|
        inject_into_file "public/#{page}.html", meta_tags, after: "<head>\n"
        replace_in_file "public/#{page}.html", /<!--.+-->\n/, ''
      end
    end

    def setup_locales
      copy_file 'i18n-tasks.yml', 'config/i18n-tasks.yml'
      copy_file 'i18n_spec.rb', 'spec/i18n_spec.rb'
      replace_in_file 'config/locales/en.yml', '  hello: "Hello world"', ''
    end

    def bundler_audit_config
      copy_file 'bundler_audit.rake', 'lib/tasks/bundler_audit.rake'
      append_file 'Rakefile', %(\ntask default: 'bundler:audit'\n)
    end

    def exception_on_missing_assets_in_test
      configure_environment 'test', 'config.assets.raise_runtime_errors = true'
    end

    def spec_translations_config
      copy_file 'i18n.rb', 'spec/support/i18n.rb'
    end

    def spec_action_mailer_config
      copy_file 'action_mailer.rb', 'spec/support/action_mailer.rb'
    end

    def spec_database_cleaner_config
      copy_file 'database_cleaner.rb', 'spec/support/database_cleaner.rb'
    end

    def spec_shoulda_matchers_config
      copy_file 'shoulda_matchers.rb', 'spec/support/shoulda_matchers.rb'
    end

    def spec_factory_bot_config
      copy_file 'factory_bot.rb', 'spec/support/factory_bot.rb'
    end

    def spec_quality_tests
      create_file '.quality.yml'

      [
        'quality.yml',
        'brakeman.yml',
        'eslintrc.yml',
        'haml-lint.yml',
        'reek',
        'rubocop.yml',
        'scss-lint.yml'
      ].each do |file|
        copy_file "quality/configs/#{file}", ".quality/.#{file}"
      end

      [
        'brakeman_spec.rb',
        'bundler_audit_spec.rb',
        'eslint_spec.rb',
        'reek_spec.rb',
        'rubocop_spec.rb',
        'scss_lint_spec.rb'
      ].each do |file|
        copy_file "quality/specs/#{file}", "spec/qualities/#{file}"
      end

      [
        'brakeman',
        'bundler-audit',
        'haml-lint',
        'reek',
        'rubocop',
        'scss-lint'
      ].each do |file|
        copy_file "bin/#{file}", "bin/#{file}", preserve: true
        run "chmod +x bin/#{file}"
      end

      run 'npm install eslint --save-dev'
      run 'bundle binstubs bundler --force'
    end

    def rspec_config
      generate 'rspec:install'
    end

    def rspec_replace_config
      copy_file 'rails_helper.rb', 'spec/rails_helper.rb', force: true
      copy_file 'spec_helper.rb', 'spec/spec_helper.rb', force: true
    end

    def smtp_config
      copy_file 'smtp.rb', 'config/smtp.rb'

      prepend_file 'config/environments/production.rb',
                   %{require Rails.root.join("config/smtp")\n}

      config = <<-RUBY
  config.action_mailer.delivery_method = :smtp
  config.action_mailer.smtp_settings = SMTP_SETTINGS

      RUBY

      inject_into_file 'config/environments/production.rb',
                       config,
                       after: 'config.action_mailer.raise_delivery_errors = false'
    end

    def rack_timeout_config
      rack_timeout_config = <<-RUBY
  Rack::Timeout.timeout = (ENV['RACK_TIMEOUT'] || 10).to_i

      RUBY

      append_file 'config/environments/production.rb', rack_timeout_config
    end

    def rack_canonical_host_config
      config = <<-RUBY
  config.middleware.use Rack::CanonicalHost, ENV.fetch('APPLICATION_HOST')
      RUBY

      inject_into_file 'config/environments/production.rb',
                       config,
                       after: 'Rails.application.configure do'
    end

    def rack_deflater_config
      configure_environment 'production', 'config.middleware.use Rack::Deflater'
    end

    def rollbar_config
      copy_file 'rollbar.rb', 'config/initializers/rollbar.rb'
    end

    def spring
      bundle_command 'exec spring binstub --all'
    end

    def irresponsible_modules_reek
      config = <<-RUBY
  # The ApplicationController - filters added to this controller apply to all
  # controllers in the application. Likewise, all the methods added will be available
  # for all controllers.

      RUBY
      prepend_file 'app/controllers/application_controller.rb', config
      config = <<-RUBY
  # The ApplicationHelper - methods added to this helper will be available to all
  # templates in the application.

      RUBY
      prepend_file 'app/helpers/application_helper.rb', config
      config = <<-RUBY
  # The FlashHelper - module to user flash.

      RUBY
      prepend_file 'app/helpers/flashes_helper.rb', config
      config = <<-RUBY
  # The ApplicationJob - is a framework for declaring jobs and making them run
  # on a variety of queuing backends. These jobs can be everything from regularly
  # scheduled clean-ups, to billing charges, to mailings. Anything that can be
  # chopped up into small units of work and run in parallel, really.

      RUBY
      prepend_file 'app/jobs/application_job.rb', config
      config = <<-RUBY
  # The ApplicationMailer allows you to send emails from your application
  # using mailer classes and views. Mailers work very similarly to controllers.
  # They inherit from ActionMailer::Base and live in app/mailers, and they
  # have associated views that appear in app/views.

      RUBY
      prepend_file 'app/mailers/application_mailer.rb', config
      config = <<-RUBY
  # The ApplicationRecord all the methods added will be available for all models.

      RUBY
      prepend_file 'app/models/application_record.rb', config
    end

    def add_comment_rubocop
      [
        'Rakefile',
        'config.ru',
        'app/jobs/application_job.rb',
        'app/mailers/application_mailer.rb',
        'app/models/application_record.rb',
        'app/helpers/application_helper.rb',
        'app/controllers/application_controller.rb'
      ].each do |file|
        prepend_file file, "# frozen_string_literal: true\n\n"
      end
    end

    def empty_directories
      [
        'app/assets/fonts',
        'app/controllers/api',
        'app/controllers/web',
        'app/decorators',
        'app/interactors/integrations',
        'app/interactors/mailers',
        'app/services/integrations',
        'app/services/mailers',
        'app/policies',
        'app/validations',
        'app/views/shared',
        'spec/controllers',
        'spec/decorators/integrations',
        'spec/decorators/mailers',
        'spec/interactors/integrations',
        'spec/interactors/mailers',
        'spec/factories',
        'spec/helpers',
        'spec/models',
        'spec/mailers',
        'spec/requests'
      ].each do |dir|
        empty_directory_with_keep_file dir
      end
    end

    def seo_controller
      [
        'app/views/web/seo',
        'app/utilities',
        'spec/controllers/web',
        'spec/routing/web',
        'spec/utilities'
      ].each do |dir|
        empty_directory_with_keep_file dir
      end

      copy_file 'features/seo/seo_controller.rb', 'app/controllers/web/seo_controller.rb'
      copy_file 'features/seo/seo_controller_spec.rb', 'spec/controllers/web/seo_controller_spec.rb'
      copy_file 'features/seo/seo_routing_spec.rb', 'spec/routing/web/seo_routing_spec.rb'
      copy_file 'features/seo/settings_utility_spec.rb', 'spec/utilities/settings_utility_spec.rb'
      copy_file 'features/seo/robots.text.erb', 'app/views/web/seo/robots.text.erb'
      copy_file 'features/seo/sitemap.xml.builder', 'app/views/web/seo/sitemap.xml.builder'
      copy_file 'features/seo/settings_utility.rb', 'app/utilities/settings_utility.rb'
      copy_file 'routes.rb', 'config/routes.rb', force: true

      remove_file 'app/controllers/web/.keep'
      remove_file 'app/utilities/.keep'
      remove_file 'app/views/web/seo/.keep'
      remove_file 'app/spec/controllers/web/.keep'
      remove_file 'app/spec/controllers/web/seo/.keep'
      remove_file 'app/spec/routing/web/seo/.keep'
      remove_file 'app/spec/routing/utilities/.keep'
    end

    def mailers_templates
      empty_directory 'app/views/mailers/layouts'
      %w[mailer.html.erb mailer.text.erb].each do |file|
        copy_file "app/views/layouts/#{file}", "app/views/mailers/layouts/#{file}"
        remove_file "app/views/layouts/#{file}"
      end
      config = <<-RUBY
    config.paths['app/views'].unshift(Rails.root.join('app/views/mailers'))
      RUBY

      inject_into_file 'config/application.rb',
                       config,
                       after: "config.assets.quiet = true\n"
    end

    def init_commit
      run 'git init'
      run 'git add .'
      run 'git commit -m "Init commit"'
    end

    private

    def exception_on_missing_translations_in(environment)
      config = 'config.action_view.raise_on_missing_translations = true'

      uncomment_lines("config/environments/#{environment}.rb", config)
    end
  end
end