# frozen_string_literal: truerequire"rails/generators"moduleRailsmoduleGeneratorsclassDevcontainerGenerator<Base# :nodoc:class_option:app_name,type: :string,default: "rails_app",desc: "Name of the app"class_option:database,enum: Database::DATABASES,type: :string,default: "sqlite3",desc: "Include configuration for selected database"class_option:redis,type: :boolean,default: true,desc: "Include configuration for Redis"class_option:system_test,type: :boolean,default: true,desc: "Include configuration for System Tests"class_option:active_storage,type: :boolean,default: true,desc: "Include configuration for Active Storage"class_option:node,type: :boolean,default: false,desc: "Include configuration for Node"class_option:dev,type: :boolean,default: false,desc: "For applications pointing to a local Rails checkout"source_paths<<File.expand_path(File.join(base_name,"app","templates"),base_root)defcreate_devcontainerempty_directory".devcontainer"template"devcontainer/devcontainer.json",".devcontainer/devcontainer.json"template"devcontainer/Dockerfile",".devcontainer/Dockerfile"template"devcontainer/compose.yaml",".devcontainer/compose.yaml"enddefupdate_application_system_test_casereturnunlessoptions[:system_test]returnunlessFile.exist?("test/application_system_test_case.rb")gsub_file("test/application_system_test_case.rb",/^\s*driven_by\b.*/,system_test_configuration)enddefupdate_database_yml# Only postgresql has devcontainer specific configuration, so only update database.yml if we are using postgresreturnunlessoptions[:database]=="postgresql"template("config/databases/#{options[:database]}.yml","config/database.yml")endprivatedefdevcontainer?trueenddefapp_nameoptions[:app_name]enddefdependenciesreturn@dependenciesif@dependencies@dependencies=[]@dependencies<<"selenium"ifoptions[:system_test]@dependencies<<"redis"ifoptions[:redis]@dependencies<<database.nameifdatabase.service@dependenciesenddefcontainer_envreturn@container_envif@container_env@container_env={}@container_env["CAPYBARA_SERVER_PORT"]="45678"ifoptions[:system_test]@container_env["SELENIUM_HOST"]="selenium"ifoptions[:system_test]@container_env["REDIS_URL"]="redis://redis:6379/1"ifoptions[:redis]@container_env["DB_HOST"]=database.nameifdatabase.service@container_envenddefvolumesreturn@volumesif@volumes@volumes=[]@volumes<<"redis-data"ifoptions[:redis]@volumes<<database.volumeifdatabase.volume@volumesenddeffeaturesreturn@featuresif@features@features={"ghcr.io/devcontainers/features/github-cli:1"=>{}}@features["ghcr.io/rails/devcontainer/features/activestorage"]={}ifoptions[:active_storage]@features["ghcr.io/devcontainers/features/node:1"]={}ifoptions[:node]@features.merge!(database.feature)ifdatabase.feature@featuresenddefmountsreturn@mountsif@mounts@mounts=[]@mounts<<local_rails_mountifoptions[:dev]@mountsenddefforward_portsreturn@forward_portsif@forward_ports@forward_ports=[3000]@forward_ports<<database.portifdatabase.port@forward_ports<<6379ifoptions[:redis]@forward_portsenddefdatabase@database||=Database.build(options[:database])enddefdevcontainer_db_service_yaml(**options)returnunlessservice=database.service{database.name=>service}.to_yaml(**options)[4..-1]enddeflocal_rails_mount{type: "bind",source: Rails::Generators::RAILS_DEV_PATH,target: Rails::Generators::RAILS_DEV_PATH}enddefsystem_test_configurationoptimize_indentation(<<-'RUBY',2).chomp
if ENV["CAPYBARA_SERVER_PORT"]
served_by host: "rails-app", port: ENV["CAPYBARA_SERVER_PORT"]
driven_by :selenium, using: :headless_chrome, screen_size: [ 1400, 1400 ], options: {
browser: :remote,
url: "http://#{ENV["SELENIUM_HOST"]}:4444"
}
else
driven_by :selenium, using: :headless_chrome, screen_size: [ 1400, 1400 ]
end
RUBYendendendend