Skip to content

Commit

Permalink
feat(manager/dockerfile): Add syntax statement support (#25530)
Browse files Browse the repository at this point in the history
Co-authored-by: Michael Kriese <michael.kriese@visualon.de>
Co-authored-by: Rhys Arkins <rhys@arkins.net>
Co-authored-by: Johannes Feichtner <343448+Churro@users.noreply.github.com>
  • Loading branch information
4 people committed Nov 10, 2023
1 parent 0525c36 commit 235d512
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 1 deletion.
64 changes: 64 additions & 0 deletions lib/modules/manager/dockerfile/extract.spec.ts
Expand Up @@ -941,6 +941,16 @@ describe('modules/manager/dockerfile/extract', () => {
it('handles an alternative escape character', () => {
const res = extractPackageFile(d4, '', {})?.deps;
expect(res).toEqual([
{
autoReplaceStringTemplate:
'{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}',
currentDigest: undefined,
currentValue: '1',
datasource: 'docker',
depName: 'docker/dockerfile',
depType: 'syntax',
replaceString: 'docker/dockerfile:1',
},
{
autoReplaceStringTemplate:
' ARG `\n' +
Expand Down Expand Up @@ -1152,6 +1162,60 @@ describe('modules/manager/dockerfile/extract', () => {
});
});

it('handles # syntax statements', () => {
const res = extractPackageFile(
'# syntax=docker/dockerfile:1.1.7\n' + 'FROM alpine:3.13.5\n',
'',
{},
);
expect(res).toEqual({
deps: [
{
autoReplaceStringTemplate:
'{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}',
currentDigest: undefined,
currentValue: '1.1.7',
datasource: 'docker',
depName: 'docker/dockerfile',
depType: 'syntax',
replaceString: 'docker/dockerfile:1.1.7',
},
{
autoReplaceStringTemplate:
'{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}',
currentDigest: undefined,
currentValue: '3.13.5',
datasource: 'docker',
depName: 'alpine',
depType: 'final',
replaceString: 'alpine:3.13.5',
},
],
});
});

it('ignores # syntax statements after first line', () => {
const res = extractPackageFile(
'FROM alpine:3.13.5\n' + '# syntax=docker/dockerfile:1.1.7\n',
'',
{},
);
expect(res).toEqual({
deps: [
{
autoReplaceStringTemplate:
'{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}',
currentDigest: undefined,
currentValue: '3.13.5',
datasource: 'docker',
depName: 'alpine',
depType: 'final',
replaceString: 'alpine:3.13.5',
},
],
});
});

describe('getDep()', () => {
it('rejects null', () => {
expect(getDep(null)).toEqual({ skipReason: 'invalid-value' });
Expand Down
32 changes: 31 additions & 1 deletion lib/modules/manager/dockerfile/extract.ts
Expand Up @@ -251,6 +251,7 @@ export function extractPackageFile(

let escapeChar = '\\\\';
let lookForEscapeChar = true;
let lookForSyntaxDirective = true;

const lineFeed = content.indexOf('\r\n') >= 0 ? '\r\n' : '\n';
const lines = content.split(newlineRegex);
Expand All @@ -272,6 +273,33 @@ export function extractPackageFile(
}
}

if (lookForSyntaxDirective) {
const syntaxRegex = regEx(
'^#[ \\t]*syntax[ \\t]*=[ \\t]*(?<image>\\S+)',
'im',
);
const syntaxMatch = instruction.match(syntaxRegex);
if (syntaxMatch?.groups?.image) {
const syntaxImage = syntaxMatch.groups.image;
const lineNumberRanges: number[][] = [
[lineNumberInstrStart, lineNumber],
];
const dep = getDep(syntaxImage, true, config.registryAliases);
dep.depType = 'syntax';
processDepForAutoReplace(dep, lineNumberRanges, lines, lineFeed);
logger.trace(
{
depName: dep.depName,
currentValue: dep.currentValue,
currentDigest: dep.currentDigest,
},
'Dockerfile # syntax',
);
deps.push(dep);
}
lookForSyntaxDirective = false;
}

const lineContinuationRegex = regEx(escapeChar + '[ \\t]*$|^[ \\t]*#', 'm');
let lineLookahead = instruction;
while (
Expand Down Expand Up @@ -400,7 +428,9 @@ export function extractPackageFile(
return null;
}
for (const d of deps) {
d.depType = 'stage';
if (!d.depType) {
d.depType = 'stage';
}
}
deps[deps.length - 1].depType = 'final';
return { deps };
Expand Down

0 comments on commit 235d512

Please sign in to comment.