diff --git a/CHANGELOG.md b/CHANGELOG.md
index e51ecd3e9..ff9f2f81d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,18 +4,27 @@
- Refactor logging for more sane defaults
- Remove long-deprecated configuration and API functionality
-For most users this should be a minor upgrade; as long as not depending on deprecated functionality or JRuby 9.x.
+For most users this should be a minor upgrade; as long as you do not depend on functionality deprecated within
+JRuby-Rack 1.2.x, EOL JRuby or EOL Rails versions.
Breaking compatibility changes
- Drop support for JRuby 9.x (and thus Java < 21)
- Drop support for Rails < 7.2
+- Drop JMS support
Breaking behavioral changes
- Change context listener to throw by default in case of an exception during initialization
- Change rails context listener to assume a thread-safe application by default
+- Rack is no longer vendored inside the jar, so applications must ensure rack is provided via bundler or GEM_PATH
-Breaking Java API changes
-- Drop JMS support
+Breaking configuration capability changes
+- Drop `jruby.rack.jruby.version` and `jruby.rack.rack.release` keys from rack `env` Hash
+- Drop deprecated and undocumented jruby-rack 1.0 backwards compat properties `jruby.runtime.timeout.sec`, `jruby.runtime.initializer.threads`, `jruby.init.serial`, `jruby.rack.request.size.threshold.bytes`
+- Drop deprecated `jruby.rack.ignore.env` property, replaced long ago by `jruby.runtime.env` and optional `jruby.runtime.env.rubyopt`
+- Drop deprecated `jruby.rack.filter.*` properties, replaced long ago by init parameters `addsHtmlToPathInfo` and `verifiesHtmlResource`
+- Drop handling of `# rack.version` magic comments inside `config.ru` files, replaced by bundler or user-managed `GEM_PATH`
+
+Breaking Java API changes (only relevant for users extending the Java API)
- Drop unnecessary `jruby.compat.version` and `RackConfig.getCompatVersion()` API
- Drop deprecated `org.jruby.rack.RackInput` alias for `org.jruby.rack.ext.Input` class
- Drop/rename deprecated `RackConfig` and `ServletRackEnvironment` API methods per their earlier comments
@@ -23,18 +32,12 @@ Breaking Java API changes
- Custom `RackLogger` implementations must accept `CharSequence` rather than `String` to allow `RubyString` passthrough
- Rename deprecated `JRuby::Rack::ServletLog` to `JRuby::Rack::ErrorLog` for clarity, despite usage only in servlet contexts.
-Breaking Ruby API changes
+Breaking Ruby API changes (only relevant for users extending the Ruby API)
- Drop deprecated `JRuby::Rack::RailsFileSystemLayout` alias for `JRuby::Rack::FileSystemLayout`
- Drop deprecated `JRuby::Rack::Errors` alias for `JRuby::Rack::ErrorApp`
- Drop deprecated `Rack::Handler::Servlet::Env` and `Rack::Handler::Servlet::LazyEnv` types (replaced by `DefaultEnv`)
- Drop deprecated setting of global `$servlet_context` variable during embedded usage (replaced by `JRuby::Rack.context`)
-Breaking configuration capability changes
-- Drop `jruby.rack.jruby.version` and `jruby.rack.rack.release` keys from rack `env` Hash
-- Drop deprecated and undocumented jruby-rack 1.0 backwards compat properties `jruby.runtime.timeout.sec`, `jruby.runtime.initializer.threads`, `jruby.init.serial`, `jruby.rack.request.size.threshold.bytes`
-- Drop deprecated `jruby.rack.ignore.env` property, replaced long ago by `jruby.runtime.env` and optional `jruby.runtime.env.rubyopt`
-- Drop deprecated `jruby.rack.filter.*` properties, replaced long ago by init parameters `addsHtmlToPathInfo` and `verifiesHtmlResource`
-
## 1.2.8
- Improve isolation and bundler version/CLI boot issues with more opinionated boot process (#461)
diff --git a/Gemfile b/Gemfile
index 78d8d7b93..f47ca98ec 100644
--- a/Gemfile
+++ b/Gemfile
@@ -1,7 +1,7 @@
source 'https://rubygems.org'
group :default do
- if rack_version = ENV['RACK_VERSION']
+ if (rack_version = ENV['RACK_VERSION'])
gem 'rack', rack_version
else
gem 'rack', '~> 2.2.24'
diff --git a/README.md b/README.md
index b55e70015..c3e77f421 100644
--- a/README.md
+++ b/README.md
@@ -267,24 +267,10 @@ Ruby environment before booting the application. You can create a file called
These files, if found, will be evaluated before booting the Rack environment,
allowing you to set environment variables, load scripts, etc.
-For plain Rack applications, JRuby-Rack also supports a magic comment to solve
-the "rackup" chicken-egg problem (you need Rack's builder loaded before loading
-the `config.ru`, yet you may want to setup the gem version from within the rackup
- file). As we ship with the Rack gem bundled, otherwise when executing the
-provided `config.ru` the bundled (latest) version of Rack will get loaded.
-
-Use `rack.version` to specify the Rack gem version to be loaded before rackup :
-
-```ruby
-# encoding: UTF-8
-# rack.version: ~>2.2.10 (before code is loaded gem '~>2.2.10' will be called)
-```
-
-Or the equivalent of doing `bundle exec rackup ...` if you're using Bundler :
-
-```ruby
-# rack.version: bundler (require 'bundler'; Bundler.setup; before loading the script)
-```
+JRuby-Rack does not vendor Rack - the application is expected to provide it, just like
+with other Ruby web servers. For applications depending on `jruby-rack` via jar (rather than gem),
+this means having `rack` in the `Gemfile` (usually implied by the web framework);
+or available on the application's gem path.
## Logging
diff --git a/Rakefile b/Rakefile
index 3014f0de4..b298734ad 100644
--- a/Rakefile
+++ b/Rakefile
@@ -51,53 +51,18 @@ task(:test_prepare => ['target/classes', 'target/test-classes']) do
sh "./mvnw -ntp -Dstyle.color=always -Djruby.compat.artifact=jruby-complete test-compile"
end
-desc "Unpack the rack gem"
-task :unpack_gem => "target" do |t|
- target = File.expand_path(t.prerequisites.first)
- rack_gemfile = Gem.loaded_specs['rack'].cache_file
- unless uptodate?("#{target}/vendor/rack.rb", [__FILE__, rack_gemfile])
- mkdir_p "target/vendor"
- require 'rubygems/installer'
- rack_dir = File.basename(rack_gemfile).sub(/\.gem$/, '')
- Gem::Package.new(rack_gemfile).extract_files("#{target}/#{rack_dir}")
- File.open("#{target}/vendor/rack.rb", "w") do |f|
- f << "dir = File.dirname(__FILE__)\n"
- f << "if dir =~ /.jar!/ && dir !~ /^file:/\n"
- f << " $LOAD_PATH.unshift 'file:' + dir + '/#{rack_dir}'\n"
- f << "else\n"
- f << " $LOAD_PATH.unshift dir + '/#{rack_dir}'\n"
- f << "end\n"
- f << "require 'rack'"
- end
- end
-end
-GENERATED << 'target/vendor/rack.rb'
-
-desc "Generate (ruby) resources"
-task :resources => ['target/classes', :unpack_gem] do |t|
- rack_dir = File.basename(FileList["target/rack-*"].first)
- classes_dir = t.prerequisites.first
- { 'target/vendor' => "#{classes_dir}/vendor",
- "target/#{rack_dir}/lib" => "#{classes_dir}/vendor/#{rack_dir}"}.each do |src,dest|
- mkdir_p dest
- FileList["#{src}/*"].each do |f|
- cp_r f, dest
- end
- end
-end
-
task :test_resources => ["target/test-classes"]
namespace :resources do
- desc "Copy (and generate) resources"
- task :copy => :resources do
+ desc "Copy resources"
+ task :copy do
sh './mvnw -ntp process-resources -Dstyle.color=always -Dmdep.skip=true'
end
desc "Generate test resources"
task :test => :test_resources
end
-task :speconly => [ :resources, :test_resources ] do
+task :speconly => [ :test_resources ] do
if ENV['SKIP_SPECS'].to_s == 'true'
puts "Skipping specs due to SKIP_SPECS=#{ENV['SKIP_SPECS']}"
else
@@ -143,7 +108,6 @@ GENERATED << target_jruby_rack
file (target_jar = "target/jruby-rack-#{JAR_VERSION}.jar") do |file|
Rake::Task['compile'].invoke
- Rake::Task['resources'].invoke
sh "jar cf #{file.name} -C target/classes ."
end
@@ -179,6 +143,7 @@ task :gem => [:clean, target_jar, target_jruby_rack, target_jruby_rack_version]
gem.files = FileList["./**/*"].exclude("*.gem").map{ |f| f.sub(/^\.\//, '') }
gem.homepage = %q{http://jruby.org}
gem.required_ruby_version = '>= 3.4.0' # JRuby >= 10.0
+ gem.add_dependency 'rack', '~> 2.2.0'
end
require 'rubygems/package'
diff --git a/examples/README.md b/examples/README.md
index 17acdb929..4d21a5605 100644
--- a/examples/README.md
+++ b/examples/README.md
@@ -21,7 +21,7 @@ As an executable jar within Jetty:
rm -f Gemfile.lock && bundle install && bundle exec warble executable war
```
2. ```shell
- java -Dwarbler.debug=true -Dwarbler.port=8080 -jar *.war
+ java -Dwarbler.debug=true -Dwarbler.port=8989 -jar *.war
```
## Demo routes
@@ -29,21 +29,21 @@ As an executable jar within Jetty:
| Example | Component | Embedded Route | Deployed War Route |
|---------|------------------------|-------------------------------------|---------------------------------------------|
| Rails 7 | Status Page | http://localhost:8080/up | http://localhost:8080/rails7/up |
-| Rails 7 | Snoop Dump | http://localhost:8080/snoop | http://localhost:8080/rails7/snoop |
-| Rails 7 | Simple Form submission | http://localhost:8080/simple_form | http://localhost:8080/rails7/simple_form |
-| Rails 7 | Body Posts | http://localhost:8080/body | http://localhost:8080/rails7/body |
-| Rails 7 | JSP (render) | http://localhost:8080/jsp/ | http://localhost:8080/rails7/jsp/ |
-| Rails 7 | JSP (forward to) | http://localhost:8080/jsp-forward/ | http://localhost:8080/rails7/jsp-forward/ |
-| Rails 7 | JSP (include) | http://localhost:8080/jsp-include/ | http://localhost:8080/rails7/jsp-include/ |
-| Sinatra | Demo Index | http://localhost:8080/ | http://localhost:8080/sinatra |
-| Sinatra | Info | http://localhost:8080/info | http://localhost:8080/sinatra/info |
-| Sinatra | Snoop Dump | http://localhost:8080/env | http://localhost:8080/sinatra/env |
-| Sinatra | JSP (render) | http://localhost:8080/jsp/index.jsp | http://localhost:8080/sinatra/jsp/index.jsp |
-| Sinatra | JSP (forward to) | http://localhost:8080/jsp_forward | http://localhost:8080/sinatra/jsp_forward |
-| Sinatra | JSP (include) | http://localhost:8080/jsp_include | http://localhost:8080/sinatra/jsp_include |
-| Sinatra | Streaming Demo | http://localhost:8080/stream | http://localhost:8080/sinatra/stream |
-| Camping | Demo Index | http://localhost:8080/ | http://localhost:8080/camping |
-| Camping | Snoop Dump | http://localhost:8080/snoop | http://localhost:8080/camping/snoop |
+| Rails 7 | Snoop Dump | http://localhost:8989/snoop | http://localhost:8080/rails7/snoop |
+| Rails 7 | Simple Form submission | http://localhost:8989/simple_form | http://localhost:8080/rails7/simple_form |
+| Rails 7 | Body Posts | http://localhost:8989/body | http://localhost:8080/rails7/body |
+| Rails 7 | JSP (render) | http://localhost:8989/jsp/ | http://localhost:8080/rails7/jsp/ |
+| Rails 7 | JSP (forward to) | http://localhost:8989/jsp-forward/ | http://localhost:8080/rails7/jsp-forward/ |
+| Rails 7 | JSP (include) | http://localhost:8989/jsp-include/ | http://localhost:8080/rails7/jsp-include/ |
+| Sinatra | Demo Index | http://localhost:8989/ | http://localhost:8080/sinatra |
+| Sinatra | Info | http://localhost:8989/info | http://localhost:8080/sinatra/info |
+| Sinatra | Snoop Dump | http://localhost:8989/env | http://localhost:8080/sinatra/env |
+| Sinatra | JSP (render) | http://localhost:8989/jsp/index.jsp | http://localhost:8080/sinatra/jsp/index.jsp |
+| Sinatra | JSP (forward to) | http://localhost:8989/jsp_forward | http://localhost:8080/sinatra/jsp_forward |
+| Sinatra | JSP (include) | http://localhost:8989/jsp_include | http://localhost:8080/sinatra/jsp_include |
+| Sinatra | Streaming Demo | http://localhost:8989/stream | http://localhost:8080/sinatra/stream |
+| Camping | Demo Index | http://localhost:8989/ | http://localhost:8080/camping |
+| Camping | Snoop Dump | http://localhost:8989/snoop | http://localhost:8080/camping/snoop |
## Development
diff --git a/examples/camping/Gemfile b/examples/camping/Gemfile
index 4bf2959c8..d196905b7 100644
--- a/examples/camping/Gemfile
+++ b/examples/camping/Gemfile
@@ -2,8 +2,7 @@ source 'https://rubygems.org'
ruby RUBY_VERSION
-gem 'camping', '< 3'
-gem 'rack', '~> 2.2.0'
+gem 'camping', '< 3' # v3 requires Rack 3.x support
group :development do
gem 'jruby-jars', JRUBY_VERSION
diff --git a/examples/rails7/Gemfile b/examples/rails7/Gemfile
index c4549f3bf..f6c1746eb 100644
--- a/examples/rails7/Gemfile
+++ b/examples/rails7/Gemfile
@@ -4,7 +4,6 @@ ruby RUBY_VERSION
gem 'rails', '~> 7.2.0'
gem 'sprockets-rails'
-gem 'rack', '~> 2.2.0'
group :development do
gem 'jruby-jars', JRUBY_VERSION
diff --git a/examples/sinatra/Gemfile b/examples/sinatra/Gemfile
index db21fe919..f77c3478d 100644
--- a/examples/sinatra/Gemfile
+++ b/examples/sinatra/Gemfile
@@ -2,8 +2,12 @@ source 'https://rubygems.org'
ruby RUBY_VERSION
-gem 'sinatra', '< 4'
-gem 'rack', '~> 2.2.0'
+gem 'sinatra', '< 4' # v4 requires Rack 3.x support
+
+if JRUBY_VERSION.start_with?('10.1.')
+ gem 'ostruct'
+ gem 'logger'
+end
group :development do
gem 'jruby-jars', JRUBY_VERSION
diff --git a/pom.xml b/pom.xml
index 2fd3fdaf9..e60dcf063 100644
--- a/pom.xml
+++ b/pom.xml
@@ -275,16 +275,6 @@
-S rake speconly SKIP_SPECS=${skipTests}
-
-
- rake-resources
- prepare-package
-
- exec
-
- -S rake resources VERSION=${project.version}
-
-
diff --git a/src/main/java/org/jruby/rack/DefaultRackApplicationFactory.java b/src/main/java/org/jruby/rack/DefaultRackApplicationFactory.java
index 0fe0cedca..05f7619bc 100644
--- a/src/main/java/org/jruby/rack/DefaultRackApplicationFactory.java
+++ b/src/main/java/org/jruby/rack/DefaultRackApplicationFactory.java
@@ -165,7 +165,6 @@ public IRubyObject createApplicationObject(final Ruby runtime) {
rackContext.log(WARN, "no rackup script found - starting empty Rack application!");
rackupScript = "";
}
- checkAndSetRackVersion(runtime);
runtime.evalScriptlet("load 'jruby/rack/boot/rack.rb'");
return createRackServletWrapper(runtime, rackupScript, rackupLocation);
}
@@ -366,40 +365,6 @@ public void initRuntime(final Ruby runtime) {
}
}
- /**
- * Checks and sets the required Rack version (if specified as a magic comment).
- *
- * e.g. # rack.version: =2.2.0
- *
- * @apiNote Internal API, only visible due tests.
- *
- * @param runtime the JRuby runtime
- * @return the rack version requirement
- */
- public String checkAndSetRackVersion(final Ruby runtime) {
- String rackVersion = null;
- try {
- rackVersion = IOHelpers.rubyMagicCommentValue(rackupScript, "rack.version:");
- }
- catch (Exception e) {
- rackContext.log(DEBUG, "could not read 'rack.version' magic comment from rackup", e);
- }
-
- if ( rackVersion != null ) {
- runtime.evalScriptlet("require 'rubygems'");
-
- if ( rackVersion.equalsIgnoreCase("bundler") ) {
- runtime.evalScriptlet("require 'bundler'; Bundler.setup");
- }
- else {
- rackContext.log(DEBUG, "detected 'rack.version' magic comment, " +
- "will use `gem 'rack', '"+ rackVersion +"'`");
- runtime.evalScriptlet("gem 'rack', '"+ rackVersion +"' if defined? gem");
- }
- }
- return rackVersion;
- }
-
private RackApplication createApplication(final ApplicationObjectFactory appFactory) {
return new RackApplicationImpl(appFactory);
}
diff --git a/src/main/java/org/jruby/rack/util/IOHelpers.java b/src/main/java/org/jruby/rack/util/IOHelpers.java
index 9091cb67a..4362aba0a 100644
--- a/src/main/java/org/jruby/rack/util/IOHelpers.java
+++ b/src/main/java/org/jruby/rack/util/IOHelpers.java
@@ -23,12 +23,10 @@
*/
package org.jruby.rack.util;
-import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
-import java.io.StringReader;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -67,27 +65,4 @@ public static String inputStreamToString(final InputStream stream)
return str.toString();
}
- public static String rubyMagicCommentValue(final String script, final String prefix)
- throws IOException {
- if ( script == null ) return null;
-
- final BufferedReader reader = new BufferedReader(new StringReader(script), 80);
-
- String line, comment = null; Pattern pattern = null;
- while ( (line = reader.readLine()) != null ) {
- // we only support (magic) comments at the beginning :
- if (line.isEmpty() || line.charAt(0) != '#' ) break;
-
- if (pattern == null) {
- pattern = Pattern.compile(prefix + "\\s*(\\S+)");
- }
- Matcher matcher = pattern.matcher(line);
- if (matcher.find()) {
- comment = matcher.group(1); break;
- }
- }
- reader.close();
- return comment;
- }
-
}
\ No newline at end of file
diff --git a/src/main/ruby/jruby/rack.rb b/src/main/ruby/jruby/rack.rb
index 445b41f18..d65077cfb 100644
--- a/src/main/ruby/jruby/rack.rb
+++ b/src/main/ruby/jruby/rack.rb
@@ -60,6 +60,6 @@ def logger=(logger); @@logger = logger end
require 'jruby/rack/servlet_ext'
require 'jruby/rack/core_ext'
-# loading Rack is delayed to allow the application to boot it's desired Rack
-# version (if it needs one) e.g. in a Rails application until Bundler setups
+# loading Rack is delayed until the booter has run `Bundler.setup` (for a
+# bundled application), so that the application's lockfile decides the version
JRuby::Rack::Booter.on_boot { require 'jruby/rack/rack_ext' }
diff --git a/src/main/ruby/jruby/rack/booter.rb b/src/main/ruby/jruby/rack/booter.rb
index 9b2aececa..ebe1bfbc1 100644
--- a/src/main/ruby/jruby/rack/booter.rb
+++ b/src/main/ruby/jruby/rack/booter.rb
@@ -91,6 +91,7 @@ def boot!
export_global_settings
load_settings_from_init_rb
prepare_bundler_env
+ prepare_bundler
set_relative_url_root
run_boot_hooks
self
@@ -199,6 +200,19 @@ def prepare_bundler_env
ENV['BUNDLE_FROZEN'] ||= 'true' if File.exist?("#{ENV['BUNDLE_GEMFILE']}.lock")
end
+ # Boots Bundler (`Bundler.setup`) up-front for a bundled application, so that gems required during the boot - Rack
+ # in particular - resolve per the application's lockfile, instead of rubygems activating the newest version found
+ # on the gem path. The application's own `Bundler.setup` (e.g. from *config.ru*) then becomes a no-op.
+ def prepare_bundler
+ boot_bundler! if ENV['BUNDLE_GEMFILE'] # not a bundled application
+ end
+
+ def boot_bundler!
+ require 'bundler'
+ # pre-boot bundler with groups respecting BUNDLE_WITHOUT from the environment
+ Bundler.ui.silence { Bundler.setup }
+ end
+
def relative_url_root(init_param = 'rack.relative_url_append')
relative_url_root = @rack_context.getContextPath || ''
if relative_url_append = @rack_context.getInitParameter(init_param)
diff --git a/src/main/ruby/jruby/rack/rack_ext.rb b/src/main/ruby/jruby/rack/rack_ext.rb
index 79c531944..4ba177249 100644
--- a/src/main/ruby/jruby/rack/rack_ext.rb
+++ b/src/main/ruby/jruby/rack/rack_ext.rb
@@ -7,8 +7,9 @@
begin
require 'rack'
-rescue LoadError
- require 'vendor/rack'
+rescue LoadError => e
+ raise LoadError, "#{e.message}\nJRuby-Rack no longer vendors Rack - make sure the rack gem is " \
+ "available to the application (e.g. add it to the Gemfile or install it into the gem path)"
end unless defined?(::Rack::RELEASE)
# Servlet API friendly extensions to Rack
diff --git a/src/main/ruby/jruby/rack/rails_booter.rb b/src/main/ruby/jruby/rack/rails_booter.rb
index b04e7e042..32ab26c47 100644
--- a/src/main/ruby/jruby/rack/rails_booter.rb
+++ b/src/main/ruby/jruby/rack/rails_booter.rb
@@ -38,9 +38,7 @@ def to_app
# Loads the Rails environment (*config/environment.rb*).
def load_environment
- user_boot = expand_path('config/boot.rb')
- prepare_bundler(user_boot)
- require user_boot
+ require rails_boot_path
require 'jruby/rack/rails/railtie'
require expand_path('config/environment.rb')
require 'jruby/rack/rails/extensions'
@@ -48,45 +46,46 @@ def load_environment
protected
+ # For a Rails booter bundler setup is delayed to be run during the (Rails) environment load so we can
+ # determine whether Rails requires opinionated bundler pre-boot.
+ # @see JRuby::Rack::RailsBooter#load_environment
+ # @see #rails_boot_path
+ def prepare_bundler
+ # no-op, deferred
+ end
+
def set_relative_url_root
if rails_relative_url_root = relative_url_root('rails.relative_url_append')
ENV['RAILS_RELATIVE_URL_ROOT'] = rails_relative_url_root
end
end
- # no rack etc extensions required here (called during boot!)
- # require 'jruby/rack/rails/extensions' on #load_environment
+ def rails_boot_path
+ user_boot = expand_path('config/boot.rb')
+ # pre-boot bundler if the user boot.rb appears to be using CLI/default bundler setup
+ boot_bundler! if default_rails_bundler_boot?(user_boot)
+ user_boot
+ end
- # For a Rails booter the boot hooks are delayed to be run after the
- # (Rails) environment gets loaded.
- # @see JRuby::Rack::Railtie
+ # For a Rails booter the boot hooks are delayed to be run after the (Rails) environment gets loaded, before
+ # extensions.
+ # @see JRuby::Rack::RailsBooter#load_environment / jruby/rack/rails/extensions
# @see JRuby::Rack::Booter#run_boot_hooks
+ # @see JRuby::Rack::Railtie#
def run_boot_hooks
- # no-op hooks run when 'jruby/rack/rails/extensions' gets loaded
+ # no-op, deferred
end
private
- # For a default (unmodified) Rails *config/boot.rb*, runs `Bundler.setup` up-front. `bundler/setup` can swallow setup
- # errors and end up calling `exit` when it believes stdout is a tty (which is frequently mis-detected under a servlet
- # container); pre-booting makes failures raise instead, so the container logs the actual error.
- def prepare_bundler(boot_rb_path)
+ def default_rails_bundler_boot?(boot_rb_path)
return unless ENV['BUNDLE_GEMFILE'] # not a bundled application
-
- if rails_has_default_bundler_boot?(boot_rb_path)
- # pre-boot bundler with groups respecting BUNDLE_WITHOUT from the environment
- require 'bundler'
- Bundler.ui.silence { Bundler.setup }
- end
- end
-
- def rails_has_default_bundler_boot?(boot_rb_path)
boot_rb_content = File.read(boot_rb_path) if File.readable?(boot_rb_path)
- return false unless boot_rb_content
# Assume default if there is a `require 'bundler/setup'` and no custom Bundler management e.g
# explicit `Bundler.setup(...)` call or `BUNDLE_WITHOUT` hardcoded.
- %r{^\s*require\s+["']bundler/setup["']} =~ boot_rb_content &&
+ boot_rb_content &&
+ %r{^\s*require\s+["']bundler/setup["']} =~ boot_rb_content &&
%r{Bundler\.setup} !~ boot_rb_content &&
%r{BUNDLE_WITHOUT} !~ boot_rb_content
end
@@ -105,7 +104,7 @@ def to_app; rails_booter.to_app end
# @private
def rails_booter
- raise "no booter set" unless booter = JRuby::Rack.booter
+ raise "no booter set" unless (booter = JRuby::Rack.booter)
raise "not a rails booter" unless booter.is_a?(JRuby::Rack::RailsBooter)
booter
end
diff --git a/src/spec/ruby/jruby/rack/booter_spec.rb b/src/spec/ruby/jruby/rack/booter_spec.rb
index 9cebdb910..86afe2e74 100644
--- a/src/spec/ruby/jruby/rack/booter_spec.rb
+++ b/src/spec/ruby/jruby/rack/booter_spec.rb
@@ -423,4 +423,41 @@ def boot_app(gemfile = "source 'https://rubygems.org'\n", lockfile = "GEM\n")
end
+ describe "#prepare_bundler" do
+ require 'tmpdir'; require 'fileutils'
+
+ before :each do
+ @original_pwd = Dir.pwd
+ @original_bundle_env = {}
+ %w(BUNDLE_GEMFILE BUNDLE_VERSION BUNDLE_FROZEN).each { |k| @original_bundle_env[k] = ENV.delete(k) }
+ require 'bundler'
+ end
+
+ after :each do
+ Dir.chdir(@original_pwd)
+ @original_bundle_env.each { |k, v| v.nil? ? ENV.delete(k) : ENV[k] = v }
+ FileUtils.rm_rf @app_dir if @app_dir
+ end
+
+ def boot_app(gemfile = "source 'https://rubygems.org'\n")
+ @app_dir = File.realpath(Dir.mktmpdir('rack-app')) # macOS: /var -> /private/var
+ File.write(File.join(@app_dir, 'Gemfile'), gemfile) if gemfile
+ booter.layout_class = JRuby::Rack::FileSystemLayout
+ booter.app_path = @app_dir
+ booter.boot!
+ end
+
+ it "boots Bundler up-front for a bundled application (so Rack resolves per the lockfile)" do
+ allow(Bundler.ui).to receive(:silence).and_yield
+ expect(Bundler).to receive(:setup)
+ boot_app
+ end
+
+ it "does not boot Bundler for a non-bundled application (no Gemfile)" do
+ expect(Bundler).to_not receive(:setup)
+ boot_app nil
+ end
+
+ end
+
end
diff --git a/src/spec/ruby/jruby/rack/rails_booter_spec.rb b/src/spec/ruby/jruby/rack/rails_booter_spec.rb
index 171074d9d..2b03b3613 100644
--- a/src/spec/ruby/jruby/rack/rails_booter_spec.rb
+++ b/src/spec/ruby/jruby/rack/rails_booter_spec.rb
@@ -132,39 +132,35 @@ def booted_with_boot_rb(boot_rb, gemfile = "source 'https://rubygems.org'\n")
booter
end
- def prepare_bundler!(booted)
- booted.send :prepare_bundler, File.join(@app_dir, 'config', 'boot.rb')
- end
-
it "pre-boots bundler for a default rails boot.rb" do
booted = booted_with_boot_rb DEFAULT_RAILS_BOOT_RB
allow(Bundler.ui).to receive(:silence).and_yield
expect(Bundler).to receive(:setup)
- prepare_bundler! booted
+ booted.send :rails_boot_path
end
it "does not pre-boot when boot.rb manages BUNDLE_WITHOUT itself" do
booted = booted_with_boot_rb %Q{ENV['BUNDLE_WITHOUT'] = 'test'\nrequire "bundler/setup"\n}
expect(Bundler).to_not receive(:setup)
- prepare_bundler! booted
+ booted.send :rails_boot_path
end
it "does not pre-boot when boot.rb ever calls Bundler.setup itself" do
booted = booted_with_boot_rb %Q{if ENV['BOOT_ALL']\n require "bundler/setup"\nelse\n require "bundler"\n Bundler.setup(:default)\nend\n}
expect(Bundler).to_not receive(:setup)
- prepare_bundler! booted
+ booted.send :rails_boot_path
end
it "does not pre-boot when the require is commented out" do
booted = booted_with_boot_rb %Q{# require "bundler/setup"\n}
expect(Bundler).to_not receive(:setup)
- prepare_bundler! booted
+ booted.send :rails_boot_path
end
it "does not pre-boot a non-bundled application (no Gemfile)" do
booted = booted_with_boot_rb DEFAULT_RAILS_BOOT_RB, nil
expect(Bundler).to_not receive(:setup)
- prepare_bundler! booted
+ booted.send :rails_boot_path
end
end
diff --git a/src/spec/ruby/rack/application_spec.rb b/src/spec/ruby/rack/application_spec.rb
index b8b031f07..183651092 100644
--- a/src/spec/ruby/rack/application_spec.rb
+++ b/src/spec/ruby/rack/application_spec.rb
@@ -2,8 +2,6 @@
describe org.jruby.rack.DefaultRackApplication, "call" do
- before(:all) { require 'tempfile' }
-
before :each do
@rack_env = org.jruby.rack.RackEnvironment.impl do |name, *args|
case name.to_s
@@ -310,31 +308,6 @@ def newRuntime()
should_eval_as_nil "defined?(::Rack::RELEASE)"
end
- it "loads specified version of rack via bundler", :lib => :stub do
- gem_install_unless_installed 'rack', '2.2.0'
- set_config 'jruby.runtime.env', 'false'
-
- script = "# encoding: UTF-8\n" +
- "# rack.version: bundler \n" +
- "Proc.new { 'proc-rack-app' }"
- app_factory.setRackupScript script
- @runtime = app_factory.newRuntime
-
- file = Tempfile.new('Gemfile')
- file << "source 'https://rubygems.org'\n gem 'rack', '2.2.0'"
- file.flush
- @runtime.evalScriptlet "ENV['BUNDLE_GEMFILE'] = #{file.path.inspect}"
- @runtime.evalScriptlet "ENV['GEM_HOME'] = #{ENV['GEM_HOME'].inspect}"
- @runtime.evalScriptlet "ENV['GEM_PATH'] = #{ENV['GEM_PATH'].inspect}"
-
- app_factory.checkAndSetRackVersion(@runtime)
- @runtime.evalScriptlet "require 'rack'"
-
- should_eval_as_not_nil "defined?(Bundler)"
- should_eval_as_eql_to "Rack.release", '2.2.0'
- should_eval_as_eql_to "Gem.loaded_specs['rack'].version.to_s", '2.2.0'
- end
-
it "initializes the $servlet_context global variable" do
@runtime = app_factory.new_runtime
expect(@runtime.evalScriptlet("defined?($servlet_context)")).to be_truthy
diff --git a/src/spec/ruby/rack/util_spec.rb b/src/spec/ruby/rack/util_spec.rb
index b239cfaa8..e93f2ecab 100644
--- a/src/spec/ruby/rack/util_spec.rb
+++ b/src/spec/ruby/rack/util_spec.rb
@@ -20,27 +20,4 @@
expect(string).to eql "# comment\nputs 'vůl or kôň';\nexit(0)\n"
end
- it "reads magic comment 1" do
- code = "# hello: world \n" +
- "# comment\n" +
- "exit(0);"
- string = IOHelpers.rubyMagicCommentValue(code, "hello:")
- expect(string).to eql "world"
- end
-
- it "reads magic comment 2" do
- code = "# encoding: UTF-8 \n" +
- "# comment\n" +
- "# rack.version: 2.2.0 \n" +
- "exit(0)\n'42'"
- string = IOHelpers.rubyMagicCommentValue(code, "rack.version:")
- expect(string).to eql "2.2.0"
- end
-
- it "works when reading an empty/null string" do
- expect(IOHelpers.rubyMagicCommentValue(nil, 'ruby.version:')).to be nil
- expect(IOHelpers.rubyMagicCommentValue('', 'ruby.version:')).to be nil
- expect(IOHelpers.rubyMagicCommentValue("\n", 'ruby.version:')).to be nil
- end
-
end
\ No newline at end of file
diff --git a/src/spec/ruby/spec_helper.rb b/src/spec/ruby/spec_helper.rb
index c3aa7fe38..6a72e618e 100644
--- a/src/spec/ruby/spec_helper.rb
+++ b/src/spec/ruby/spec_helper.rb
@@ -59,12 +59,6 @@ def raise_logger(level = 'WARN')
org.jruby.rack.logging.RaiseLogger.new(level, JRuby.runtime.out)
end
- def gem_install_unless_installed(name, version)
- require 'rubygems/dependency_installer'
- installer = Gem::DependencyInstaller.new
- installer.install name, version
- end
-
ExpectationNotMetError = RSpec::Expectations::ExpectationNotMetError
def expect_eql_java_bytes(actual, expected)