Skip to content
Snippets Groups Projects
Unverified Commit a1c51509 authored by Julien Tanay's avatar Julien Tanay Committed by GitHub
Browse files

feat(bundler): add source variables support (#32337)

parent 0cc330e9
No related branches found
No related tags found
No related merge requests found
import is from '@sindresorhus/is'; import is from '@sindresorhus/is';
import { codeBlock } from 'common-tags';
import { Fixtures } from '../../../../test/fixtures'; import { Fixtures } from '../../../../test/fixtures';
import { fs } from '../../../../test/util'; import { fs } from '../../../../test/util';
import { isValid } from '../../versioning/ruby'; import { isValid } from '../../versioning/ruby';
...@@ -141,4 +142,29 @@ describe('modules/manager/bundler/extract', () => { ...@@ -141,4 +142,29 @@ describe('modules/manager/bundler/extract', () => {
{ depName: 'sfn_my_dep2', currentValue: '"~> 1"' }, { depName: 'sfn_my_dep2', currentValue: '"~> 1"' },
]); ]);
}); });
it('parses source variable in Gemfile', async () => {
const sourceVariableGemfile = codeBlock`
source "https://rubygems.org"
ruby '~> 1.5.3'
foo = 'https://gems.foo.com'
bar = 'https://gems.bar.com'
source foo
source bar do
gem "some_internal_gem"
end
`;
fs.readLocalFile.mockResolvedValueOnce(sourceVariableGemfile);
const res = await extractPackageFile(sourceVariableGemfile, 'Gemfile');
expect(res?.deps).toHaveLength(2);
expect(res?.registryUrls).toHaveLength(2);
expect(res?.registryUrls?.[1]).toBe('https://gems.foo.com');
expect(res?.deps[1]).toMatchObject({
depName: 'some_internal_gem',
registryUrls: ['https://gems.bar.com'],
});
});
}); });
...@@ -78,6 +78,9 @@ export async function extractPackageFile( ...@@ -78,6 +78,9 @@ export async function extractPackageFile(
registryUrls: [], registryUrls: [],
deps: [], deps: [],
}; };
const variables: Record<string, string> = {};
const lines = content.split(newlineRegex); const lines = content.split(newlineRegex);
for (lineNumber = 0; lineNumber < lines.length; lineNumber += 1) { for (lineNumber = 0; lineNumber < lines.length; lineNumber += 1) {
const line = lines[lineNumber]; const line = lines[lineNumber];
...@@ -85,12 +88,20 @@ export async function extractPackageFile( ...@@ -85,12 +88,20 @@ export async function extractPackageFile(
for (const delimiter of delimiters) { for (const delimiter of delimiters) {
sourceMatch = sourceMatch =
sourceMatch ?? sourceMatch ??
regEx(`^source ${delimiter}([^${delimiter}]+)${delimiter}\\s*$`).exec( regEx(
line, `^source ((${delimiter}(?<registryUrl>[^${delimiter}]+)${delimiter})|(?<sourceName>\\w+))\\s*$`,
); ).exec(line);
} }
if (sourceMatch) { 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); const rubyMatch = extractRubyVersion(line);
...@@ -103,8 +114,18 @@ export async function extractPackageFile( ...@@ -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( 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); const gemMatch = gemMatchRegex.exec(line);
if (gemMatch) { if (gemMatch) {
...@@ -124,10 +145,18 @@ export async function extractPackageFile( ...@@ -124,10 +145,18 @@ export async function extractPackageFile(
for (const delimiter of delimiters) { for (const delimiter of delimiters) {
const sourceBlockMatch = regEx( const sourceBlockMatch = regEx(
`^source\\s+${delimiter}(.*?)${delimiter}\\s+do`, `^source\\s+((${delimiter}(?<registryUrl>[^${delimiter}]+)${delimiter})|(?<sourceName>\\w+))\\s+do`,
).exec(line); ).exec(line);
if (sourceBlockMatch) { 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; const sourceLineNumber = lineNumber;
let sourceContent = ''; let sourceContent = '';
let sourceLine = ''; let sourceLine = '';
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment