diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml
index da2ed2af2..2a251c432 100644
--- a/.github/workflows/maven.yml
+++ b/.github/workflows/maven.yml
@@ -19,9 +19,16 @@ jobs:
strategy:
matrix:
- jruby_version: [ '9.3.15.0', '9.4.14.0' ]
+ jruby_version: [ '9.3.15.0', '9.4.14.0', '10.0.2.0' ]
java_version: [ '8', '11', '17', '21', '25' ]
rack_version: [ '~> 2.2.0' ]
+ exclude:
+ - jruby_version: '10.0.2.0'
+ java_version: '8' # JRuby 10 requires Java 21
+ - jruby_version: '10.0.2.0'
+ java_version: '11' # JRuby 10 requires Java 21
+ - jruby_version: '10.0.2.0'
+ java_version: '17' # JRuby 10 requires Java 21
fail-fast: false
steps:
@@ -59,16 +66,27 @@ jobs:
'rails70_rack22',
'rails71_rack22',
'rails72_rack22',
+ 'rails80_rack22',
]
- jruby_version: [ '9.3.15.0', '9.4.14.0' ]
+ jruby_version: [ '9.3.15.0', '9.4.14.0', '10.0.2.0' ]
java_version: [ '8', '11', '17', '21', '25' ]
exclude:
+ - jruby_version: '10.0.2.0'
+ java_version: '8' # JRuby 10 requires Java 21
+ - jruby_version: '10.0.2.0'
+ java_version: '11' # JRuby 10 requires Java 21
+ - jruby_version: '10.0.2.0'
+ java_version: '17' # JRuby 10 requires Java 21
- appraisal: 'rails70_rack22' # Requires Ruby 2.7 compatibility, which JRuby 9.3 does not support
jruby_version: '9.3.15.0'
- appraisal: 'rails71_rack22' # Requires Ruby 2.7 compatibility, which JRuby 9.3 does not support
jruby_version: '9.3.15.0'
- appraisal: 'rails72_rack22' # Requires Ruby 3.1 compatibility, which JRuby 9.3 does not support
jruby_version: '9.3.15.0'
+ - appraisal: 'rails80_rack22' # Requires Ruby 3.4 compatibility, which JRuby 9.3 does not support
+ jruby_version: '9.3.15.0'
+ - appraisal: 'rails80_rack22' # Requires Ruby 3.4 compatibility, which JRuby 9.4 does not support
+ jruby_version: '9.4.14.0'
fail-fast: false
env:
diff --git a/Appraisals b/Appraisals
index 44cff81b8..d23863e35 100644
--- a/Appraisals
+++ b/Appraisals
@@ -9,7 +9,8 @@ version_spec = ->(prefix, desc) { "~> #{desc.split(prefix).last.insert(1, ".")}.
"rails61" => %w[rack22],
"rails70" => %w[rack22],
"rails71" => %w[rack22],
- "rails72" => %w[rack22]
+ "rails72" => %w[rack22],
+ "rails80" => %w[rack22]
}.each do |rails_desc, rack_descs|
rack_descs.each do |rack_desc|
diff --git a/CHANGELOG.md b/CHANGELOG.md
index dc2ce17c0..c57763489 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,7 @@
- Ensure rack boot process leaves ENV['GEM_PATH'] and Gem.paths in a consistent state
- Remove undocumented and unsafe jruby.rack.env.gem_path = false option (unusable on Bundler 1.6+)
- Fix unintended Rubygems initialization too early in boot process with JRuby 9.4+
+- Adds basic compatibility with JRuby 10.0
## 1.2.5
diff --git a/README.md b/README.md
index e7bf465b0..5401cb297 100644
--- a/README.md
+++ b/README.md
@@ -15,7 +15,7 @@ For more information on Rack, visit http://rack.github.io/.
| JRuby-Rack Series | Status | Rack | JRuby | Java | Rails | Target Servlet API | Notes |
|------------------------------------------------------------|------------|-----------|------------|------|-----------|---------------------|--------------------------------------------|
-| [1.2](https://github.com/jruby/jruby-rack/tree/1.2-stable) | Maintained | 2.2 | 9.3 → 9.4 | 8+ | 5.0 → 7.2 | 3.0 (Java EE 6) | Servlet 3.1 → 4.0 OK with some containers. |
+| [1.2](https://github.com/jruby/jruby-rack/tree/1.2-stable) | Maintained | 2.2 | 9.3 → 10.0 | 8+ | 5.0 → 8.0 | 3.0 (Java EE 6) | Servlet 3.1 → 4.0 OK with some containers. |
| [1.1](https://github.com/jruby/jruby-rack/tree/1.1-stable) | EOL | 1.x → 2.2 | 1.6 → 9.4 | 6+ | 2.1 → 5.2 | 2.5 (Java EE 5) | Servlet 3.0 → 4.0 OK with some containers. |
| 1.0 | EOL | 0.9 → 1.x | 1.1 → 1.9 | 5+ | 2.1 → 3.x | 2.5 (Java EE 5) | |
@@ -209,8 +209,6 @@ as context init parameters in web.xml or as VM-wide system properties.
sub-path of the main servlet context root.
- `gem.path`: Relative path to the bundled gem repository. Defaults to
`/WEB-INF/gems`.
-- `jruby.compat.version`: Set to "1.8" or "1.9" to make JRuby run a specific
- version of Ruby (same as the --1.8 / --1.9 command line flags).
- `jruby.min.runtimes`: For non-threadsafe Rails applications using a runtime
pool, specify an integer minimum number of runtimes to hold in the pool.
- `jruby.max.runtimes`: For non-threadsafe Rails applications, an integer
diff --git a/gemfiles/rails80_rack22.gemfile b/gemfiles/rails80_rack22.gemfile
new file mode 100644
index 000000000..470ec79a5
--- /dev/null
+++ b/gemfiles/rails80_rack22.gemfile
@@ -0,0 +1,15 @@
+# This file was generated by Appraisal
+
+source "https://rubygems.org"
+
+gem "rake", "~> 13.3", group: :test, require: nil
+gem "rspec", group: :test
+
+group :default do
+ gem "rack", "~> 2.2.0"
+ gem "rails", "~> 8.0.0"
+end
+
+group :development do
+ gem "appraisal", require: nil
+end
diff --git a/src/main/java/org/jruby/CompatVersion.java b/src/main/java/org/jruby/CompatVersion.java
new file mode 100644
index 000000000..629b765ee
--- /dev/null
+++ b/src/main/java/org/jruby/CompatVersion.java
@@ -0,0 +1,62 @@
+package org.jruby;
+
+/**
+ * Removed from JRuby Core as of 10.0; but deprecated and unused for a long time.
+ *
+ * Added back to jruby-rack 1.2.x to allow JRuby 10 support without an API changed, but
+ * will be removed in jruby-rack 1.3.0
+ *
+ * @link https://github.com/jruby/jruby/blob/jruby-9.3/core/src/main/java/org/jruby/CompatVersion.java
+ * @deprecated since JRuby 9.2 with no replacement; for removal with jruby-rack 1.3.0
+ */
+@Deprecated
+public enum CompatVersion {
+
+ @Deprecated RUBY1_8,
+ @Deprecated RUBY1_9,
+ @Deprecated RUBY2_0,
+ @Deprecated RUBY2_1,
+ @Deprecated BOTH;
+
+ @Deprecated
+ public boolean is1_9() {
+ return this == RUBY1_9 || this == RUBY2_0 || this == RUBY2_1;
+ }
+
+ @Deprecated
+ public boolean is2_0() {
+ return this == RUBY2_0 || this == RUBY2_1;
+ }
+
+ @Deprecated
+ public static CompatVersion getVersionFromString(String compatString) {
+ if (compatString.equalsIgnoreCase("RUBY1_8")) {
+ return CompatVersion.RUBY1_8;
+ } else if (compatString.equalsIgnoreCase("1.8")) {
+ return CompatVersion.RUBY1_8;
+ } else if (compatString.equalsIgnoreCase("RUBY1_9")) {
+ return CompatVersion.RUBY1_9;
+ } else if (compatString.equalsIgnoreCase("1.9")) {
+ return CompatVersion.RUBY1_9;
+ } else if (compatString.equalsIgnoreCase("RUBY2_0")) {
+ return CompatVersion.RUBY2_0;
+ } else if (compatString.equalsIgnoreCase("2.0")) {
+ return CompatVersion.RUBY2_0;
+ } else if (compatString.equalsIgnoreCase("RUBY2_1")) {
+ return CompatVersion.RUBY2_1;
+ } else if (compatString.equalsIgnoreCase("2.1")) {
+ return CompatVersion.RUBY2_1;
+ } else {
+ return null;
+ }
+ }
+
+ @Deprecated
+ public static boolean shouldBindMethod(CompatVersion runtimeVersion, CompatVersion methodVersion) {
+ if (runtimeVersion == RUBY1_8) return methodVersion == RUBY1_8 || methodVersion == BOTH;
+ if (runtimeVersion == RUBY1_9) return methodVersion == RUBY1_9 || methodVersion == BOTH;
+ if (runtimeVersion == RUBY2_0) return methodVersion == RUBY1_9 || methodVersion == RUBY2_0 || methodVersion == BOTH;
+ if (runtimeVersion == RUBY2_1) return methodVersion == RUBY1_9 || methodVersion == RUBY2_0 || methodVersion == RUBY2_1 || methodVersion == BOTH;
+ return false;
+ }
+}
diff --git a/src/main/java/org/jruby/rack/DefaultRackApplicationFactory.java b/src/main/java/org/jruby/rack/DefaultRackApplicationFactory.java
index 63b3b2a67..9b37a0a63 100644
--- a/src/main/java/org/jruby/rack/DefaultRackApplicationFactory.java
+++ b/src/main/java/org/jruby/rack/DefaultRackApplicationFactory.java
@@ -302,10 +302,6 @@ protected RubyInstanceConfig initRuntimeConfig(final RubyInstanceConfig config)
// Process arguments, namely any that might be in RUBYOPT
config.processArguments(rackConfig.getRuntimeArguments());
- if ( rackConfig.getCompatVersion() != null ) {
- config.setCompatVersion(rackConfig.getCompatVersion());
- }
-
try { // try to set jruby home to jar file path
final URL resource = Ruby.class.getResource("/META-INF/jruby.home");
if ( resource != null && "jar".equals( resource.getProtocol() ) ) {
diff --git a/src/main/java/org/jruby/rack/DefaultRackConfig.java b/src/main/java/org/jruby/rack/DefaultRackConfig.java
index 8a0fd14c3..7f36a45a1 100644
--- a/src/main/java/org/jruby/rack/DefaultRackConfig.java
+++ b/src/main/java/org/jruby/rack/DefaultRackConfig.java
@@ -17,8 +17,6 @@
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
import org.jruby.CompatVersion;
import org.jruby.rack.logging.OutputStreamLogger;
@@ -81,23 +79,6 @@ public void setQuiet(boolean quiet) {
@Override
public CompatVersion getCompatVersion() {
- final String version = getProperty("jruby.compat.version");
- if ( version != null ) {
- // we handle 1.8, RUBY1_9, --2.0 1_9 2.1.0.dev etc :
- final Pattern pattern = Pattern.compile("([123])[._]([8901234567])");
- final Matcher matcher = pattern.matcher(version);
- if ( matcher.find() ) {
- final String name = "RUBY" +
- matcher.group(1) + '_' + matcher.group(2);
- try {
- return Enum.valueOf(CompatVersion.class, name);
- }
- catch (IllegalArgumentException e) {
- getLogger().log(WARN,
- "could not resolve compat version from '"+ version +"' will use default", e);
- }
- }
- }
return null;
}
diff --git a/src/main/java/org/jruby/rack/RackConfig.java b/src/main/java/org/jruby/rack/RackConfig.java
index 438d29195..18f8f307b 100644
--- a/src/main/java/org/jruby/rack/RackConfig.java
+++ b/src/main/java/org/jruby/rack/RackConfig.java
@@ -36,7 +36,10 @@ public interface RackConfig {
/**
* Return the Ruby version that JRuby should run.
* @return RUBY_VERSION (e.g. 1.8, 1.9)
+ *
+ * @deprecated Since jruby-rack 1.2 (and JRuby 9.2), for removal in 1.3.0
*/
+ @Deprecated
CompatVersion getCompatVersion();
/**
diff --git a/src/main/java/org/jruby/rack/embed/Config.java b/src/main/java/org/jruby/rack/embed/Config.java
index 49009f9b5..468b55811 100644
--- a/src/main/java/org/jruby/rack/embed/Config.java
+++ b/src/main/java/org/jruby/rack/embed/Config.java
@@ -44,7 +44,6 @@ public class Config implements RackConfig {
private RackLogger logger;
private Map rubyENV;
- private CompatVersion compatVersion;
public Config() {
delegate = new DefaultRackConfig() {
@@ -66,7 +65,6 @@ public void doInitialize(final Ruby runtime) {
setOut( runtime.getOut() );
setErr( runtime.getErr() );
rubyENV = runtime.getENV();
- compatVersion = runtime.getInstanceConfig().getCompatVersion();
}
@@ -106,9 +104,15 @@ public final Number getNumberProperty(String key, Number defaultValue) {
return delegate.getNumberProperty(key, defaultValue);
}
+ /**
+ * @return Always CompatVersion.RUBY2_1, consistent with JRuby 9.3+
+ *
+ * @deprecated Since jruby-rack 1.2 (and JRuby 9.2), for removal in 1.3.0
+ */
+ @Deprecated
@Override
public CompatVersion getCompatVersion() {
- return compatVersion;
+ return CompatVersion.RUBY2_1;
}
@Override
diff --git a/src/spec/ruby/jruby/rack/error_app_spec.rb b/src/spec/ruby/jruby/rack/error_app_spec.rb
index 4fa91d9a2..65302d959 100644
--- a/src/spec/ruby/jruby/rack/error_app_spec.rb
+++ b/src/spec/ruby/jruby/rack/error_app_spec.rb
@@ -165,7 +165,7 @@ def in_tmpdir_with_files(files = {})
end
yield path
ensure
- FileUtils.rm_rf(path) if path && File.exists?(path)
+ FileUtils.rm_rf(path) if path && File.exist?(path)
end
end
diff --git a/src/spec/ruby/jruby/rack/integration_spec.rb b/src/spec/ruby/jruby/rack/integration_spec.rb
index 6ed0802d5..44858bfb4 100644
--- a/src/spec/ruby/jruby/rack/integration_spec.rb
+++ b/src/spec/ruby/jruby/rack/integration_spec.rb
@@ -19,8 +19,6 @@
before do
@servlet_context = org.jruby.rack.mock.RackLoggingMockServletContext.new "file://#{STUB_DIR}/rack"
@servlet_context.logger = raise_logger
- # make sure we always boot runtimes in the same mode as specs :
- set_compat_version @servlet_context
end
it "initializes" do
@@ -221,6 +219,10 @@
it_should_behave_like 'a rails app'
end
+ describe 'rails 8.0', lib: :rails80 do
+ it_should_behave_like 'a rails app'
+ end
+
def expect_to_have_monkey_patched_chunked
@runtime.evalScriptlet "require 'rack/chunked'"
script = %{
@@ -260,16 +262,10 @@ def new_servlet_context(base_path = nil)
end
def prepare_servlet_context(servlet_context, base_path)
- set_compat_version servlet_context
servlet_context.addInitParameter('rails.root', base_path)
servlet_context.addInitParameter('jruby.rack.layout_class', 'FileSystemLayout')
end
- def set_compat_version(servlet_context = @servlet_context); require 'jruby'
- compat_version = JRuby.runtime.getInstanceConfig.getCompatVersion # RUBY1_9
- servlet_context.addInitParameter("jruby.compat.version", compat_version.to_s)
- end
-
GEMFILES_DIR = File.expand_path('../../../gemfiles', STUB_DIR)
def copy_gemfile
diff --git a/src/spec/ruby/rack/application_spec.rb b/src/spec/ruby/rack/application_spec.rb
index c571fc79d..3d9852198 100644
--- a/src/spec/ruby/rack/application_spec.rb
+++ b/src/spec/ruby/rack/application_spec.rb
@@ -393,13 +393,6 @@ def newRuntime()
should_eval_as_eql_to "require 'yaml'", true # -ryaml not processed
end
- it "handles jruby.compat.version == '1.9' and starts in 1.9 mode" do
- set_config 'jruby.compat.version', '1.9'
- #@rack_config.stub(:getCompatVersion).and_return org.jruby.CompatVersion::RUBY1_9
- @runtime = app_factory.new_runtime
- expect(@runtime.is1_9).to be_truthy
- end
-
it "handles jruby.runtime.arguments == '-X+O -Ke' and start with object space enabled and KCode EUC" do
set_config 'jruby.runtime.arguments', '-X+O -Ke'
# allow(@rack_config).to receive(:getRuntimeArguments).and_return ['-X+O', '-Ke'].to_java(:String)
diff --git a/src/spec/ruby/rack/config_spec.rb b/src/spec/ruby/rack/config_spec.rb
index 37daa4909..92415a9ff 100644
--- a/src/spec/ruby/rack/config_spec.rb
+++ b/src/spec/ruby/rack/config_spec.rb
@@ -184,56 +184,10 @@ def expect_empty_env(env)
end
- it "sets compat version from init parameter" do
- expect(@servlet_context).to receive(:getInitParameter).with("jruby.compat.version").
- and_return "RUBY1_9"
- expect( config.getCompatVersion ).to be org.jruby.CompatVersion::RUBY1_9
- end
-
- it "sets compat version from init parameter (dot syntax)" do
- expect(@servlet_context).to receive(:getInitParameter).with("jruby.compat.version").
- and_return "1.8"
- expect( config.getCompatVersion ).to be org.jruby.CompatVersion::RUBY1_8
- end
-
- it "leaves compat version nil if not specified" do
- expect(@servlet_context).to receive(:getInitParameter).with("jruby.compat.version").
- and_return nil
+ it "always returns nil compat version (backwards compat)" do
expect( config.getCompatVersion ).to be nil
end
- it "leaves compat version nil if invalid value specified" do
- expect(@servlet_context).to receive(:getInitParameter).with("jruby.compat.version").
- and_return "4.2"
- expect( config.getCompatVersion ).to be nil
- end
-
- it "sets compat version from init parameter (head-syntax)" do
- expect(@servlet_context).to receive(:getInitParameter).with("jruby.compat.version").
- and_return "1.9.3-SNAPSHOT"
- expect( config.getCompatVersion ).to be org.jruby.CompatVersion::RUBY1_9
- end
-
- if JRUBY_VERSION >= '1.7.0'
- it "sets compat version 2.0 from init parameter" do
- expect(@servlet_context).to receive(:getInitParameter).with("jruby.compat.version").
- and_return "RUBY2_0"
- expect( config.getCompatVersion ).to be org.jruby.CompatVersion::RUBY2_0
- end
-
- it "sets compat version 2.0 from init parameter (dot syntax)" do
- expect(@servlet_context).to receive(:getInitParameter).with("jruby.compat.version").
- and_return "2_0"
- expect( config.getCompatVersion ).to be org.jruby.CompatVersion::RUBY2_0
- end
-
- it "sets compat version 2.0 from init parameter (head-syntax)" do
- expect(@servlet_context).to receive(:getInitParameter).with("jruby.compat.version").
- and_return "2.0.0.dev"
- expect( config.getCompatVersion ).to be org.jruby.CompatVersion::RUBY2_0
- end
- end
-
describe "custom-properties" do
it "parser an int property" do
diff --git a/src/spec/ruby/rack/embed/config_spec.rb b/src/spec/ruby/rack/embed/config_spec.rb
index 657443297..22cb41367 100644
--- a/src/spec/ruby/rack/embed/config_spec.rb
+++ b/src/spec/ruby/rack/embed/config_spec.rb
@@ -58,10 +58,8 @@
end
end
- it "sets compat version from runtime" do
- require 'jruby'
- compat_version = JRuby.runtime.instance_config.compat_version
- expect( @config.compat_version ).to eql compat_version
+ it "always returns default runtime compat version (backwards compat)" do
+ expect( @config.compat_version ).to eql Java::OrgJRuby::CompatVersion::RUBY2_1
end
it "sets out/err streams from runtime" do
diff --git a/src/spec/stub/rails80/app/controllers/application_controller.rb b/src/spec/stub/rails80/app/controllers/application_controller.rb
new file mode 100644
index 000000000..0d95db22b
--- /dev/null
+++ b/src/spec/stub/rails80/app/controllers/application_controller.rb
@@ -0,0 +1,4 @@
+class ApplicationController < ActionController::Base
+ # Only allow modern browsers supporting webp images, web push, badges, import maps, CSS nesting, and CSS :has.
+ allow_browser versions: :modern
+end
diff --git a/src/spec/stub/rails80/app/helpers/application_helper.rb b/src/spec/stub/rails80/app/helpers/application_helper.rb
new file mode 100644
index 000000000..de6be7945
--- /dev/null
+++ b/src/spec/stub/rails80/app/helpers/application_helper.rb
@@ -0,0 +1,2 @@
+module ApplicationHelper
+end
diff --git a/src/spec/stub/rails80/config/application.rb b/src/spec/stub/rails80/config/application.rb
new file mode 100644
index 000000000..5c934c8ab
--- /dev/null
+++ b/src/spec/stub/rails80/config/application.rb
@@ -0,0 +1,42 @@
+require_relative "boot"
+
+require "rails"
+# Pick the frameworks you want:
+require "active_model/railtie"
+# require "active_job/railtie"
+# require "active_record/railtie"
+# require "active_storage/engine"
+require "action_controller/railtie"
+# require "action_mailer/railtie"
+# require "action_mailbox/engine"
+# require "action_text/engine"
+require "action_view/railtie"
+# require "action_cable/engine"
+# require "rails/test_unit/railtie"
+
+# Require the gems listed in Gemfile, including any gems
+# you've limited to :test, :development, or :production.
+Bundler.require(*Rails.groups)
+
+module Rails80
+ class Application < Rails::Application
+ # Initialize configuration defaults for originally generated Rails version.
+ config.load_defaults 8.0
+
+ # Please, add to the `ignore` list any other `lib` subdirectories that do
+ # not contain `.rb` files, or that should not be reloaded or eager loaded.
+ # Common ones are `templates`, `generators`, or `middleware`, for example.
+ config.autoload_lib(ignore: %w[assets tasks])
+
+ # Configuration for the application, engines, and railties goes here.
+ #
+ # These settings can be overridden in specific environments using the files
+ # in config/environments, which are processed later.
+ #
+ # config.time_zone = "Central Time (US & Canada)"
+ # config.eager_load_paths << Rails.root.join("extras")
+
+ # Don't generate system test files.
+ config.generators.system_tests = nil
+ end
+end
diff --git a/src/spec/stub/rails80/config/boot.rb b/src/spec/stub/rails80/config/boot.rb
new file mode 100644
index 000000000..282011619
--- /dev/null
+++ b/src/spec/stub/rails80/config/boot.rb
@@ -0,0 +1,3 @@
+ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
+
+require "bundler/setup" # Set up gems listed in the Gemfile.
diff --git a/src/spec/stub/rails80/config/credentials.yml.enc b/src/spec/stub/rails80/config/credentials.yml.enc
new file mode 100644
index 000000000..52f451f19
--- /dev/null
+++ b/src/spec/stub/rails80/config/credentials.yml.enc
@@ -0,0 +1 @@
+NCPB0BoQmoDBGNi6wTV45XD6wglzlWKz9UaJ+0/a4ByWCTVIwQ0TU7sBgXAqugWW122abcrrVuicT4K3/f3N4rGXSK7ub5ThDpY0q/+9NQrc1uYTLN5W8lAVjrO1mtk1uskK47hc8gvBXKRhOrxV1IGJazzXBgY2GA3fh6FtdUKMlKrUcq9TmmbGffCUOfqf1dD5KwDVPuwuavzFDbK32P3/Dvvjgh8FnfLms2QZo+WKp7/TtRxChonWkq/+AA/tKZZMFnKc4hbNA5tJfFL2NV2613UBj+nIITwxVxfFbhArKbR65S+3x5fwOVBl19TYT8SC/ITR9zOXQh/tNOJGZfEuQhKLYyIr+bbwoo0fDqvwExRiRbhg0rPccTpP+ISfE4HwAdKKi8v3MQht5J4bK3DWIx8OxPQFLaweCKZ187RH9dMkqJeMjQiUGzpcTXzJ+rkbDdRXPdpjOgsEi0+6BOHn84Tv5QTTvKwXky0bLjF8ffrfBZmThryy--pOOE0qME1o1qDga2--P86TbVCxNjPYcMsuRouaEg==
\ No newline at end of file
diff --git a/src/spec/stub/rails80/config/environment.rb b/src/spec/stub/rails80/config/environment.rb
new file mode 100644
index 000000000..cac531577
--- /dev/null
+++ b/src/spec/stub/rails80/config/environment.rb
@@ -0,0 +1,5 @@
+# Load the Rails application.
+require_relative "application"
+
+# Initialize the Rails application.
+Rails.application.initialize!
diff --git a/src/spec/stub/rails80/config/environments/development.rb b/src/spec/stub/rails80/config/environments/development.rb
new file mode 100644
index 000000000..f68dd3575
--- /dev/null
+++ b/src/spec/stub/rails80/config/environments/development.rb
@@ -0,0 +1,42 @@
+require "active_support/core_ext/integer/time"
+
+Rails.application.configure do
+ # Settings specified here will take precedence over those in config/application.rb.
+
+ # Make code changes take effect immediately without server restart.
+ config.enable_reloading = true
+
+ # Do not eager load code on boot.
+ config.eager_load = false
+
+ # Show full error reports.
+ config.consider_all_requests_local = true
+
+ # Enable server timing.
+ config.server_timing = true
+
+ # Enable/disable Action Controller caching. By default Action Controller caching is disabled.
+ # Run rails dev:cache to toggle Action Controller caching.
+ if Rails.root.join("tmp/caching-dev.txt").exist?
+ config.action_controller.perform_caching = true
+ config.action_controller.enable_fragment_cache_logging = true
+ config.public_file_server.headers = { "cache-control" => "public, max-age=#{2.days.to_i}" }
+ else
+ config.action_controller.perform_caching = false
+ end
+
+ # Change to :null_store to avoid any caching.
+ config.cache_store = :memory_store
+
+ # Print deprecation notices to the Rails logger.
+ config.active_support.deprecation = :log
+
+ # Raises error for missing translations.
+ # config.i18n.raise_on_missing_translations = true
+
+ # Annotate rendered view with file names.
+ config.action_view.annotate_rendered_view_with_filenames = true
+
+ # Raise error when a before_action's only/except options reference missing actions.
+ config.action_controller.raise_on_missing_callback_actions = true
+end
diff --git a/src/spec/stub/rails80/config/environments/production.rb b/src/spec/stub/rails80/config/environments/production.rb
new file mode 100644
index 000000000..4f2cfb8f8
--- /dev/null
+++ b/src/spec/stub/rails80/config/environments/production.rb
@@ -0,0 +1,61 @@
+require "active_support/core_ext/integer/time"
+
+Rails.application.configure do
+ # Settings specified here will take precedence over those in config/application.rb.
+
+ # Code is not reloaded between requests.
+ config.enable_reloading = false
+
+ # Eager load code on boot for better performance and memory savings (ignored by Rake tasks).
+ config.eager_load = true
+
+ # Full error reports are disabled.
+ config.consider_all_requests_local = false
+
+ # Turn on fragment caching in view templates.
+ config.action_controller.perform_caching = true
+
+ # Cache assets for far-future expiry since they are all digest stamped.
+ config.public_file_server.headers = { "cache-control" => "public, max-age=#{1.year.to_i}" }
+
+ # Enable serving of images, stylesheets, and JavaScripts from an asset server.
+ # config.asset_host = "http://assets.example.com"
+
+ # Assume all access to the app is happening through a SSL-terminating reverse proxy.
+ config.assume_ssl = true
+
+ # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
+ config.force_ssl = true
+
+ # Skip http-to-https redirect for the default health check endpoint.
+ # config.ssl_options = { redirect: { exclude: ->(request) { request.path == "/up" } } }
+
+ # Log to STDOUT with the current request id as a default log tag.
+ config.log_tags = [ :request_id ]
+ # config.logger = ActiveSupport::TaggedLogging.logger(STDOUT)
+
+ # Change to "debug" to log everything (including potentially personally-identifiable information!)
+ config.log_level = ENV.fetch("RAILS_LOG_LEVEL", "info")
+
+ # Prevent health checks from clogging up the logs.
+ config.silence_healthcheck_path = "/up"
+
+ # Don't log any deprecations.
+ config.active_support.report_deprecations = false
+
+ # Replace the default in-process memory cache store with a durable alternative.
+ # config.cache_store = :mem_cache_store
+
+ # Enable locale fallbacks for I18n (makes lookups for any locale fall back to
+ # the I18n.default_locale when a translation cannot be found).
+ config.i18n.fallbacks = true
+
+ # Enable DNS rebinding protection and other `Host` header attacks.
+ # config.hosts = [
+ # "example.com", # Allow requests from example.com
+ # /.*\.example\.com/ # Allow requests from subdomains like `www.example.com`
+ # ]
+ #
+ # Skip DNS rebinding protection for the default health check endpoint.
+ # config.host_authorization = { exclude: ->(request) { request.path == "/up" } }
+end
diff --git a/src/spec/stub/rails80/config/environments/test.rb b/src/spec/stub/rails80/config/environments/test.rb
new file mode 100644
index 000000000..14bc29e06
--- /dev/null
+++ b/src/spec/stub/rails80/config/environments/test.rb
@@ -0,0 +1,42 @@
+# The test environment is used exclusively to run your application's
+# test suite. You never need to work with it otherwise. Remember that
+# your test database is "scratch space" for the test suite and is wiped
+# and recreated between test runs. Don't rely on the data there!
+
+Rails.application.configure do
+ # Settings specified here will take precedence over those in config/application.rb.
+
+ # While tests run files are not watched, reloading is not necessary.
+ config.enable_reloading = false
+
+ # Eager loading loads your entire application. When running a single test locally,
+ # this is usually not necessary, and can slow down your test suite. However, it's
+ # recommended that you enable it in continuous integration systems to ensure eager
+ # loading is working properly before deploying your code.
+ config.eager_load = ENV["CI"].present?
+
+ # Configure public file server for tests with cache-control for performance.
+ config.public_file_server.headers = { "cache-control" => "public, max-age=3600" }
+
+ # Show full error reports.
+ config.consider_all_requests_local = true
+ config.cache_store = :null_store
+
+ # Render exception templates for rescuable exceptions and raise for other exceptions.
+ config.action_dispatch.show_exceptions = :rescuable
+
+ # Disable request forgery protection in test environment.
+ config.action_controller.allow_forgery_protection = false
+
+ # Print deprecation notices to the stderr.
+ config.active_support.deprecation = :stderr
+
+ # Raises error for missing translations.
+ # config.i18n.raise_on_missing_translations = true
+
+ # Annotate rendered view with file names.
+ # config.action_view.annotate_rendered_view_with_filenames = true
+
+ # Raise error when a before_action's only/except options reference missing actions.
+ config.action_controller.raise_on_missing_callback_actions = true
+end
diff --git a/src/spec/stub/rails80/config/initializers/content_security_policy.rb b/src/spec/stub/rails80/config/initializers/content_security_policy.rb
new file mode 100644
index 000000000..b3076b38f
--- /dev/null
+++ b/src/spec/stub/rails80/config/initializers/content_security_policy.rb
@@ -0,0 +1,25 @@
+# Be sure to restart your server when you modify this file.
+
+# Define an application-wide content security policy.
+# See the Securing Rails Applications Guide for more information:
+# https://guides.rubyonrails.org/security.html#content-security-policy-header
+
+# Rails.application.configure do
+# config.content_security_policy do |policy|
+# policy.default_src :self, :https
+# policy.font_src :self, :https, :data
+# policy.img_src :self, :https, :data
+# policy.object_src :none
+# policy.script_src :self, :https
+# policy.style_src :self, :https
+# # Specify URI for violation reports
+# # policy.report_uri "/csp-violation-report-endpoint"
+# end
+#
+# # Generate session nonces for permitted importmap, inline scripts, and inline styles.
+# config.content_security_policy_nonce_generator = ->(request) { request.session.id.to_s }
+# config.content_security_policy_nonce_directives = %w(script-src style-src)
+#
+# # Report violations without enforcing the policy.
+# # config.content_security_policy_report_only = true
+# end
diff --git a/src/spec/stub/rails80/config/initializers/filter_parameter_logging.rb b/src/spec/stub/rails80/config/initializers/filter_parameter_logging.rb
new file mode 100644
index 000000000..c0b717f7e
--- /dev/null
+++ b/src/spec/stub/rails80/config/initializers/filter_parameter_logging.rb
@@ -0,0 +1,8 @@
+# Be sure to restart your server when you modify this file.
+
+# Configure parameters to be partially matched (e.g. passw matches password) and filtered from the log file.
+# Use this to limit dissemination of sensitive information.
+# See the ActiveSupport::ParameterFilter documentation for supported notations and behaviors.
+Rails.application.config.filter_parameters += [
+ :passw, :email, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn, :cvv, :cvc
+]
diff --git a/src/spec/stub/rails80/config/initializers/inflections.rb b/src/spec/stub/rails80/config/initializers/inflections.rb
new file mode 100644
index 000000000..3860f659e
--- /dev/null
+++ b/src/spec/stub/rails80/config/initializers/inflections.rb
@@ -0,0 +1,16 @@
+# Be sure to restart your server when you modify this file.
+
+# Add new inflection rules using the following format. Inflections
+# are locale specific, and you may define rules for as many different
+# locales as you wish. All of these examples are active by default:
+# ActiveSupport::Inflector.inflections(:en) do |inflect|
+# inflect.plural /^(ox)$/i, "\\1en"
+# inflect.singular /^(ox)en/i, "\\1"
+# inflect.irregular "person", "people"
+# inflect.uncountable %w( fish sheep )
+# end
+
+# These inflection rules are supported but not enabled by default:
+# ActiveSupport::Inflector.inflections(:en) do |inflect|
+# inflect.acronym "RESTful"
+# end
diff --git a/src/spec/stub/rails80/config/locales/en.yml b/src/spec/stub/rails80/config/locales/en.yml
new file mode 100644
index 000000000..6c349ae5e
--- /dev/null
+++ b/src/spec/stub/rails80/config/locales/en.yml
@@ -0,0 +1,31 @@
+# Files in the config/locales directory are used for internationalization and
+# are automatically loaded by Rails. If you want to use locales other than
+# English, add the necessary files in this directory.
+#
+# To use the locales, use `I18n.t`:
+#
+# I18n.t "hello"
+#
+# In views, this is aliased to just `t`:
+#
+# <%= t("hello") %>
+#
+# To use a different locale, set it with `I18n.locale`:
+#
+# I18n.locale = :es
+#
+# This would use the information in config/locales/es.yml.
+#
+# To learn more about the API, please read the Rails Internationalization guide
+# at https://guides.rubyonrails.org/i18n.html.
+#
+# Be aware that YAML interprets the following case-insensitive strings as
+# booleans: `true`, `false`, `on`, `off`, `yes`, `no`. Therefore, these strings
+# must be quoted to be interpreted as strings. For example:
+#
+# en:
+# "yes": yup
+# enabled: "ON"
+
+en:
+ hello: "Hello world"
diff --git a/src/spec/stub/rails80/config/master.key b/src/spec/stub/rails80/config/master.key
new file mode 100644
index 000000000..6f3181b8a
--- /dev/null
+++ b/src/spec/stub/rails80/config/master.key
@@ -0,0 +1 @@
+84d2b16f6454c9ac885725a8974f9bfc
\ No newline at end of file
diff --git a/src/spec/stub/rails80/config/puma.rb b/src/spec/stub/rails80/config/puma.rb
new file mode 100644
index 000000000..787e4ce98
--- /dev/null
+++ b/src/spec/stub/rails80/config/puma.rb
@@ -0,0 +1,38 @@
+# This configuration file will be evaluated by Puma. The top-level methods that
+# are invoked here are part of Puma's configuration DSL. For more information
+# about methods provided by the DSL, see https://puma.io/puma/Puma/DSL.html.
+#
+# Puma starts a configurable number of processes (workers) and each process
+# serves each request in a thread from an internal thread pool.
+#
+# You can control the number of workers using ENV["WEB_CONCURRENCY"]. You
+# should only set this value when you want to run 2 or more workers. The
+# default is already 1.
+#
+# The ideal number of threads per worker depends both on how much time the
+# application spends waiting for IO operations and on how much you wish to
+# prioritize throughput over latency.
+#
+# As a rule of thumb, increasing the number of threads will increase how much
+# traffic a given process can handle (throughput), but due to CRuby's
+# Global VM Lock (GVL) it has diminishing returns and will degrade the
+# response time (latency) of the application.
+#
+# The default is set to 3 threads as it's deemed a decent compromise between
+# throughput and latency for the average Rails application.
+#
+# Any libraries that use a connection pool or another resource pool should
+# be configured to provide at least as many connections as the number of
+# threads. This includes Active Record's `pool` parameter in `database.yml`.
+threads_count = ENV.fetch("RAILS_MAX_THREADS", 3)
+threads threads_count, threads_count
+
+# Specifies the `port` that Puma will listen on to receive requests; default is 3000.
+port ENV.fetch("PORT", 3000)
+
+# Allow puma to be restarted by `bin/rails restart` command.
+plugin :tmp_restart
+
+# Specify the PID file. Defaults to tmp/pids/server.pid in development.
+# In other environments, only set the PID file if requested.
+pidfile ENV["PIDFILE"] if ENV["PIDFILE"]
diff --git a/src/spec/stub/rails80/config/routes.rb b/src/spec/stub/rails80/config/routes.rb
new file mode 100644
index 000000000..48254e88e
--- /dev/null
+++ b/src/spec/stub/rails80/config/routes.rb
@@ -0,0 +1,14 @@
+Rails.application.routes.draw do
+ # Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html
+
+ # Reveal health status on /up that returns 200 if the app boots with no exceptions, otherwise 500.
+ # Can be used by load balancers and uptime monitors to verify that the app is live.
+ get "up" => "rails/health#show", as: :rails_health_check
+
+ # Render dynamic PWA files from app/views/pwa/* (remember to link manifest in application.html.erb)
+ # get "manifest" => "rails/pwa#manifest", as: :pwa_manifest
+ # get "service-worker" => "rails/pwa#service_worker", as: :pwa_service_worker
+
+ # Defines the root path route ("/")
+ # root "posts#index"
+end
diff --git a/src/spec/stub/rails80/public/robots.txt b/src/spec/stub/rails80/public/robots.txt
new file mode 100644
index 000000000..c19f78ab6
--- /dev/null
+++ b/src/spec/stub/rails80/public/robots.txt
@@ -0,0 +1 @@
+# See https://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file