# 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 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 source = File.join(Hephaestus::AppGenerator.source_root, "script") directory(source, "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_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 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}") 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 replace_in_files(destination_root, "${APP}", short_appname.capitalize) replace_in_files(destination_root, "${app}", short_appname.downcase) replace_in_files(destination_root, "PlugApp", app_name.underscore.camelcase) replace_in_files(destination_root, "plug-app", app_name.dasherize) replace_in_files(destination_root, "PLUG_APP", app_name.underscore.upcase) replace_in_files(destination_root, "plug_app", app_name.underscore) end private def short_appname app_name.split("_").last end def root_path @root_path ||= Pathname(__dir__).join("..", "..").expand_path end def development_env? root_path.join("hephaestus.gemspec").exist? end def raise_on_missing_translations_in(environment) config = "config.i18n.raise_on_missing_translations = true" uncomment_lines("config/environments/#{environment}.rb", config) end def heroku_adapter @heroku_adapter ||= Adapters::Heroku.new(self) end end end