Skip to content

Commit

Permalink
feat(bundler): add source variables support
Browse files Browse the repository at this point in the history
  • Loading branch information
Djiit committed Nov 5, 2024
1 parent 85267b9 commit 7bc6760
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 7 deletions.
20 changes: 20 additions & 0 deletions lib/modules/manager/bundler/extract.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import is from '@sindresorhus/is';
import { codeBlock } from 'common-tags';
import { Fixtures } from '../../../../test/fixtures';
import { fs } from '../../../../test/util';
import { isValid } from '../../versioning/ruby';
Expand Down Expand Up @@ -29,6 +30,15 @@ const sourceBlockWithNewLinesGemfile = Fixtures.get(
const sourceBlockWithGroupsGemfile = Fixtures.get(
'Gemfile.sourceBlockWithGroups',
);
const sourceVariableGemfile = codeBlock`
source "https://rubygems.org"
ruby '~> 1.5.3'
example = 'https://gems.example.com'
source example do
gem "some_internal_gem"
end
`;

describe('modules/manager/bundler/extract', () => {
describe('extractPackageFile()', () => {
Expand Down Expand Up @@ -141,4 +151,14 @@ describe('modules/manager/bundler/extract', () => {
{ depName: 'sfn_my_dep2', currentValue: '"~> 1"' },
]);
});

it('parses source variable in Gemfile', async () => {
fs.readLocalFile.mockResolvedValueOnce(sourceVariableGemfile);
const res = await extractPackageFile(sourceVariableGemfile, 'Gemfile');
expect(res?.deps).toHaveLength(2);
expect(res?.deps[1]).toMatchObject({
depName: 'some_internal_gem',
registryUrls: ['https://gems.example.com'],
});
});
});
43 changes: 36 additions & 7 deletions lib/modules/manager/bundler/extract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,19 +78,30 @@ export async function extractPackageFile(
registryUrls: [],
deps: [],
};

const variables: Record<string, string> = {};

const lines = content.split(newlineRegex);
for (lineNumber = 0; lineNumber < lines.length; lineNumber += 1) {
const line = lines[lineNumber];
let sourceMatch: RegExpMatchArray | null = null;
for (const delimiter of delimiters) {
sourceMatch =
sourceMatch ??
regEx(`^source ${delimiter}([^${delimiter}]+)${delimiter}\\s*$`).exec(
line,
);
regEx(
`^source ((${delimiter}(?<registryUrl>[^${delimiter}]+)${delimiter})|(?<sourceName>\\w+))\\s*$`,
).exec(line);
}
if (sourceMatch) {
res.registryUrls?.push(sourceMatch[1]);
if (sourceMatch.groups?.registryUrl) {
res.registryUrls?.push(sourceMatch.groups.registryUrl);
}
if (sourceMatch.groups?.sourceName) {
const registryUrl = variables[sourceMatch.groups.sourceName];
if (registryUrl) {
res.registryUrls?.push(registryUrl);
}
}
}

const rubyMatch = extractRubyVersion(line);
Expand All @@ -103,8 +114,18 @@ export async function extractPackageFile(
});
}

const variableMatchRegex = regEx(
`^(?<key>\\w+)\\s*=\\s*['"](?<value>[^'"]+)['"]`,
);
const variableMatch = variableMatchRegex.exec(line);
if (variableMatch) {
if (variableMatch.groups?.key) {
variables[variableMatch.groups?.key] = variableMatch.groups?.value;
}
}

const gemMatchRegex = regEx(
`^\\s*gem\\s+(['"])(?<depName>[^'"]+)(['"])(\\s*,\\s*(?<currentValue>(['"])[^'"]+['"](\\s*,\\s*['"][^'"]+['"])?))?`,
`^\\s*gem\\s+(['"])(?<depName>[^'"]+)(['"])(\\s*,\\s*(?<currentValue>(['"])[^'"]+['"](\\s*,\\s*['"][^'"]+['"])?))?(\\s*,\\s*source:\\s*(['"](?<registryUrl>[^'"]+)['"]|(?<sourceName>[^'"]+)))?`,
);
const gemMatch = gemMatchRegex.exec(line);
if (gemMatch) {
Expand All @@ -124,10 +145,18 @@ export async function extractPackageFile(

for (const delimiter of delimiters) {
const sourceBlockMatch = regEx(
`^source\\s+${delimiter}(.*?)${delimiter}\\s+do`,
`^source ((${delimiter}(?<registryUrl>[^${delimiter}]+)${delimiter})|(?<sourceName>\\w+))\\s+do`,
).exec(line);
if (sourceBlockMatch) {
const repositoryUrl = sourceBlockMatch[1];
let repositoryUrl = '';
if (sourceBlockMatch.groups?.registryUrl) {
repositoryUrl = sourceBlockMatch.groups.registryUrl;
}
if (sourceBlockMatch.groups?.sourceName) {
if (variables[sourceBlockMatch.groups.sourceName]) {
repositoryUrl = variables[sourceBlockMatch.groups.sourceName];
}
}
const sourceLineNumber = lineNumber;
let sourceContent = '';
let sourceLine = '';
Expand Down

0 comments on commit 7bc6760

Please sign in to comment.