Files
renovate/lib/modules/manager/gradle/parser.ts
Sergei Zharinov 930cf6633c refactor: Rewrite imports with .ts extensions (#40700)
fix: Additional vi.mock path corrections and prettier formatting
2026-01-26 22:48:17 +00:00

161 lines
4.2 KiB
TypeScript

import { lang, query as q } from '@renovatebot/good-enough-parser';
import { newlineRegex, regEx } from '../../../util/regex.ts';
import type { PackageDependency } from '../types.ts';
import { qApplyFrom } from './parser/apply-from.ts';
import { qAssignments } from './parser/assignments.ts';
import { qKotlinImport } from './parser/common.ts';
import { qDependencies, qLongFormDep } from './parser/dependencies.ts';
import { setParseGradleFunc } from './parser/handlers.ts';
import { qToolchainVersion } from './parser/language-version.ts';
import { qKotlinMultiObjectVarAssignment } from './parser/objects.ts';
import { qPlugins } from './parser/plugins.ts';
import { qRegistryUrls } from './parser/registry-urls.ts';
import { qVersionCatalogs } from './parser/version-catalogs.ts';
import type {
Ctx,
GradleManagerData,
PackageRegistry,
PackageVariables,
ParseGradleResult,
} from './types.ts';
import { parseDependencyString } from './utils.ts';
const groovy = lang.createLang('groovy');
const ctx: Ctx = {
packageFile: '',
fileContents: {},
recursionDepth: 0,
globalVars: {},
deps: [],
registryUrls: [],
varTokens: [],
tmpKotlinImportStore: [],
tmpNestingDepth: [],
tmpRegistryContent: [],
tmpTokenStore: {},
tokenMap: {},
};
setParseGradleFunc(parseGradle);
export function parseGradle(
input: string,
initVars: PackageVariables = {},
packageFile = '',
fileContents: Record<string, string | null> = {},
recursionDepth = 0,
): ParseGradleResult {
let vars: PackageVariables = { ...initVars };
const deps: PackageDependency<GradleManagerData>[] = [];
const urls: PackageRegistry[] = [];
const query = q.tree<Ctx>({
type: 'root-tree',
search: q.alt<Ctx>(
qKotlinImport,
qAssignments,
qKotlinMultiObjectVarAssignment,
qDependencies,
qPlugins,
qRegistryUrls,
qVersionCatalogs,
qLongFormDep,
qApplyFrom,
),
});
const parsedResult = groovy.query(input, query, {
...ctx,
packageFile,
fileContents,
recursionDepth,
globalVars: vars,
});
if (parsedResult) {
deps.push(...parsedResult.deps);
vars = { ...vars, ...parsedResult.globalVars };
urls.push(...parsedResult.registryUrls);
}
return { deps, urls, vars };
}
export function parseKotlinSource(
input: string,
initVars: PackageVariables = {},
packageFile = '',
): { vars: PackageVariables; deps: PackageDependency<GradleManagerData>[] } {
let vars: PackageVariables = { ...initVars };
const deps: PackageDependency<GradleManagerData>[] = [];
const query = q.tree<Ctx>({
type: 'root-tree',
maxDepth: 1,
search: qKotlinMultiObjectVarAssignment,
});
const parsedResult = groovy.query(input, query, {
...ctx,
packageFile,
globalVars: vars,
});
if (parsedResult) {
deps.push(...parsedResult.deps);
vars = { ...vars, ...parsedResult.globalVars };
}
return { deps, vars };
}
export function parseJavaToolchainVersion(input: string): string | null {
const ctx: Partial<Ctx> = {};
const parsedResult = groovy.query(input, qToolchainVersion, ctx);
return parsedResult?.javaLanguageVersion ?? null;
}
const propWord = '[a-zA-Z_][a-zA-Z0-9_]*(?:\\.[a-zA-Z_][a-zA-Z0-9_]*)*';
const propRegex = regEx(
`^(?<leftPart>\\s*(?<key>${propWord})\\s*[= :]\\s*['"]?)(?<value>[^\\s'"]+)['"]?\\s*$`,
);
export function parseProps(
input: string,
packageFile?: string,
): { vars: PackageVariables; deps: PackageDependency<GradleManagerData>[] } {
let offset = 0;
const vars: PackageVariables = {};
const deps: PackageDependency<GradleManagerData>[] = [];
for (const line of input.split(newlineRegex)) {
const lineMatch = propRegex.exec(line);
if (lineMatch?.groups) {
const { key, value, leftPart } = lineMatch.groups;
const replacePosition = offset + leftPart.length;
const dep = parseDependencyString(value);
if (dep) {
deps.push({
...dep,
managerData: {
fileReplacePosition: replacePosition + dep.depName!.length + 1,
packageFile,
},
});
} else {
vars[key] = {
key,
value,
fileReplacePosition: replacePosition,
packageFile,
};
}
}
offset += line.length + 1;
}
return { vars, deps };
}