diff --git a/lib/modules/manager/gradle/parser.spec.ts b/lib/modules/manager/gradle/parser.spec.ts index 222f37186ef55e638d53d0d5dfd4c5832346985f..6f778f563fe97b5db502064a823cfd801b144cf7 100644 --- a/lib/modules/manager/gradle/parser.spec.ts +++ b/lib/modules/manager/gradle/parser.spec.ts @@ -1053,5 +1053,42 @@ describe('modules/manager/gradle/parser', () => { ], }); }); + + it('imported objects', () => { + const input = codeBlock` + object ModuleConfiguration { + object Build { + object Database { + const val h2Version = "2.0.206" + } + } + } + `; + + const gradleKtsInput = codeBlock` + import ModuleConfiguration.Build.Database + dependencies { + runtimeOnly("com.h2database:h2:\${Database.h2Version}") + } + `; + + const { vars } = parseKotlinSource(input); + const res = parseGradle(gradleKtsInput, vars); + expect(res).toMatchObject({ + vars: { + 'ModuleConfiguration.Build.Database.h2Version': { + key: 'ModuleConfiguration.Build.Database.h2Version', + value: '2.0.206', + }, + }, + deps: [ + { + depName: 'com.h2database:h2', + currentValue: '2.0.206', + groupName: 'ModuleConfiguration.Build.Database.h2Version', + }, + ], + }); + }); }); }); diff --git a/lib/modules/manager/gradle/parser.ts b/lib/modules/manager/gradle/parser.ts index a3824ed8a2d0e7dab04c99f00a81589806e28919..5d5367baf56179e9592bfc56820f801a7150ab56 100644 --- a/lib/modules/manager/gradle/parser.ts +++ b/lib/modules/manager/gradle/parser.ts @@ -3,6 +3,7 @@ import { newlineRegex, regEx } from '../../../util/regex'; import type { PackageDependency } from '../types'; import { qApplyFrom } from './parser/apply-from'; import { qAssignments } from './parser/assignments'; +import { qKotlinImport } from './parser/common'; import { qDependencies, qLongFormDep } from './parser/dependencies'; import { setParseGradleFunc } from './parser/handlers'; import { qKotlinMultiObjectVarAssignment } from './parser/objects'; @@ -29,6 +30,7 @@ const ctx: Ctx = { registryUrls: [], varTokens: [], + tmpKotlinImportStore: [], tmpNestingDepth: [], tmpTokenStore: {}, tokenMap: {}, @@ -51,6 +53,7 @@ export function parseGradle( type: 'root-tree', maxDepth: 32, search: q.alt<Ctx>( + qKotlinImport, qAssignments, qDependencies, qPlugins, diff --git a/lib/modules/manager/gradle/parser/common.spec.ts b/lib/modules/manager/gradle/parser/common.spec.ts index 6915f7339d4b3a84a1b80c093d59651a11eea1b5..589130e4983b5c0223e52c9ebdad7c9a44b4d555 100644 --- a/lib/modules/manager/gradle/parser/common.spec.ts +++ b/lib/modules/manager/gradle/parser/common.spec.ts @@ -30,6 +30,7 @@ describe('modules/manager/gradle/parser/common', () => { registryUrls: [], varTokens: [], + tmpKotlinImportStore: [], tmpNestingDepth: [], tmpTokenStore: {}, tokenMap: {}, @@ -139,6 +140,11 @@ describe('modules/manager/gradle/parser/common', () => { ctx.tmpNestingDepth = []; expect(findVariable('foo', ctx)).toStrictEqual(ctx.globalVars['foo']); + + ctx.tmpKotlinImportStore = [[token, token]]; + expect(findVariable('test.foo3', ctx)).toStrictEqual( + ctx.globalVars['test.test.foo3'] + ); }); it('interpolateString', () => { diff --git a/lib/modules/manager/gradle/parser/common.ts b/lib/modules/manager/gradle/parser/common.ts index a57da4f9fddbdb4b3a1a4fb9689dd756e048908f..da60daa174f2841564355fc424839bdf0aa2d035 100644 --- a/lib/modules/manager/gradle/parser/common.ts +++ b/lib/modules/manager/gradle/parser/common.ts @@ -112,6 +112,31 @@ export function coalesceVariable(ctx: Ctx): Ctx { return ctx; } +export function findVariableInKotlinImport( + name: string, + ctx: Ctx, + variables: PackageVariables +): VariableData | undefined { + if (ctx.tmpKotlinImportStore.length && name.includes('.')) { + for (const tokens of ctx.tmpKotlinImportStore) { + const lastToken = tokens[tokens.length - 1]; + if (lastToken && name.startsWith(`${lastToken.value}.`)) { + const prefix = tokens + .slice(0, -1) + .map((token) => token.value) + .join('.'); + const identifier = `${prefix}.${name}`; + + if (variables[identifier]) { + return variables[identifier]; + } + } + } + } + + return undefined; +} + export function findVariable( name: string, ctx: Ctx, @@ -129,7 +154,11 @@ export function findVariable( } } - return variables[name]; + if (variables[name]) { + return variables[name]; + } + + return findVariableInKotlinImport(name, ctx, variables); } export function interpolateString( @@ -271,3 +300,14 @@ export const qValueMatcher = qConcatExpr( qPropertyAccessIdentifier, qVariableAccessIdentifier ); + +// import foo.bar +// runtimeOnly("some:foo:${bar.bazVersion}") +export const qKotlinImport = q + .sym<Ctx>('import') + .join(qVariableAssignmentIdentifier) + .handler((ctx) => { + ctx.tmpKotlinImportStore.push(ctx.varTokens); + return ctx; + }) + .handler(cleanupTempVars); diff --git a/lib/modules/manager/gradle/types.ts b/lib/modules/manager/gradle/types.ts index 7222c36345aa7111d232dcd6d34665ff9b9bb92f..74dfd059c9823590982a2961979e8677bd4419b0 100644 --- a/lib/modules/manager/gradle/types.ts +++ b/lib/modules/manager/gradle/types.ts @@ -82,6 +82,7 @@ export interface Ctx { registryUrls: PackageRegistry[]; varTokens: lexer.Token[]; + tmpKotlinImportStore: lexer.Token[][]; tmpNestingDepth: lexer.Token[]; tmpTokenStore: Record<string, lexer.Token[]>; tokenMap: Record<string, lexer.Token[]>;