From d5ee2364f01b3ef4a4740e4a4d3005051e122356 Mon Sep 17 00:00:00 2001
From: Benoit Daloze <eregontp@gmail.com>
Date: Fri, 29 Jul 2022 18:10:31 +0200
Subject: [PATCH] Ensure Bundler 2.2+ is used for all Rubies which support
 Bundler 2 (Ruby >= 2.3)

---
 README.md                        |  4 ++--
 action.yml                       |  4 ++--
 bundler.js                       | 13 +++++--------
 common.js                        | 12 ++++++++++++
 dist/index.js                    | 26 ++++++++++++++++++--------
 gemfiles/gem_from_github.gemfile |  4 ++++
 6 files changed, 43 insertions(+), 20 deletions(-)

diff --git a/README.md b/README.md
index 3af7db3f2..ae0dabaef 100644
--- a/README.md
+++ b/README.md
@@ -159,8 +159,8 @@ By default, Bundler is installed as follows:
 
 * If there is a `Gemfile.lock` file (or `$BUNDLE_GEMFILE.lock` or `gems.locked`) with a `BUNDLED WITH` section,
   that version of Bundler will be installed and used.
-* If the Ruby ships with Bundler (as a default gem), that version is used.
-* Otherwise, the latest compatible Bundler version is installed (Bundler 2 on Ruby >= 2.4, Bundler 1 on Ruby < 2.4).
+* If the Ruby ships with Bundler 2.2+ (as a default gem), that version is used.
+* Otherwise, the latest compatible Bundler version is installed (Bundler 2 on Ruby >= 2.3, Bundler 1 on Ruby < 2.3).
 
 This behavior can be customized, see [action.yml](action.yml) for more details about the `bundler` input.
 
diff --git a/action.yml b/action.yml
index c5ade6091..9328b12c2 100644
--- a/action.yml
+++ b/action.yml
@@ -18,8 +18,8 @@ inputs:
     description: |
       The version of Bundler to install. Either 'Gemfile.lock' (the default), 'default', 'latest', 'none', or a version number (e.g., 1, 2, 2.1, 2.1.4).
       For 'Gemfile.lock', the version of the BUNDLED WITH section from the Gemfile.lock if it exists. If the file or section does not exist then the same as 'default'.
-      For 'default', the version of Bundler that comes with that Ruby by default is used, or if that Ruby comes without Bundler then the same as 'latest'.
-      For 'latest', the latest compatible Bundler version is installed (Bundler 2 on Ruby >= 2.4, Bundler 1 on Ruby < 2.4).
+      For 'default', if the Ruby ships with Bundler 2.2+ as a default gem, that version is used, otherwise the same as 'latest'.
+      For 'latest', the latest compatible Bundler version is installed (Bundler 2 on Ruby >= 2.3, Bundler 1 on Ruby < 2.3).
       For 'none', nothing is done.
   bundler-cache:
     description: 'Run "bundle install", and cache the result automatically. Either true or false.'
diff --git a/bundler.js b/bundler.js
index 03709f3d8..71e8f25bf 100644
--- a/bundler.js
+++ b/bundler.js
@@ -71,18 +71,15 @@ export async function installBundler(bundlerVersionInput, rubygemsInputSet, lock
   const floatVersion = common.floatVersion(rubyVersion)
 
   if (bundlerVersion === 'default') {
-    if (engine === 'ruby' && floatVersion < 3.0 && common.hasBundlerDefaultGem(engine, rubyVersion)) {
-      // Ruby 2.6 and 2.7 have a old Bundler default gem which does not work well for `gem 'foo', github: 'foo/foo'`:
+    if (common.isBundler2dot2Default(engine, rubyVersion)) {
+      console.log(`Using Bundler 2 shipped with ${engine}-${rubyVersion}`)
+      return '2'
+    } else if (common.hasBundlerDefaultGem(engine, rubyVersion)) {
+      // Those Rubies have a old Bundler default gem < 2.2 which does not work well for `gem 'foo', github: 'foo/foo'`:
       // https://github.com/ruby/setup-ruby/issues/358#issuecomment-1195899304
       // Also, Ruby 2.6 would get Bundler 1 yet Ruby 2.3 - 2.5 get latest Bundler 2 which might be unexpected.
       console.log(`Using latest Bundler for ${engine}-${rubyVersion} because the default Bundler gem is too old for that Ruby version`)
       bundlerVersion = 'latest'
-    } else if (common.isBundler2Default(engine, rubyVersion)) {
-      console.log(`Using Bundler 2 shipped with ${engine}-${rubyVersion}`)
-      return '2'
-    } else if (common.isBundler1Default(engine, rubyVersion)) {
-      console.log(`Using Bundler 1 shipped with ${engine}-${rubyVersion}`)
-      return '1'
     } else {
       bundlerVersion = 'latest'
     }
diff --git a/common.js b/common.js
index 9dd90f145..c575f8c0d 100644
--- a/common.js
+++ b/common.js
@@ -83,6 +83,18 @@ export function isBundler2Default(engine, rubyVersion) {
   }
 }
 
+export function isBundler2dot2Default(engine, rubyVersion) {
+  if (engine === 'ruby') {
+    return floatVersion(rubyVersion) >= 3.0
+  } else if (engine.startsWith('truffleruby')) {
+    return floatVersion(rubyVersion) >= 22.0
+  } else if (engine === 'jruby') {
+    return floatVersion(rubyVersion) >= 9.3
+  } else {
+    return false
+  }
+}
+
 export function floatVersion(rubyVersion) {
   const match = rubyVersion.match(/^\d+\.\d+/)
   if (match) {
diff --git a/dist/index.js b/dist/index.js
index e16c42baa..58d36e1f9 100644
--- a/dist/index.js
+++ b/dist/index.js
@@ -85,18 +85,15 @@ async function installBundler(bundlerVersionInput, rubygemsInputSet, lockFile, p
   const floatVersion = common.floatVersion(rubyVersion)
 
   if (bundlerVersion === 'default') {
-    if (engine === 'ruby' && floatVersion < 3.0 && common.hasBundlerDefaultGem(engine, rubyVersion)) {
-      // Ruby 2.6 and 2.7 have a old Bundler default gem which does not work well for `gem 'foo', github: 'foo/foo'`:
+    if (common.isBundler2dot2Default(engine, rubyVersion)) {
+      console.log(`Using Bundler 2 shipped with ${engine}-${rubyVersion}`)
+      return '2'
+    } else if (common.hasBundlerDefaultGem(engine, rubyVersion)) {
+      // Those Rubies have a old Bundler default gem < 2.2 which does not work well for `gem 'foo', github: 'foo/foo'`:
       // https://github.com/ruby/setup-ruby/issues/358#issuecomment-1195899304
       // Also, Ruby 2.6 would get Bundler 1 yet Ruby 2.3 - 2.5 get latest Bundler 2 which might be unexpected.
       console.log(`Using latest Bundler for ${engine}-${rubyVersion} because the default Bundler gem is too old for that Ruby version`)
       bundlerVersion = 'latest'
-    } else if (common.isBundler2Default(engine, rubyVersion)) {
-      console.log(`Using Bundler 2 shipped with ${engine}-${rubyVersion}`)
-      return '2'
-    } else if (common.isBundler1Default(engine, rubyVersion)) {
-      console.log(`Using Bundler 1 shipped with ${engine}-${rubyVersion}`)
-      return '1'
     } else {
       bundlerVersion = 'latest'
     }
@@ -262,6 +259,7 @@ __nccwpck_require__.r(__webpack_exports__);
 /* harmony export */   "hasBundlerDefaultGem": () => (/* binding */ hasBundlerDefaultGem),
 /* harmony export */   "isBundler1Default": () => (/* binding */ isBundler1Default),
 /* harmony export */   "isBundler2Default": () => (/* binding */ isBundler2Default),
+/* harmony export */   "isBundler2dot2Default": () => (/* binding */ isBundler2dot2Default),
 /* harmony export */   "floatVersion": () => (/* binding */ floatVersion),
 /* harmony export */   "hashFile": () => (/* binding */ hashFile),
 /* harmony export */   "supportedPlatforms": () => (/* binding */ supportedPlatforms),
@@ -357,6 +355,18 @@ function isBundler2Default(engine, rubyVersion) {
   }
 }
 
+function isBundler2dot2Default(engine, rubyVersion) {
+  if (engine === 'ruby') {
+    return floatVersion(rubyVersion) >= 3.0
+  } else if (engine.startsWith('truffleruby')) {
+    return floatVersion(rubyVersion) >= 22.0
+  } else if (engine === 'jruby') {
+    return floatVersion(rubyVersion) >= 9.3
+  } else {
+    return false
+  }
+}
+
 function floatVersion(rubyVersion) {
   const match = rubyVersion.match(/^\d+\.\d+/)
   if (match) {
diff --git a/gemfiles/gem_from_github.gemfile b/gemfiles/gem_from_github.gemfile
index 869370869..940638996 100644
--- a/gemfiles/gem_from_github.gemfile
+++ b/gemfiles/gem_from_github.gemfile
@@ -2,6 +2,10 @@ source "https://rubygems.org"
 
 # Ruby < 2.3 only support Bundler 1, which no longer works with gem github:
 if RUBY_VERSION >= '2.3'
+  unless Gem::Version.new(Bundler::VERSION) >= Gem::Version.new("2.2.0")
+    raise "Expected Bundler 2.2+ is used on Ruby >= 2.3"
+  end
+
   # From https://github.com/ruby/setup-ruby/issues/358#issuecomment-1195899304
   # Tests using github: and the repository uses a non-master default branch.
   gem 'rack-test', github: 'rack/rack-test'