Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(manager/circleci): replace regex system with YAML parsing #30142

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/config/migration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@
} else if (is.array(val)) {
if (is.array(migratedConfig?.[key])) {
const newArray = [];
for (const item of migratedConfig[key] as unknown[]) {
for (const item of migratedConfig[key]) {

Check failure on line 73 in lib/config/migration.ts

View workflow job for this annotation

GitHub Actions / lint-other

Object is of type 'unknown'.

Check failure on line 73 in lib/config/migration.ts

View workflow job for this annotation

GitHub Actions / build

Object is of type 'unknown'.
secustor marked this conversation as resolved.
Show resolved Hide resolved
if (is.object(item) && !is.array(item)) {
const arrMigrate = migrateConfig(item as RenovateConfig);
newArray.push(arrMigrate.migratedConfig);
Expand Down
2 changes: 1 addition & 1 deletion lib/modules/datasource/npm/npmrc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@

const ENV_EXPR = regEx(/(\\*)\$\{([^}]+)\}/g);

return value.replace(ENV_EXPR, (match, _esc, envVarName) => {

Check failure on line 27 in lib/modules/datasource/npm/npmrc.ts

View workflow job for this annotation

GitHub Actions / lint-other

No overload matches this call.

Check failure on line 27 in lib/modules/datasource/npm/npmrc.ts

View workflow job for this annotation

GitHub Actions / build

No overload matches this call.
if (env[envVarName] === undefined) {
logger.warn('Failed to replace env in config: ' + match);
throw new Error('env-replace');
}
return env[envVarName]!;
return env[envVarName];
secustor marked this conversation as resolved.
Show resolved Hide resolved
});
}

Expand Down
2 changes: 1 addition & 1 deletion lib/modules/manager/circleci/__fixtures__/config2.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ orbs:
no-version: abc/def

# Comments help me understand my work.
volatile: zzz/zzz@volatile # Comments help me understand my work.
volatile: "zzz/zzz@volatile" # Comments help me understand my work.

test_plan: &test_plan
steps:
Expand Down
6 changes: 2 additions & 4 deletions lib/modules/manager/circleci/__fixtures__/config3.yml
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
aliases:
aliases:
- &nodejs
image: cimg/node:14.8.0

version: 2
jobs:
checkout:
<<: *defaults
checkout:
viceice marked this conversation as resolved.
Show resolved Hide resolved
docker:
- *nodejs
steps:
- run: yarn build:runtime

release_docker:
<<: *defaults
machine:
image: ubuntu-1604:201903-01
docker_layer_caching: true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ exports[`modules/manager/circleci/extract extractPackageFile() extracts multiple
"depName": "node",
"depType": "docker",
"replaceString": "node",
"versioning": "docker",
},
{
"autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}",
Expand All @@ -20,7 +19,6 @@ exports[`modules/manager/circleci/extract extractPackageFile() extracts multiple
"depName": "node",
"depType": "docker",
"replaceString": "node:4",
"versioning": "docker",
},
{
"autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}",
Expand All @@ -30,7 +28,6 @@ exports[`modules/manager/circleci/extract extractPackageFile() extracts multiple
"depName": "node",
"depType": "docker",
"replaceString": "node:6",
"versioning": "docker",
},
{
"autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}",
Expand All @@ -40,7 +37,6 @@ exports[`modules/manager/circleci/extract extractPackageFile() extracts multiple
"depName": "node",
"depType": "docker",
"replaceString": "node:8.9.0",
"versioning": "docker",
},
]
`;
1 change: 1 addition & 0 deletions lib/modules/manager/circleci/extract.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ describe('modules/manager/circleci/extract', () => {
const res = extractPackageFile(file3);
expect(res?.deps).toMatchObject([
{ currentValue: '14.8.0', depName: 'cimg/node' },
{ currentValue: '14.8.0', depName: 'cimg/node' },
]);
});

Expand Down
96 changes: 33 additions & 63 deletions lib/modules/manager/circleci/extract.ts
Original file line number Diff line number Diff line change
@@ -1,80 +1,50 @@
import { logger } from '../../../logger';
import { newlineRegex, regEx } from '../../../util/regex';
import { coerceArray } from '../../../util/array';
import { parseSingleYaml } from '../../../util/yaml';
import { OrbDatasource } from '../../datasource/orb';
import * as npmVersioning from '../../versioning/npm';
import { getDep } from '../dockerfile/extract';
import type { PackageDependency, PackageFileContent } from '../types';
import { CircleCiFile } from './schema';

export function extractPackageFile(
content: string,
packageFile?: string,
): PackageFileContent | null {
const deps: PackageDependency[] = [];
try {
const lines = content.split(newlineRegex);
for (let lineNumber = 0; lineNumber < lines.length; lineNumber += 1) {
const line = lines[lineNumber];
const orbs = regEx(/^\s*orbs:\s*$/).exec(line);
if (orbs) {
logger.trace(`Matched orbs on line ${lineNumber}`);
let foundOrbOrNoop: boolean;
do {
foundOrbOrNoop = false;
const orbLine = lines[lineNumber + 1];
logger.trace(`orbLine: "${orbLine}"`);
const yamlNoop = regEx(/^\s*(#|$)/).exec(orbLine);
if (yamlNoop) {
logger.debug('orbNoop');
foundOrbOrNoop = true;
lineNumber += 1;
continue;
}
const orbMatch = regEx(/^\s+([^:]+):\s(.+?)(?:\s*#.*)?$/).exec(
orbLine,
);
if (orbMatch) {
logger.trace('orbMatch');
foundOrbOrNoop = true;
lineNumber += 1;
const depName = orbMatch[1];
const [orbName, currentValue] = orbMatch[2].split('@');
const dep: PackageDependency = {
depType: 'orb',
depName,
currentValue,
datasource: OrbDatasource.id,
packageName: orbName,
commitMessageTopic: '{{{depName}}} orb',
versioning: npmVersioning.id,
};
deps.push(dep);
}
} while (foundOrbOrNoop);
}
const match = regEx(/^\s*-? image:\s*'?"?([^\s'"]+)'?"?\s*$/).exec(line);
if (match) {
const currentFrom = match[1];
const dep = getDep(currentFrom);
logger.debug(
{
depName: dep.depName,
currentValue: dep.currentValue,
currentDigest: dep.currentDigest,
},
'CircleCI docker image',
);
dep.depType = 'docker';
dep.versioning = 'docker';
if (
!dep.depName?.startsWith('ubuntu-') &&
!dep.depName?.startsWith('windows-server-') &&
!dep.depName?.startsWith('android-') &&
dep.depName !== 'android'
viceice marked this conversation as resolved.
Show resolved Hide resolved
) {
deps.push(dep);
}
const parsed = parseSingleYaml(content, {
customSchema: CircleCiFile,
});

for (const [key, orb] of Object.entries(parsed.orbs ?? {})) {
const [packageName, currentValue] = orb.split('@');

deps.push({
depName: key,
packageName,
depType: 'orb',
currentValue,
versioning: npmVersioning.id,
datasource: OrbDatasource.id,
});
}

for (const job of Object.values(parsed.jobs)) {
for (const dockerElement of coerceArray(job.docker)) {
deps.push({
...getDep(dockerElement.image),
depType: 'docker',
});
}
}

for (const alias of coerceArray(parsed.aliases)) {
deps.push({
...getDep(alias.image),
depType: 'docker',
});
}
} catch (err) /* istanbul ignore next */ {
logger.debug({ err, packageFile }, 'Error extracting circleci images');
}
Expand Down
15 changes: 15 additions & 0 deletions lib/modules/manager/circleci/schema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { z } from 'zod';

export const CircleCiDocker = z.object({
image: z.string(),
});

export const CircleCiJob = z.object({
docker: z.array(CircleCiDocker).optional(),
});

export const CircleCiFile = z.object({
aliases: z.array(CircleCiDocker).optional(),
jobs: z.record(z.string(), CircleCiJob),
orbs: z.record(z.string()).optional(),
});
2 changes: 1 addition & 1 deletion lib/modules/manager/gradle/parser/handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@

const matchResult = parseGradle(
// TODO #22198
ctx.fileContents[scriptFilePath]!,
ctx.fileContents[scriptFilePath],

Check failure on line 374 in lib/modules/manager/gradle/parser/handlers.ts

View workflow job for this annotation

GitHub Actions / lint-other

Argument of type 'string | null' is not assignable to parameter of type 'string'.

Check failure on line 374 in lib/modules/manager/gradle/parser/handlers.ts

View workflow job for this annotation

GitHub Actions / build

Argument of type 'string | null' is not assignable to parameter of type 'string'.
secustor marked this conversation as resolved.
Show resolved Hide resolved
ctx.globalVars,
scriptFilePath,
ctx.fileContents,
Expand Down
2 changes: 1 addition & 1 deletion lib/modules/manager/npm/post-update/npm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@
if (
lockFileParsed.packages?.['']?.[depType]?.[lockUpdate.packageName!]
) {
lockFileParsed.packages[''][depType]![lockUpdate.packageName!] =
lockFileParsed.packages[''][depType][lockUpdate.packageName!] =

Check failure on line 237 in lib/modules/manager/npm/post-update/npm.ts

View workflow job for this annotation

GitHub Actions / lint-other

Object is possibly 'undefined'.

Check failure on line 237 in lib/modules/manager/npm/post-update/npm.ts

View workflow job for this annotation

GitHub Actions / build

Object is possibly 'undefined'.
secustor marked this conversation as resolved.
Show resolved Hide resolved
lockUpdate.newValue!;
}
});
Expand Down
2 changes: 1 addition & 1 deletion lib/modules/manager/nuget/artifacts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ export async function updateArtifacts({
file: {
type: 'addition',
path: lockFileName,
contents: newLockFileContentMap[lockFileName]!,
contents: newLockFileContentMap[lockFileName],
secustor marked this conversation as resolved.
Show resolved Hide resolved
},
});
}
Expand Down
Loading