# typed: false # frozen_string_literal: true require "forwardable" module Hephaestus class AppBuilder < ::Rails::AppBuilder include Hephaestus::Actions extend Forwardable def readme template("README.md.erb", "README.md") end def gitignore copy_file("hephaestus_gitignore", ".gitignore") end # it is, apparently, extraordinarly important to keep this as an erb def gemfile template("Gemfile.erb", "Gemfile") end def raise_on_delivery_errors replace_in_file( "config/environments/development.rb", "raise_delivery_errors = false", "raise_delivery_errors = true", ) end def copy_setup_scripts directory(Hephaestus.source_path("script"), "script") Dir.glob("script/**/*").each do |file| next if File.directory?(file) chmod(file, 0o755) end end def configure_dev_hosting config = <<~EOD # Let dev server run on GitHub Codespaces config.hosts << /[a-z0-9-]+.githubpreview.dev/ # Let dev server run on ngrok domains config.hosts << /[a-z0-9-]+.ngrok.io/ EOD configure_environment("development", config) end def setup_asset_host config = <<~EOD config.public_file_server.headers = { "Cache-Control" => "public, max-age=31557600", } EOD configure_environment("production", config) end def setup_background_worker config = <<~EOD # Use a real queuing backend for Active Job (and separate queues per environment). config.active_job.queue_adapter = :sidekiq EOD configure_environment("production", config) configure_environment("staging", config) end def setup_slack_logger config = <<~EOD config.after_initialize do Rails.logger.extend(ActiveSupport::Logger.broadcast(SlackWebhookLogger.logger)) end EOD configure_environment("production", config) configure_environment("staging", config) configure_environment("test", config) end def setup_ssl ssl = <<~SSL config.force_ssl = true config.ssl_options = { hsts: { subdomains: true, preload: true, expires: 1.year } } SSL replace_in_file( "config/environments/production.rb", "# config.force_ssl = true", ssl, ) end def setup_staging_environment FileUtils.cp(File.join(destination_root, "config/environments/production.rb"), File.join(destination_root, "config/environments/staging.rb")) end def replace_gemfile template("Gemfile.erb", "Gemfile", force: true) do |content| if development_env? content.gsub(/gem .hephaestus./) { |s| %(#{s}, path: "#{root_path}") } else content end end end def restore_gemfile replace_in_file("Gemfile", /gem "hephaestus".+/, "gem \"hephaestus\"") end def ruby_version create_file(".ruby-version", "#{Hephaestus::RUBY_VERSION}\n") end def configure_time_formats replace_in_file("config/application.rb", /# config.time_zone = .*/, "config.time_zone = \"UTC\"") end def create_github_repo(repo_name) run("gh repo create #{repo_name}", exit_on_failure: false) end def remove_config_comment_lines config_files = [ "application.rb", "environment.rb", "environments/development.rb", "environments/production.rb", "environments/test.rb", ] config_files.each do |config_file| path = Pathname(destination_root).join("config", config_file) source = Actions::StripCommentsAction.call(path.read) path.write(source) end end def remove_routes_comment_lines replace_in_file( "config/routes.rb", /Rails\.application\.routes\.draw do.*end/m, "Rails.application.routes.draw do\nend", ) end def setup_test_environment remove_dir("test") source = File.join(Hephaestus::AppGenerator.source_root, "test") directory(source, "test") end def replace_generic_variables say(set_color("Replacing generic variable names...", :cyan)) replace_in_files(destination_root, /App(?!lication)/, short_app_name.capitalize) replace_in_files(destination_root, %r{(?