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 = {}, recursionDepth = 0, ): ParseGradleResult { let vars: PackageVariables = { ...initVars }; const deps: PackageDependency[] = []; const urls: PackageRegistry[] = []; const query = q.tree({ type: 'root-tree', search: q.alt( 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[] } { let vars: PackageVariables = { ...initVars }; const deps: PackageDependency[] = []; const query = q.tree({ 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 = {}; 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( `^(?\\s*(?${propWord})\\s*[= :]\\s*['"]?)(?[^\\s'"]+)['"]?\\s*$`, ); export function parseProps( input: string, packageFile?: string, ): { vars: PackageVariables; deps: PackageDependency[] } { let offset = 0; const vars: PackageVariables = {}; const deps: PackageDependency[] = []; 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 }; }