diff --git a/lib/modules/manager/gomod/extract.ts b/lib/modules/manager/gomod/extract.ts index 935f63e4c2af29387984375aa77fe11c6883cc87..61d30af520d20bd07900be1deae75219836a9026 100644 --- a/lib/modules/manager/gomod/extract.ts +++ b/lib/modules/manager/gomod/extract.ts @@ -5,6 +5,7 @@ import { GoDatasource } from '../../datasource/go'; import { GolangVersionDatasource } from '../../datasource/golang-version'; import { isVersion } from '../../versioning/semver'; import type { PackageDependency, PackageFile } from '../types'; +import type { MultiLineParseResult } from './types'; function getDep( lineNumber: number, @@ -56,7 +57,7 @@ export function extractPackageFile(content: string): PackageFile | null { try { const lines = content.split(newlineRegex); for (let lineNumber = 0; lineNumber < lines.length; lineNumber += 1) { - let line = lines[lineNumber]; + const line = lines[lineNumber]; const goVer = line.startsWith('go ') ? line.replace('go ', '') : null; if (goVer && semver.validRange(goVer)) { const dep = getGoDep(lineNumber, goVer); @@ -78,20 +79,15 @@ export function extractPackageFile(content: string): PackageFile | null { } if (line.trim() === 'require (') { logger.trace(`Matched multi-line require on line ${lineNumber}`); - do { - lineNumber += 1; - line = lines[lineNumber]; - const multiMatch = regEx(/^\s+([^\s]+)\s+([^\s]+)/).exec(line); - logger.trace(`reqLine: "${line}"`); - if (multiMatch && !line.endsWith('// indirect')) { - logger.trace({ lineNumber }, `require line: "${line}"`); - const dep = getDep(lineNumber, multiMatch, 'require'); - dep.managerData!.multiLine = true; - deps.push(dep); - } else if (line.trim() !== ')') { - logger.trace(`No multi-line match: ${line}`); - } - } while (line.trim() !== ')'); + const matcher = regEx(/^\s+([^\s]+)\s+([^\s]+)/); + const { reachedLine, detectedDeps } = parseMultiLine( + lineNumber, + lines, + matcher, + 'require' + ); + lineNumber = reachedLine; + deps.push(...detectedDeps); } } } catch (err) /* istanbul ignore next */ { @@ -102,3 +98,29 @@ export function extractPackageFile(content: string): PackageFile | null { } return { constraints, deps }; } + +function parseMultiLine( + startingLine: number, + lines: string[], + matchRegex: RegExp, + blockType: 'require' | 'replace' +): MultiLineParseResult { + const deps: PackageDependency[] = []; + let lineNumber = startingLine; + let line = ''; + do { + lineNumber += 1; + line = lines[lineNumber]; + const multiMatch = matchRegex.exec(line); + logger.trace(`${blockType}: "${line}"`); + if (multiMatch && !line.endsWith('// indirect')) { + logger.trace({ lineNumber }, `${blockType} line: "${line}"`); + const dep = getDep(lineNumber, multiMatch, blockType); + dep.managerData!.multiLine = true; + deps.push(dep); + } else if (line.trim() !== ')') { + logger.trace(`No multi-line match: ${line}`); + } + } while (line.trim() !== ')'); + return { reachedLine: lineNumber, detectedDeps: deps }; +} diff --git a/lib/modules/manager/gomod/types.ts b/lib/modules/manager/gomod/types.ts new file mode 100644 index 0000000000000000000000000000000000000000..70c3dace8b1b2b7957a7e8eeeabcbed519371fb9 --- /dev/null +++ b/lib/modules/manager/gomod/types.ts @@ -0,0 +1,6 @@ +import type { PackageDependency } from '../types'; + +export interface MultiLineParseResult { + reachedLine: number; + detectedDeps: PackageDependency[]; +}