railties 7.1.5.1 → 7.2.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +197 -767
- data/lib/minitest/rails_plugin.rb +5 -2
- data/lib/rails/all.rb +1 -3
- data/lib/rails/api/task.rb +6 -4
- data/lib/rails/application/bootstrap.rb +5 -6
- data/lib/rails/application/configuration.rb +68 -33
- data/lib/rails/application/dummy_config.rb +2 -2
- data/lib/rails/application/finisher.rb +7 -0
- data/lib/rails/application.rb +22 -89
- data/lib/rails/backtrace_cleaner.rb +14 -1
- data/lib/rails/cli.rb +0 -1
- data/lib/rails/command.rb +1 -1
- data/lib/rails/commands/app/update_command.rb +102 -0
- data/lib/rails/commands/boot/boot_command.rb +14 -0
- data/lib/rails/commands/console/console_command.rb +2 -21
- data/lib/rails/commands/console/irb_console.rb +146 -0
- data/lib/rails/commands/credentials/credentials_command.rb +2 -2
- data/lib/rails/commands/dbconsole/dbconsole_command.rb +21 -30
- data/lib/rails/commands/devcontainer/devcontainer_command.rb +39 -0
- data/lib/rails/commands/rake/rake_command.rb +1 -1
- data/lib/rails/commands/runner/runner_command.rb +14 -3
- data/lib/rails/commands/server/server_command.rb +5 -3
- data/lib/rails/commands/test/test_command.rb +2 -0
- data/lib/rails/configuration.rb +10 -1
- data/lib/rails/console/app.rb +5 -32
- data/lib/rails/console/helpers.rb +5 -16
- data/lib/rails/console/methods.rb +23 -0
- data/lib/rails/engine.rb +7 -7
- data/lib/rails/gem_version.rb +2 -2
- data/lib/rails/generators/app_base.rb +70 -49
- data/lib/rails/generators/base.rb +5 -1
- data/lib/rails/generators/database.rb +227 -69
- data/lib/rails/generators/erb/scaffold/templates/edit.html.erb.tt +2 -0
- data/lib/rails/generators/erb/scaffold/templates/index.html.erb.tt +2 -0
- data/lib/rails/generators/erb/scaffold/templates/new.html.erb.tt +2 -0
- data/lib/rails/generators/generated_attribute.rb +26 -1
- data/lib/rails/generators/rails/app/app_generator.rb +56 -28
- data/lib/rails/generators/rails/app/templates/Dockerfile.tt +22 -15
- data/lib/rails/generators/rails/app/templates/Gemfile.tt +17 -17
- data/lib/rails/generators/rails/app/templates/app/controllers/application_controller.rb.tt +4 -0
- data/lib/rails/generators/rails/app/templates/app/views/layouts/application.html.erb.tt +8 -1
- data/lib/rails/generators/rails/app/templates/app/views/pwa/manifest.json.erb.tt +22 -0
- data/lib/rails/generators/rails/app/templates/app/views/pwa/service-worker.js +26 -0
- data/lib/rails/generators/rails/app/templates/bin/brakeman.tt +6 -0
- data/lib/rails/generators/rails/app/templates/bin/rubocop.tt +7 -0
- data/lib/rails/generators/rails/app/templates/bin/setup.tt +6 -2
- data/lib/rails/generators/rails/app/templates/config/application.rb.tt +1 -1
- data/lib/rails/generators/rails/app/templates/config/databases/mysql.yml.tt +3 -3
- data/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml.tt +7 -0
- data/lib/rails/generators/rails/app/templates/config/databases/sqlite3.yml.tt +8 -1
- data/lib/rails/generators/rails/app/templates/config/databases/trilogy.yml.tt +3 -3
- data/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt +14 -7
- data/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt +8 -0
- data/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt +8 -5
- data/lib/rails/generators/rails/app/templates/config/initializers/assets.rb.tt +1 -1
- data/lib/rails/generators/rails/app/templates/config/initializers/filter_parameter_logging.rb.tt +1 -1
- data/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_7_2.rb.tt +70 -0
- data/lib/rails/generators/rails/app/templates/config/puma.rb.tt +25 -35
- data/lib/rails/generators/rails/app/templates/config/routes.rb.tt +6 -0
- data/lib/rails/generators/rails/app/templates/docker-entrypoint.tt +5 -0
- data/lib/rails/generators/rails/app/templates/dockerignore.tt +13 -0
- data/lib/rails/generators/rails/app/templates/github/ci.yml.tt +138 -0
- data/lib/rails/generators/rails/app/templates/github/dependabot.yml +12 -0
- data/lib/rails/generators/rails/app/templates/gitignore.tt +3 -3
- data/lib/rails/generators/rails/app/templates/public/406-unsupported-browser.html +66 -0
- data/lib/rails/generators/rails/app/templates/public/icon.png +0 -0
- data/lib/rails/generators/rails/app/templates/public/icon.svg +3 -0
- data/lib/rails/generators/rails/app/templates/rubocop.yml.tt +8 -0
- data/lib/rails/generators/rails/app/templates/test/application_system_test_case.rb.tt +1 -1
- data/lib/rails/generators/rails/controller/controller_generator.rb +1 -1
- data/lib/rails/generators/rails/db/system/change/change_generator.rb +131 -20
- data/lib/rails/generators/rails/devcontainer/devcontainer_generator.rb +166 -0
- data/lib/rails/generators/rails/devcontainer/templates/devcontainer/Dockerfile.tt +3 -0
- data/lib/rails/generators/rails/devcontainer/templates/devcontainer/compose.yaml.tt +47 -0
- data/lib/rails/generators/rails/devcontainer/templates/devcontainer/devcontainer.json.tt +37 -0
- data/lib/rails/generators/rails/migration/migration_generator.rb +4 -0
- data/lib/rails/generators/rails/plugin/plugin_generator.rb +40 -7
- data/lib/rails/generators/rails/plugin/templates/%name%.gemspec.tt +2 -2
- data/lib/rails/generators/rails/plugin/templates/Gemfile.tt +5 -1
- data/lib/rails/generators/rails/plugin/templates/app/views/layouts/%namespaced_name%/application.html.erb.tt +2 -0
- data/lib/rails/generators/rails/plugin/templates/bin/rubocop.tt +7 -0
- data/lib/rails/generators/rails/plugin/templates/github/ci.yml.tt +103 -0
- data/lib/rails/generators/rails/plugin/templates/github/dependabot.yml +12 -0
- data/lib/rails/generators/rails/plugin/templates/rubocop.yml.tt +8 -0
- data/lib/rails/generators/rails/plugin/templates/test/application_system_test_case.rb.tt +1 -1
- data/lib/rails/generators/rails/plugin/templates/test/test_helper.rb.tt +2 -2
- data/lib/rails/generators/test_unit/mailer/templates/functional_test.rb.tt +6 -4
- data/lib/rails/generators/test_unit/mailer/templates/preview.rb.tt +3 -2
- data/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb +15 -1
- data/lib/rails/generators/test_unit/scaffold/templates/api_functional_test.rb.tt +2 -2
- data/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb.tt +2 -2
- data/lib/rails/generators/test_unit/scaffold/templates/system_test.rb.tt +2 -0
- data/lib/rails/generators/test_unit/system/templates/application_system_test_case.rb.tt +1 -1
- data/lib/rails/generators/testing/assertions.rb +20 -0
- data/lib/rails/generators/testing/behavior.rb +7 -6
- data/lib/rails/generators.rb +6 -2
- data/lib/rails/health_controller.rb +1 -1
- data/lib/rails/info.rb +2 -2
- data/lib/rails/mailers_controller.rb +14 -1
- data/lib/rails/paths.rb +2 -2
- data/lib/rails/pwa_controller.rb +15 -0
- data/lib/rails/rack/logger.rb +15 -7
- data/lib/rails/railtie/configurable.rb +2 -2
- data/lib/rails/railtie.rb +2 -3
- data/lib/rails/tasks/framework.rake +0 -26
- data/lib/rails/tasks/tmp.rake +1 -1
- data/lib/rails/templates/layouts/application.html.erb +1 -1
- data/lib/rails/templates/rails/mailers/email.html.erb +12 -8
- data/lib/rails/templates/rails/welcome/index.html.erb +4 -2
- data/lib/rails/test_help.rb +2 -4
- data/lib/rails/test_unit/reporter.rb +8 -2
- data/lib/rails/test_unit/runner.rb +26 -2
- data/lib/rails/test_unit/test_parser.rb +45 -0
- data/lib/rails.rb +6 -3
- metadata +40 -30
- data/lib/rails/app_updater.rb +0 -52
- data/lib/rails/commands/secrets/USAGE +0 -61
- data/lib/rails/commands/secrets/secrets_command.rb +0 -47
- data/lib/rails/generators/rails/app/templates/config/databases/jdbc.yml.tt +0 -68
- data/lib/rails/generators/rails/app/templates/config/databases/jdbcmysql.yml.tt +0 -54
- data/lib/rails/generators/rails/app/templates/config/databases/jdbcpostgresql.yml.tt +0 -70
- data/lib/rails/generators/rails/app/templates/config/databases/jdbcsqlite3.yml.tt +0 -24
- data/lib/rails/generators/rails/app/templates/config/databases/oracle.yml.tt +0 -62
- data/lib/rails/generators/rails/app/templates/config/databases/sqlserver.yml.tt +0 -53
- data/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_7_1.rb.tt +0 -280
- data/lib/rails/generators/rails/app/templates/public/apple-touch-icon-precomposed.png +0 -0
- data/lib/rails/generators/rails/app/templates/public/apple-touch-icon.png +0 -0
- data/lib/rails/generators/rails/app/templates/public/favicon.ico +0 -0
- data/lib/rails/ruby_version_check.rb +0 -17
- data/lib/rails/secrets.rb +0 -110
@@ -1,15 +1,19 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "rails/generators/base"
|
4
|
+
require "yaml"
|
5
|
+
require "json"
|
4
6
|
|
5
7
|
module Rails
|
6
8
|
module Generators
|
7
9
|
module Db
|
8
10
|
module System
|
9
11
|
class ChangeGenerator < Base # :nodoc:
|
10
|
-
include Database
|
11
12
|
include AppName
|
12
13
|
|
14
|
+
BASE_PACKAGES = %w( curl libvips )
|
15
|
+
BUILD_PACKAGES = %w( build-essential git )
|
16
|
+
|
13
17
|
class_option :to, required: true,
|
14
18
|
desc: "The database system to switch to."
|
15
19
|
|
@@ -21,8 +25,8 @@ module Rails
|
|
21
25
|
def initialize(*)
|
22
26
|
super
|
23
27
|
|
24
|
-
unless DATABASES.include?(options[:to])
|
25
|
-
raise Error, "Invalid value for --to option. Supported preconfigurations are: #{DATABASES.join(", ")}."
|
28
|
+
unless Database::DATABASES.include?(options[:to])
|
29
|
+
raise Error, "Invalid value for --to option. Supported preconfigurations are: #{Database::DATABASES.join(", ")}."
|
26
30
|
end
|
27
31
|
|
28
32
|
opt = options.dup
|
@@ -35,7 +39,7 @@ module Rails
|
|
35
39
|
end
|
36
40
|
|
37
41
|
def edit_gemfile
|
38
|
-
name, version =
|
42
|
+
name, version = database.gem
|
39
43
|
gsub_file("Gemfile", all_database_gems_regex, name)
|
40
44
|
gsub_file("Gemfile", gem_entry_regex_for(name), gem_entry_for(name, *version))
|
41
45
|
end
|
@@ -44,27 +48,44 @@ module Rails
|
|
44
48
|
dockerfile_path = File.expand_path("Dockerfile", destination_root)
|
45
49
|
return unless File.exist?(dockerfile_path)
|
46
50
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
51
|
+
gsub_file("Dockerfile", all_docker_bases_regex, docker_base_packages(database.base_package))
|
52
|
+
gsub_file("Dockerfile", all_docker_builds_regex, docker_build_packages(database.build_package))
|
53
|
+
end
|
54
|
+
|
55
|
+
def edit_devcontainer_files
|
56
|
+
return unless devcontainer?
|
57
|
+
|
58
|
+
edit_devcontainer_json
|
59
|
+
edit_compose_yaml
|
55
60
|
end
|
56
61
|
|
57
62
|
private
|
58
63
|
def all_database_gems
|
59
|
-
|
64
|
+
Database.all.map { |database| database.gem }
|
65
|
+
end
|
66
|
+
|
67
|
+
def all_docker_bases
|
68
|
+
Database.all.map { |database| docker_base_packages(database.base_package) }.uniq
|
69
|
+
end
|
70
|
+
|
71
|
+
def docker_base_packages(database_package)
|
72
|
+
if database_package
|
73
|
+
[database_package].concat(BASE_PACKAGES).sort
|
74
|
+
else
|
75
|
+
BASE_PACKAGES
|
76
|
+
end.join("\s")
|
60
77
|
end
|
61
78
|
|
62
79
|
def all_docker_builds
|
63
|
-
|
80
|
+
Database.all.map { |database| docker_build_packages(database.build_package) }.uniq
|
64
81
|
end
|
65
82
|
|
66
|
-
def
|
67
|
-
|
83
|
+
def docker_build_packages(database_package)
|
84
|
+
if database_package
|
85
|
+
[database_package].concat(BUILD_PACKAGES).sort
|
86
|
+
else
|
87
|
+
BUILD_PACKAGES
|
88
|
+
end.join("\s")
|
68
89
|
end
|
69
90
|
|
70
91
|
def all_database_gems_regex
|
@@ -72,12 +93,12 @@ module Rails
|
|
72
93
|
/(\b#{all_database_gem_names.join('\b|\b')}\b)/
|
73
94
|
end
|
74
95
|
|
75
|
-
def
|
76
|
-
/(\b#{
|
96
|
+
def all_docker_bases_regex
|
97
|
+
/(\b#{all_docker_bases.join('\b|\b')}\b)/
|
77
98
|
end
|
78
99
|
|
79
|
-
def
|
80
|
-
/(\b#{
|
100
|
+
def all_docker_builds_regex
|
101
|
+
/(\b#{all_docker_builds.join('\b|\b')}\b)/
|
81
102
|
end
|
82
103
|
|
83
104
|
def gem_entry_regex_for(gem_name)
|
@@ -88,6 +109,96 @@ module Rails
|
|
88
109
|
gem_name_and_version.map! { |segment| "\"#{segment}\"" }
|
89
110
|
"gem #{gem_name_and_version.join(", ")}"
|
90
111
|
end
|
112
|
+
|
113
|
+
def edit_devcontainer_json
|
114
|
+
return unless devcontainer_json
|
115
|
+
|
116
|
+
update_devcontainer_db_host
|
117
|
+
update_devcontainer_db_feature
|
118
|
+
end
|
119
|
+
|
120
|
+
def edit_compose_yaml
|
121
|
+
compose_yaml_path = File.expand_path(".devcontainer/compose.yaml", destination_root)
|
122
|
+
return unless File.exist?(compose_yaml_path)
|
123
|
+
|
124
|
+
compose_config = YAML.load_file(compose_yaml_path)
|
125
|
+
|
126
|
+
Database.all.each do |database|
|
127
|
+
compose_config["services"].delete(database.name)
|
128
|
+
compose_config["volumes"]&.delete(database.volume)
|
129
|
+
compose_config["services"]["rails-app"]["depends_on"]&.delete(database.name)
|
130
|
+
end
|
131
|
+
|
132
|
+
if database.service
|
133
|
+
compose_config["services"][database.name] = database.service
|
134
|
+
compose_config["volumes"] = { database.volume => nil }.merge(compose_config["volumes"] || {})
|
135
|
+
compose_config["services"]["rails-app"]["depends_on"] = [
|
136
|
+
database.name,
|
137
|
+
compose_config["services"]["rails-app"]["depends_on"]
|
138
|
+
].flatten.compact
|
139
|
+
end
|
140
|
+
|
141
|
+
compose_config.delete("volumes") unless compose_config["volumes"]&.any?
|
142
|
+
compose_config["services"]["rails-app"].delete("depends_on") unless compose_config["services"]["rails-app"]["depends_on"]&.any?
|
143
|
+
|
144
|
+
File.write(compose_yaml_path, compose_config.to_yaml)
|
145
|
+
end
|
146
|
+
|
147
|
+
def update_devcontainer_db_host
|
148
|
+
container_env = devcontainer_json["containerEnv"]
|
149
|
+
db_name = database.name
|
150
|
+
|
151
|
+
if container_env["DB_HOST"]
|
152
|
+
if database.service
|
153
|
+
container_env["DB_HOST"] = db_name
|
154
|
+
else
|
155
|
+
container_env.delete("DB_HOST")
|
156
|
+
end
|
157
|
+
else
|
158
|
+
if database.service
|
159
|
+
container_env["DB_HOST"] = db_name
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
new_json = JSON.pretty_generate(container_env, indent: " ", object_nl: "\n ")
|
164
|
+
|
165
|
+
gsub_file(".devcontainer/devcontainer.json", /("containerEnv"\s*:\s*)(.|\n)*?(^\s{2}})/, "\\1#{new_json}")
|
166
|
+
end
|
167
|
+
|
168
|
+
def update_devcontainer_db_feature
|
169
|
+
features = devcontainer_json["features"]
|
170
|
+
db_feature = database.feature
|
171
|
+
|
172
|
+
Database.all.each do |database|
|
173
|
+
features.delete(database.feature_name)
|
174
|
+
end
|
175
|
+
|
176
|
+
features.merge!(db_feature) if db_feature
|
177
|
+
|
178
|
+
new_json = JSON.pretty_generate(features, indent: " ", object_nl: "\n ")
|
179
|
+
|
180
|
+
gsub_file(".devcontainer/devcontainer.json", /("features"\s*:\s*)(.|\n)*?(^\s{2}})/, "\\1#{new_json}")
|
181
|
+
end
|
182
|
+
|
183
|
+
def devcontainer_json
|
184
|
+
return unless File.exist?(devcontainer_json_path)
|
185
|
+
|
186
|
+
@devcontainer_json ||= JSON.parse(File.read(devcontainer_json_path))
|
187
|
+
end
|
188
|
+
|
189
|
+
def devcontainer_json_path
|
190
|
+
File.expand_path(".devcontainer/devcontainer.json", destination_root)
|
191
|
+
end
|
192
|
+
|
193
|
+
def database
|
194
|
+
@database ||= Database.build(options[:database])
|
195
|
+
end
|
196
|
+
|
197
|
+
def devcontainer?
|
198
|
+
return @devcontainer if defined?(@devcontainer)
|
199
|
+
|
200
|
+
@devcontainer = File.exist?(File.expand_path(".devcontainer", destination_root))
|
201
|
+
end
|
91
202
|
end
|
92
203
|
end
|
93
204
|
end
|
@@ -0,0 +1,166 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "rails/generators"
|
4
|
+
|
5
|
+
module Rails
|
6
|
+
module Generators
|
7
|
+
class DevcontainerGenerator < Base # :nodoc:
|
8
|
+
class_option :app_name, type: :string, default: "rails_app",
|
9
|
+
desc: "Name of the app"
|
10
|
+
|
11
|
+
class_option :database, enum: Database::DATABASES, type: :string, default: "sqlite3",
|
12
|
+
desc: "Include configuration for selected database"
|
13
|
+
|
14
|
+
class_option :redis, type: :boolean, default: true,
|
15
|
+
desc: "Include configuration for Redis"
|
16
|
+
|
17
|
+
class_option :system_test, type: :boolean, default: true,
|
18
|
+
desc: "Include configuration for System Tests"
|
19
|
+
|
20
|
+
class_option :active_storage, type: :boolean, default: true,
|
21
|
+
desc: "Include configuration for Active Storage"
|
22
|
+
|
23
|
+
class_option :node, type: :boolean, default: false,
|
24
|
+
desc: "Include configuration for Node"
|
25
|
+
|
26
|
+
class_option :dev, type: :boolean, default: false,
|
27
|
+
desc: "For applications pointing to a local Rails checkout"
|
28
|
+
|
29
|
+
source_paths << File.expand_path(File.join(base_name, "app", "templates"), base_root)
|
30
|
+
|
31
|
+
def create_devcontainer
|
32
|
+
empty_directory ".devcontainer"
|
33
|
+
|
34
|
+
template "devcontainer/devcontainer.json", ".devcontainer/devcontainer.json"
|
35
|
+
template "devcontainer/Dockerfile", ".devcontainer/Dockerfile"
|
36
|
+
template "devcontainer/compose.yaml", ".devcontainer/compose.yaml"
|
37
|
+
end
|
38
|
+
|
39
|
+
def update_application_system_test_case
|
40
|
+
return unless options[:system_test]
|
41
|
+
return unless File.exist?("test/application_system_test_case.rb")
|
42
|
+
|
43
|
+
gsub_file("test/application_system_test_case.rb", /^\s*driven_by\b.*/, system_test_configuration)
|
44
|
+
end
|
45
|
+
|
46
|
+
def update_database_yml
|
47
|
+
# Only postgresql has devcontainer specific configuration, so only update database.yml if we are using postgres
|
48
|
+
return unless options[:database] == "postgresql"
|
49
|
+
|
50
|
+
template("config/databases/#{options[:database]}.yml", "config/database.yml")
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
def devcontainer?
|
55
|
+
true
|
56
|
+
end
|
57
|
+
|
58
|
+
def app_name
|
59
|
+
options[:app_name]
|
60
|
+
end
|
61
|
+
|
62
|
+
def dependencies
|
63
|
+
return @dependencies if @dependencies
|
64
|
+
|
65
|
+
@dependencies = []
|
66
|
+
|
67
|
+
@dependencies << "selenium" if options[:system_test]
|
68
|
+
@dependencies << "redis" if options[:redis]
|
69
|
+
@dependencies << database.name if database.service
|
70
|
+
@dependencies
|
71
|
+
end
|
72
|
+
|
73
|
+
def container_env
|
74
|
+
return @container_env if @container_env
|
75
|
+
|
76
|
+
@container_env = {}
|
77
|
+
|
78
|
+
@container_env["CAPYBARA_SERVER_PORT"] = "45678" if options[:system_test]
|
79
|
+
@container_env["SELENIUM_HOST"] = "selenium" if options[:system_test]
|
80
|
+
@container_env["REDIS_URL"] = "redis://redis:6379/1" if options[:redis]
|
81
|
+
@container_env["DB_HOST"] = database.name if database.service
|
82
|
+
|
83
|
+
@container_env
|
84
|
+
end
|
85
|
+
|
86
|
+
def volumes
|
87
|
+
return @volumes if @volumes
|
88
|
+
|
89
|
+
@volumes = []
|
90
|
+
|
91
|
+
@volumes << "redis-data" if options[:redis]
|
92
|
+
@volumes << database.volume if database.volume
|
93
|
+
|
94
|
+
@volumes
|
95
|
+
end
|
96
|
+
|
97
|
+
def features
|
98
|
+
return @features if @features
|
99
|
+
|
100
|
+
@features = {
|
101
|
+
"ghcr.io/devcontainers/features/github-cli:1" => {}
|
102
|
+
}
|
103
|
+
|
104
|
+
@features["ghcr.io/rails/devcontainer/features/activestorage"] = {} if options[:active_storage]
|
105
|
+
@features["ghcr.io/devcontainers/features/node:1"] = {} if options[:node]
|
106
|
+
|
107
|
+
@features.merge!(database.feature) if database.feature
|
108
|
+
|
109
|
+
@features
|
110
|
+
end
|
111
|
+
|
112
|
+
def mounts
|
113
|
+
return @mounts if @mounts
|
114
|
+
|
115
|
+
@mounts = []
|
116
|
+
|
117
|
+
@mounts << local_rails_mount if options[:dev]
|
118
|
+
|
119
|
+
@mounts
|
120
|
+
end
|
121
|
+
|
122
|
+
def forward_ports
|
123
|
+
return @forward_ports if @forward_ports
|
124
|
+
|
125
|
+
@forward_ports = [3000]
|
126
|
+
@forward_ports << database.port if database.port
|
127
|
+
@forward_ports << 6379 if options[:redis]
|
128
|
+
|
129
|
+
@forward_ports
|
130
|
+
end
|
131
|
+
|
132
|
+
def database
|
133
|
+
@database ||= Database.build(options[:database])
|
134
|
+
end
|
135
|
+
|
136
|
+
def devcontainer_db_service_yaml(**options)
|
137
|
+
return unless service = database.service
|
138
|
+
|
139
|
+
{ database.name => service }.to_yaml(**options)[4..-1]
|
140
|
+
end
|
141
|
+
|
142
|
+
def local_rails_mount
|
143
|
+
{
|
144
|
+
type: "bind",
|
145
|
+
source: Rails::Generators::RAILS_DEV_PATH,
|
146
|
+
target: Rails::Generators::RAILS_DEV_PATH
|
147
|
+
}
|
148
|
+
end
|
149
|
+
|
150
|
+
def system_test_configuration
|
151
|
+
optimize_indentation(<<-'RUBY', 2).chomp
|
152
|
+
if ENV["CAPYBARA_SERVER_PORT"]
|
153
|
+
served_by host: "rails-app", port: ENV["CAPYBARA_SERVER_PORT"]
|
154
|
+
|
155
|
+
driven_by :selenium, using: :headless_chrome, screen_size: [ 1400, 1400 ], options: {
|
156
|
+
browser: :remote,
|
157
|
+
url: "http://#{ENV["SELENIUM_HOST"]}:4444"
|
158
|
+
}
|
159
|
+
else
|
160
|
+
driven_by :selenium, using: :headless_chrome, screen_size: [ 1400, 1400 ]
|
161
|
+
end
|
162
|
+
RUBY
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
name: "<%= options[:app_name] %>"
|
2
|
+
|
3
|
+
services:
|
4
|
+
rails-app:
|
5
|
+
build:
|
6
|
+
context: ..
|
7
|
+
dockerfile: .devcontainer/Dockerfile
|
8
|
+
|
9
|
+
volumes:
|
10
|
+
- ../..:/workspaces:cached
|
11
|
+
|
12
|
+
# Overrides default command so things don't shut down after the process ends.
|
13
|
+
command: sleep infinity
|
14
|
+
|
15
|
+
# Uncomment the next line to use a non-root user for all processes.
|
16
|
+
# user: vscode
|
17
|
+
|
18
|
+
# Use "forwardPorts" in **devcontainer.json** to forward an app port locally.
|
19
|
+
# (Adding the "ports" property to this file will not forward from a Codespace.)
|
20
|
+
<%- if !dependencies.empty? -%>
|
21
|
+
depends_on:
|
22
|
+
<%- dependencies.each do |dependency| -%>
|
23
|
+
- <%= dependency %>
|
24
|
+
<%- end -%>
|
25
|
+
<%- end -%>
|
26
|
+
<%- if options[:system_test] -%>
|
27
|
+
|
28
|
+
selenium:
|
29
|
+
image: selenium/standalone-chromium
|
30
|
+
restart: unless-stopped
|
31
|
+
<%- end -%>
|
32
|
+
|
33
|
+
<%- if options[:redis] -%>
|
34
|
+
redis:
|
35
|
+
image: redis:7.2
|
36
|
+
restart: unless-stopped
|
37
|
+
volumes:
|
38
|
+
- redis-data:/data
|
39
|
+
|
40
|
+
<%- end -%>
|
41
|
+
<%= devcontainer_db_service_yaml(indentation: 4) %>
|
42
|
+
<%- if !volumes.empty? -%>
|
43
|
+
volumes:
|
44
|
+
<%- volumes.each do |volume| -%>
|
45
|
+
<%= volume %>:
|
46
|
+
<%- end -%>
|
47
|
+
<%- end -%>
|
@@ -0,0 +1,37 @@
|
|
1
|
+
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
|
2
|
+
// README at: https://github.com/devcontainers/templates/tree/main/src/ruby
|
3
|
+
{
|
4
|
+
"name": "<%= options[:app_name] %>",
|
5
|
+
"dockerComposeFile": "compose.yaml",
|
6
|
+
"service": "rails-app",
|
7
|
+
"workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}",
|
8
|
+
|
9
|
+
// Features to add to the dev container. More info: https://containers.dev/features.
|
10
|
+
"features": {
|
11
|
+
<%= features.map { |key, value| "\"#{key}\": #{value.as_json}" }.join(",\n ") %>
|
12
|
+
},
|
13
|
+
|
14
|
+
<%- if !container_env.empty? -%>
|
15
|
+
"containerEnv": {
|
16
|
+
<%= container_env.map { |key, value| "\"#{key}\": \"#{value}\"" }.join(",\n ") %>
|
17
|
+
},
|
18
|
+
<%- end -%>
|
19
|
+
|
20
|
+
// Use 'forwardPorts' to make a list of ports inside the container available locally.
|
21
|
+
"forwardPorts": <%= forward_ports.as_json %>,
|
22
|
+
|
23
|
+
// Configure tool-specific properties.
|
24
|
+
// "customizations": {},
|
25
|
+
|
26
|
+
// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
|
27
|
+
// "remoteUser": "root",
|
28
|
+
|
29
|
+
<%- if !mounts.empty? -%>
|
30
|
+
"mounts": [
|
31
|
+
<%= mounts.map { |mount| "{\n " + mount.map { |key, value| "\"#{key}\": \"#{value}\"" }.join(",\n ") + "\n }" }.join(",\n ") %>
|
32
|
+
],
|
33
|
+
<%- end -%>
|
34
|
+
|
35
|
+
// Use 'postCreateCommand' to run commands after the container is created.
|
36
|
+
"postCreateCommand": "bin/setup"
|
37
|
+
}
|
@@ -5,6 +5,10 @@ module Rails
|
|
5
5
|
class MigrationGenerator < NamedBase # :nodoc:
|
6
6
|
argument :attributes, type: :array, default: [], banner: "field[:type][:index] field[:type][:index]"
|
7
7
|
hook_for :orm, required: true, desc: "ORM to be invoked"
|
8
|
+
|
9
|
+
def self.exit_on_failure? # :nodoc:
|
10
|
+
true
|
11
|
+
end
|
8
12
|
end
|
9
13
|
end
|
10
14
|
end
|
@@ -66,6 +66,16 @@ module Rails
|
|
66
66
|
template "gitignore", ".gitignore"
|
67
67
|
end
|
68
68
|
|
69
|
+
def cifiles
|
70
|
+
empty_directory ".github/workflows"
|
71
|
+
template "github/ci.yml", ".github/workflows/ci.yml"
|
72
|
+
template "github/dependabot.yml", ".github/dependabot.yml"
|
73
|
+
end
|
74
|
+
|
75
|
+
def rubocop
|
76
|
+
template "rubocop.yml", ".rubocop.yml"
|
77
|
+
end
|
78
|
+
|
69
79
|
def version_control
|
70
80
|
if !options[:skip_git] && !options[:pretend]
|
71
81
|
run git_init_command, capture: options[:quiet], abort_on_failure: false
|
@@ -112,9 +122,12 @@ module Rails
|
|
112
122
|
def generate_test_dummy(force = false)
|
113
123
|
opts = options.transform_keys(&:to_sym).except(*DUMMY_IGNORE_OPTIONS)
|
114
124
|
opts[:force] = force
|
125
|
+
opts[:skip_brakeman] = true
|
115
126
|
opts[:skip_bundle] = true
|
127
|
+
opts[:skip_ci] = true
|
116
128
|
opts[:skip_git] = true
|
117
129
|
opts[:skip_hotwire] = true
|
130
|
+
opts[:skip_rubocop] = true
|
118
131
|
opts[:dummy_app] = true
|
119
132
|
|
120
133
|
invoke Rails::Generators::AppGenerator,
|
@@ -144,7 +157,7 @@ module Rails
|
|
144
157
|
def test_dummy_clean
|
145
158
|
inside dummy_path do
|
146
159
|
remove_file ".ruby-version"
|
147
|
-
|
160
|
+
remove_dir "db"
|
148
161
|
remove_file "Gemfile"
|
149
162
|
remove_file "lib/tasks"
|
150
163
|
remove_file "public/robots.txt"
|
@@ -167,12 +180,12 @@ module Rails
|
|
167
180
|
end
|
168
181
|
end
|
169
182
|
|
170
|
-
def bin
|
171
|
-
|
172
|
-
|
183
|
+
def bin
|
184
|
+
exclude_pattern = Regexp.union([(engine? ? /test\.tt/ : /rails\.tt/), (/rubocop/ if skip_rubocop?)].compact)
|
185
|
+
directory "bin", { exclude_pattern: exclude_pattern } do |content|
|
173
186
|
"#{shebang}\n" + content
|
174
187
|
end
|
175
|
-
chmod "bin", 0755, verbose: false
|
188
|
+
chmod "bin", 0755 & ~File.umask, verbose: false
|
176
189
|
end
|
177
190
|
|
178
191
|
def gemfile_entry
|
@@ -180,7 +193,7 @@ module Rails
|
|
180
193
|
|
181
194
|
gemfile_in_app_path = File.join(rails_app_path, "Gemfile")
|
182
195
|
if File.exist? gemfile_in_app_path
|
183
|
-
entry =
|
196
|
+
entry = %{\ngem "#{name}", path: "#{relative_path}"}
|
184
197
|
append_file gemfile_in_app_path, entry
|
185
198
|
end
|
186
199
|
end
|
@@ -243,6 +256,16 @@ module Rails
|
|
243
256
|
build(:app)
|
244
257
|
end
|
245
258
|
|
259
|
+
def create_rubocop_file
|
260
|
+
return if skip_rubocop?
|
261
|
+
build(:rubocop)
|
262
|
+
end
|
263
|
+
|
264
|
+
def create_cifiles
|
265
|
+
return if skip_ci?
|
266
|
+
build(:cifiles)
|
267
|
+
end
|
268
|
+
|
246
269
|
def create_config_files
|
247
270
|
build(:config)
|
248
271
|
end
|
@@ -341,7 +364,7 @@ module Rails
|
|
341
364
|
build(:test_dummy_sprocket_assets) unless skip_sprockets?
|
342
365
|
build(:test_dummy_clean)
|
343
366
|
# ensure that bin/rails has proper dummy_path
|
344
|
-
build(:bin
|
367
|
+
build(:bin)
|
345
368
|
end
|
346
369
|
end
|
347
370
|
|
@@ -465,6 +488,16 @@ module Rails
|
|
465
488
|
return unless inside_application?
|
466
489
|
app_path.delete_prefix("#{rails_app_path}/")
|
467
490
|
end
|
491
|
+
|
492
|
+
def test_command
|
493
|
+
if engine? && !options[:skip_active_record] && with_dummy_app?
|
494
|
+
"bin/rails db:test:prepare test"
|
495
|
+
elsif engine?
|
496
|
+
"bin/rails test"
|
497
|
+
else
|
498
|
+
"bin/test"
|
499
|
+
end
|
500
|
+
end
|
468
501
|
end
|
469
502
|
end
|
470
503
|
end
|
@@ -3,8 +3,8 @@ require_relative "lib/<%= namespaced_name %>/version"
|
|
3
3
|
Gem::Specification.new do |spec|
|
4
4
|
spec.name = <%= name.inspect %>
|
5
5
|
spec.version = <%= camelized_modules %>::VERSION
|
6
|
-
spec.authors = [<%= author.inspect %>]
|
7
|
-
spec.email = [<%= email.inspect %>]
|
6
|
+
spec.authors = [ <%= author.inspect %> ]
|
7
|
+
spec.email = [ <%= email.inspect %> ]
|
8
8
|
spec.homepage = "TODO"
|
9
9
|
spec.summary = "TODO: Summary of <%= camelized_modules %>."
|
10
10
|
spec.description = "TODO: Description of <%= camelized_modules %>."
|
@@ -1,5 +1,4 @@
|
|
1
1
|
source "https://rubygems.org"
|
2
|
-
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
|
3
2
|
<% unless options[:skip_gemspec] -%>
|
4
3
|
|
5
4
|
# Specify your gem's dependencies in <%= name %>.gemspec.
|
@@ -8,6 +7,11 @@ gemspec
|
|
8
7
|
<% gemfile_entries.each do |gemfile_entry| %>
|
9
8
|
<%= gemfile_entry %>
|
10
9
|
<% end -%>
|
10
|
+
<%- unless options.skip_rubocop? -%>
|
11
|
+
|
12
|
+
# Omakase Ruby styling [https://github.com/rails/rubocop-rails-omakase/]
|
13
|
+
gem "rubocop-rails-omakase", require: false
|
14
|
+
<%- end -%>
|
11
15
|
<% if RUBY_ENGINE == "ruby" -%>
|
12
16
|
|
13
17
|
# Start debugger with binding.b [https://github.com/ruby/debug]
|