diff --git a/packages/ruby/index.ts b/packages/ruby/index.ts index ffa4a25f3..2f8ce2a4a 100644 --- a/packages/ruby/index.ts +++ b/packages/ruby/index.ts @@ -47,30 +47,32 @@ async function bundleInstall( ) { debug(`running "bundle install --deployment"...`); const bundleAppConfig = await getWriteableDirectory(); + const { exitCode, stderr, stdout } = await execa( + bundlePath, + ['install', '--deployment', '--gemfile', gemfilePath, '--path', bundleDir], + { + stdio: 'pipe', + reject: false, + env: { + ...process.env, + BUNDLE_SILENCE_ROOT_WARNING: '1', + BUNDLE_APP_CONFIG: bundleAppConfig, + BUNDLE_JOBS: '4', + }, + } + ); - try { - await execa( - bundlePath, - [ - 'install', - '--deployment', - '--gemfile', - gemfilePath, - '--path', - bundleDir, - ], - { - stdio: 'pipe', - env: { - BUNDLE_SILENCE_ROOT_WARNING: '1', - BUNDLE_APP_CONFIG: bundleAppConfig, - BUNDLE_JOBS: '4', - }, - } + if ( + exitCode === 0 || + (exitCode === 18 && stderr.includes('Gemfile specified -1')) + ) { + // Gemfile might contain "2.7.x" so install might exit with code 18 and message: + // "Your Ruby patchlevel is 0, but your Gemfile specified -1" + // See https://github.com/rubygems/bundler/blob/3f0638c6c8d340c2f2405ecb84eb3b39c433e36e/lib/bundler/errors.rb#L49 + } else { + throw new Error( + `"bundle install" failed with exit code ${exitCode}: ${stdout}\n${stderr}` ); - } catch (err) { - debug(`failed to run "bundle install --deployment"...`); - throw err; } } @@ -142,14 +144,7 @@ export async function build({ } else { // try installing. this won't work if native extesions are required. // if that's the case, gems should be vendored locally before deploying. - try { - await bundleInstall(bundlerPath, bundleDir, gemfilePath); - } catch (err) { - debug( - 'unable to build gems from Gemfile. vendor the gems locally with "bundle install --deployment" and retry.' - ); - throw err; - } + await bundleInstall(bundlerPath, bundleDir, gemfilePath); } } } else { diff --git a/packages/ruby/install-ruby.ts b/packages/ruby/install-ruby.ts index 7af1cb2ab..c5158c4d5 100644 --- a/packages/ruby/install-ruby.ts +++ b/packages/ruby/install-ruby.ts @@ -5,15 +5,13 @@ import { Meta, NodeVersion, debug, NowBuildError } from '@vercel/build-utils'; interface RubyVersion extends NodeVersion { minor: number; - patch: number; } const allOptions: RubyVersion[] = [ - { major: 2, minor: 7, patch: 0, range: '2.7.x', runtime: 'ruby2.7' }, + { major: 2, minor: 7, range: '2.7.x', runtime: 'ruby2.7' }, { major: 2, minor: 5, - patch: 0, range: '2.5.x', runtime: 'ruby2.5', discontinueDate: new Date('2021-11-30'), @@ -57,7 +55,7 @@ function getRubyPath(meta: Meta, gemfileContents: string) { if (isDiscontinued(selection)) { const latest = getLatestRubyVersion(); const intro = `Found \`Gemfile\` with discontinued Ruby version: \`${line}.\``; - const hint = `Please set \`ruby "~> ${latest.major}.${latest.minor}.${latest.patch}"\` in your \`Gemfile\` to use the latest Ruby version.`; + const hint = `Please set \`ruby "~> ${latest.range}"\` in your \`Gemfile\` to use Ruby ${latest.range}.`; throw new NowBuildError({ code: 'RUBY_DISCONTINUED_VERSION', link: 'http://vercel.link/ruby-version', diff --git a/packages/ruby/test/fixtures/02-cowsay-vendored/Gemfile b/packages/ruby/test/fixtures/02-cowsay-vendored/Gemfile index 216fd09e4..0512cb712 100644 --- a/packages/ruby/test/fixtures/02-cowsay-vendored/Gemfile +++ b/packages/ruby/test/fixtures/02-cowsay-vendored/Gemfile @@ -2,6 +2,6 @@ source "https://rubygems.org" -ruby "~> 2.7.0" +ruby "~> 2.7.x" gem "cowsay", "~> 0.3.0" diff --git a/packages/ruby/test/fixtures/04-cowsay-vendored-nested/project/Gemfile b/packages/ruby/test/fixtures/04-cowsay-vendored-nested/project/Gemfile index 216fd09e4..0512cb712 100644 --- a/packages/ruby/test/fixtures/04-cowsay-vendored-nested/project/Gemfile +++ b/packages/ruby/test/fixtures/04-cowsay-vendored-nested/project/Gemfile @@ -2,6 +2,6 @@ source "https://rubygems.org" -ruby "~> 2.7.0" +ruby "~> 2.7.x" gem "cowsay", "~> 0.3.0" diff --git a/packages/ruby/test/fixtures/11-version-2-5-error/Gemfile b/packages/ruby/test/fixtures/11-version-2-5-error/Gemfile index 4ae28605a..886fc6053 100644 --- a/packages/ruby/test/fixtures/11-version-2-5-error/Gemfile +++ b/packages/ruby/test/fixtures/11-version-2-5-error/Gemfile @@ -2,6 +2,6 @@ source "https://rubygems.org" -ruby "~> 2.5.0" +ruby "~> 2.5.x" gem "cowsay", "~> 0.3.0" diff --git a/packages/ruby/test/test.js b/packages/ruby/test/test.js index 98eb55412..43a986bf1 100644 --- a/packages/ruby/test/test.js +++ b/packages/ruby/test/test.js @@ -12,7 +12,7 @@ const fixturesPath = path.resolve(__dirname, 'fixtures'); const testsThatFailToBuild = new Map([ [ '11-version-2-5-error', - 'Found `Gemfile` with discontinued Ruby version: `ruby "~> 2.5.0".` Please set `ruby "~> 2.7.0"` in your `Gemfile` to use the latest Ruby version.', + 'Found `Gemfile` with discontinued Ruby version: `ruby "~> 2.5.x".` Please set `ruby "~> 2.7.x"` in your `Gemfile` to use Ruby 2.7.x.', ], ]);