From c64fe52a7e2a00af1682e72fd4b05768cbeccd58 Mon Sep 17 00:00:00 2001 From: Sergio Zharinov <zharinov@users.noreply.github.com> Date: Mon, 21 Sep 2020 23:30:09 +0400 Subject: [PATCH] fix(bundler): More flexible parsing for gem lines (#7321) Co-authored-by: Rhys Arkins <rhys@arkins.net> --- .../bundler/__fixtures__/Gemfile.sourceBlock | 5 +++ .../Gemfile.sourceBlockWithNewLines | 2 +- .../__snapshots__/extract.spec.ts.snap | 33 ++++++++++++++++++- lib/manager/bundler/extract.spec.ts | 9 +++++ lib/manager/bundler/extract.ts | 31 +++++------------ 5 files changed, 55 insertions(+), 25 deletions(-) create mode 100644 lib/manager/bundler/__fixtures__/Gemfile.sourceBlock diff --git a/lib/manager/bundler/__fixtures__/Gemfile.sourceBlock b/lib/manager/bundler/__fixtures__/Gemfile.sourceBlock new file mode 100644 index 0000000000..beeea799e4 --- /dev/null +++ b/lib/manager/bundler/__fixtures__/Gemfile.sourceBlock @@ -0,0 +1,5 @@ +source 'https://hub.tech.my.domain.de/artifactory/api/gems/my-gems-prod-local/' do + gem 'sfn_my_dep1', "~> 1" + gem 'sfn_my_dep2', "~> 1" + +end diff --git a/lib/manager/bundler/__fixtures__/Gemfile.sourceBlockWithNewLines b/lib/manager/bundler/__fixtures__/Gemfile.sourceBlockWithNewLines index 879438f90c..b2e052aac6 100644 --- a/lib/manager/bundler/__fixtures__/Gemfile.sourceBlockWithNewLines +++ b/lib/manager/bundler/__fixtures__/Gemfile.sourceBlockWithNewLines @@ -4,4 +4,4 @@ source 'https://rubygems.org' do gem 'rubocop' gem 'brakeman' -end \ No newline at end of file +end diff --git a/lib/manager/bundler/__snapshots__/extract.spec.ts.snap b/lib/manager/bundler/__snapshots__/extract.spec.ts.snap index 50ae40eb87..dff3967352 100644 --- a/lib/manager/bundler/__snapshots__/extract.spec.ts.snap +++ b/lib/manager/bundler/__snapshots__/extract.spec.ts.snap @@ -2491,12 +2491,13 @@ Object { }, }, Object { + "currentValue": "~> 0.0.2", + "datasource": "rubygems", "depName": "omniauth-ultraauth", "lockedVersion": "0.0.2", "managerData": Object { "lineNumber": 46, }, - "skipReason": "no-version", }, Object { "currentValue": "~> 1.0.5", @@ -4689,6 +4690,36 @@ Object { } `; +exports[`lib/manager/bundler/extract parse source blocks in Gemfile 1`] = ` +Object { + "deps": Array [ + Object { + "currentValue": "~> 1", + "datasource": "rubygems", + "depName": "sfn_my_dep1", + "managerData": Object { + "lineNumber": 1, + }, + "registryUrls": Array [ + "https://hub.tech.my.domain.de/artifactory/api/gems/my-gems-prod-local/", + ], + }, + Object { + "currentValue": "~> 1", + "datasource": "rubygems", + "depName": "sfn_my_dep2", + "managerData": Object { + "lineNumber": 2, + }, + "registryUrls": Array [ + "https://hub.tech.my.domain.de/artifactory/api/gems/my-gems-prod-local/", + ], + }, + ], + "registryUrls": Array [], +} +`; + exports[`lib/manager/bundler/extract parse source blocks with spaces in Gemfile 1`] = ` Object { "compatibility": Object { diff --git a/lib/manager/bundler/extract.spec.ts b/lib/manager/bundler/extract.spec.ts index f7585134f5..132f03dabb 100644 --- a/lib/manager/bundler/extract.spec.ts +++ b/lib/manager/bundler/extract.spec.ts @@ -51,6 +51,10 @@ const gitlabFossGemfile = readFileSync( 'lib/manager/bundler/__fixtures__/Gemfile.gitlab-foss', 'utf8' ); +const sourceBlockGemfile = readFileSync( + 'lib/manager/bundler/__fixtures__/Gemfile.sourceBlock', + 'utf8' +); const sourceBlockWithNewLinesGemfileLock = readFileSync( 'lib/manager/bundler/__fixtures__/Gemfile.sourceBlockWithNewLines.lock', 'utf8' @@ -157,6 +161,11 @@ describe('lib/manager/bundler/extract', () => { validateGems(gitlabFossGemfile, res); }); + it('parse source blocks in Gemfile', async () => { + fs.readLocalFile.mockResolvedValueOnce(sourceBlockGemfile); + const res = await extractPackageFile(sourceBlockGemfile, 'Gemfile'); + expect(res).toMatchSnapshot(); + }); it('parse source blocks with spaces in Gemfile', async () => { fs.readLocalFile.mockResolvedValueOnce(sourceBlockWithNewLinesGemfileLock); const res = await extractPackageFile( diff --git a/lib/manager/bundler/extract.ts b/lib/manager/bundler/extract.ts index e59c67c6ce..4f5115b315 100644 --- a/lib/manager/bundler/extract.ts +++ b/lib/manager/bundler/extract.ts @@ -38,33 +38,18 @@ export async function extractPackageFile( if (rubyMatch) { res.compatibility = { ruby: rubyMatch[1] }; } - let gemMatch: RegExpMatchArray; - let gemDelimiter: string; - for (const delimiter of delimiters) { - const gemMatchRegex = `^gem ${delimiter}([^${delimiter}]+)${delimiter}(,\\s+${delimiter}([^${delimiter}]+)${delimiter}){0,2}`; - if (regEx(gemMatchRegex).test(line)) { - gemDelimiter = delimiter; - gemMatch = gemMatch || regEx(gemMatchRegex).exec(line); - } - } + const gemMatchRegex = /^\s*gem\s+(['"])(?<depName>[^'"]+)\1(\s*,\s*(?<currentValue>(['"])[^'"]+\5(\s*,\s*\5[^'"]+\5)?))?/; + const gemMatch = gemMatchRegex.exec(line); if (gemMatch) { const dep: PackageDependency = { - depName: gemMatch[1], + depName: gemMatch.groups.depName, managerData: { lineNumber }, }; - if (gemMatch[3]) { - let currentValue = gemMatch[0] - .substring(`gem ${gemDelimiter}${dep.depName}${gemDelimiter},`.length) - .trim(); - // strip quotes unless it's a complex constraint - if ( - currentValue.startsWith(gemDelimiter) && - currentValue.endsWith(gemDelimiter) && - currentValue.split(gemDelimiter).length === 3 - ) { - currentValue = currentValue.slice(1, -1); - } - dep.currentValue = currentValue; + if (gemMatch.groups.currentValue) { + const currentValue = gemMatch.groups.currentValue; + dep.currentValue = /\s*,\s*/.test(currentValue) + ? currentValue + : currentValue.slice(1, -1); } else { dep.skipReason = SkipReason.NoVersion; } -- GitLab