Skip to content

Commit

Permalink
refactor(bundler): refactor extraction regexes (#32870)
Browse files Browse the repository at this point in the history
  • Loading branch information
Djiit authored Dec 5, 2024
1 parent 349712c commit 2f49607
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -542,12 +542,15 @@ exports[`modules/manager/bundler/extract extractPackageFile() parse mastodon Gem
},
},
{
"currentDigest": "54b17ba8c7d8d20a16dfc65d1775241833219cf2",
"currentValue": "'~> 0.6'",
"datasource": "rubygems",
"datasource": "git-refs",
"depName": "http_parser.rb",
"managerData": {
"lineNumber": 57,
},
"packageName": "https://github.com/tmm1/http_parser.rb",
"sourceUrl": "https://github.com/tmm1/http_parser.rb",
},
{
"currentValue": "'~> 1.3'",
Expand Down
44 changes: 44 additions & 0 deletions lib/modules/manager/bundler/extract.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,14 +171,21 @@ describe('modules/manager/bundler/extract', () => {
it('parses inline source in Gemfile', async () => {
const sourceInlineGemfile = codeBlock`
baz = 'https://gems.baz.com'
gem 'inline_gem'
gem "inline_source_gem", source: 'https://gems.foo.com'
gem 'inline_source_gem_with_version', "~> 1", source: 'https://gems.bar.com'
gem 'inline_source_gem_with_variable_source', source: baz
gem "inline_source_gem_with_require_after", source: 'https://gems.foo.com', require: %w[inline_source_gem]
gem "inline_source_gem_with_require_before", require: %w[inline_source_gem], source: 'https://gems.foo.com'
gem "inline_source_gem_with_group_before", group: :production, source: 'https://gems.foo.com'
`;
fs.readLocalFile.mockResolvedValueOnce(sourceInlineGemfile);
const res = await extractPackageFile(sourceInlineGemfile, 'Gemfile');
expect(res).toMatchObject({
deps: [
{
depName: 'inline_gem',
},
{
depName: 'inline_source_gem',
registryUrls: ['https://gems.foo.com'],
Expand All @@ -192,6 +199,18 @@ describe('modules/manager/bundler/extract', () => {
depName: 'inline_source_gem_with_variable_source',
registryUrls: ['https://gems.baz.com'],
},
{
depName: 'inline_source_gem_with_require_after',
registryUrls: ['https://gems.foo.com'],
},
{
depName: 'inline_source_gem_with_require_before',
registryUrls: ['https://gems.foo.com'],
},
{
depName: 'inline_source_gem_with_group_before',
registryUrls: ['https://gems.foo.com'],
},
],
});
});
Expand Down Expand Up @@ -231,4 +250,29 @@ describe('modules/manager/bundler/extract', () => {
],
});
});

it('parses multiple current values Gemfile', async () => {
const multipleValuesGemfile = codeBlock`
gem 'gem_without_values'
gem 'gem_with_one_value', ">= 3.0.5"
gem 'gem_with_multiple_values', ">= 3.0.5", "< 3.2"
`;
fs.readLocalFile.mockResolvedValueOnce(multipleValuesGemfile);
const res = await extractPackageFile(multipleValuesGemfile, 'Gemfile');
expect(res).toMatchObject({
deps: [
{
depName: 'gem_without_values',
},
{
depName: 'gem_with_one_value',
currentValue: '">= 3.0.5"',
},
{
depName: 'gem_with_multiple_values',
currentValue: '">= 3.0.5", "< 3.2"',
},
],
});
});
});
77 changes: 41 additions & 36 deletions lib/modules/manager/bundler/extract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,14 @@ function formatContent(input: string): string {
const variableMatchRegex = regEx(
`^(?<key>\\w+)\\s*=\\s*['"](?<value>[^'"]+)['"]`,
);
const gemGitRefsMatchRegex = regEx(
`^\\s*gem\\s+(['"])(?<depName>[^'"]+)['"]((\\s*,\\s*git:\\s*['"](?<gitUrl>[^'"]+)['"])|(\\s*,\\s*github:\\s*['"](?<repoName>[^'"]+)['"]))(\\s*,\\s*branch:\\s*['"](?<branchName>[^'"]+)['"])?(\\s*,\\s*ref:\\s*['"](?<refName>[^'"]+)['"])?(\\s*,\\s*tag:\\s*['"](?<tagName>[^'"]+)['"])?`,
);
const gemMatchRegex = regEx(
`^\\s*gem\\s+(['"])(?<depName>[^'"]+)(['"])(\\s*,\\s*(?<currentValue>(['"])[^'"]+['"](\\s*,\\s*['"][^'"]+['"])?))?(\\s*,\\s*source:\\s*(['"](?<registryUrl>[^'"]+)['"]|(?<sourceName>[^'"]+)))?`,
`^\\s*gem\\s+(['"])(?<depName>[^'"]+)(['"])(\\s*,\\s*(?<currentValue>(['"])[^'"]+['"](\\s*,\\s*['"][^'"]+['"])?))?`,
);
const sourceMatchRegex = regEx(
`source:\\s*(['"](?<registryUrl>[^'"]+)['"]|(?<sourceName>[^'"]+))?`,
);
const gitRefsMatchRegex = regEx(
`((git:\\s*['"](?<gitUrl>[^'"]+)['"])|(\\s*,\\s*github:\\s*['"](?<repoName>[^'"]+)['"]))(\\s*,\\s*branch:\\s*['"](?<branchName>[^'"]+)['"])?(\\s*,\\s*ref:\\s*['"](?<refName>[^'"]+)['"])?(\\s*,\\s*tag:\\s*['"](?<tagName>[^'"]+)['"])?`,
);

export async function extractPackageFile(
Expand Down Expand Up @@ -132,49 +135,51 @@ export async function extractPackageFile(
}
}

const gemGitRefsMatch = gemGitRefsMatchRegex.exec(line)?.groups;
const gemMatch = gemMatchRegex.exec(line)?.groups;

if (gemGitRefsMatch) {
const dep: PackageDependency = {
depName: gemGitRefsMatch.depName,
managerData: { lineNumber },
};
if (gemGitRefsMatch.gitUrl) {
const gitUrl = gemGitRefsMatch.gitUrl;
dep.packageName = gitUrl;

if (gitUrl.startsWith('https://')) {
dep.sourceUrl = gitUrl.replace(/\.git$/, '');
}
} else if (gemGitRefsMatch.repoName) {
dep.packageName = `https://github.com/${gemGitRefsMatch.repoName}`;
dep.sourceUrl = dep.packageName;
}
if (gemGitRefsMatch.refName) {
dep.currentDigest = gemGitRefsMatch.refName;
} else if (gemGitRefsMatch.branchName) {
dep.currentValue = gemGitRefsMatch.branchName;
} else if (gemGitRefsMatch.tagName) {
dep.currentValue = gemGitRefsMatch.tagName;
}
dep.datasource = GitRefsDatasource.id;
res.deps.push(dep);
} else if (gemMatch) {
if (gemMatch) {
const dep: PackageDependency = {
depName: gemMatch.depName,
managerData: { lineNumber },
datasource: RubygemsDatasource.id,
};

if (gemMatch.currentValue) {
const currentValue = gemMatch.currentValue;
dep.currentValue = currentValue;
}
if (gemMatch.registryUrl) {
dep.registryUrls = [gemMatch.registryUrl];
} else if (gemMatch.sourceName) {
dep.registryUrls = [variables[gemMatch.sourceName]];

const sourceMatch = sourceMatchRegex.exec(line)?.groups;
if (sourceMatch) {
if (sourceMatch.registryUrl) {
dep.registryUrls = [sourceMatch.registryUrl];
} else if (sourceMatch.sourceName) {
dep.registryUrls = [variables[sourceMatch.sourceName]];
}
}

const gitRefsMatch = gitRefsMatchRegex.exec(line)?.groups;
if (gitRefsMatch) {
if (gitRefsMatch.gitUrl) {
const gitUrl = gitRefsMatch.gitUrl;
dep.packageName = gitUrl;

if (gitUrl.startsWith('https://')) {
dep.sourceUrl = gitUrl.replace(/\.git$/, '');
}
} else if (gitRefsMatch.repoName) {
dep.packageName = `https://github.com/${gitRefsMatch.repoName}`;
dep.sourceUrl = dep.packageName;
}
if (gitRefsMatch.refName) {
dep.currentDigest = gitRefsMatch.refName;
} else if (gitRefsMatch.branchName) {
dep.currentValue = gitRefsMatch.branchName;
} else if (gitRefsMatch.tagName) {
dep.currentValue = gitRefsMatch.tagName;
}
dep.datasource = GitRefsDatasource.id;
}
dep.datasource = RubygemsDatasource.id;
res.deps.push(dep);
}

Expand Down

0 comments on commit 2f49607

Please sign in to comment.