diff --git a/lib/manager/gradle/build-gradle.ts b/lib/manager/gradle/build-gradle.ts index 7445665dcdc6026a83a1dfd1366ce5dca3fe0c26..787a6977f5f548201aafb2ba29acda09a53a7341 100644 --- a/lib/manager/gradle/build-gradle.ts +++ b/lib/manager/gradle/build-gradle.ts @@ -47,46 +47,60 @@ function kotlinPluginStringVersionFormatMatch( ); } -function moduleMapVersionFormatMatch(dependency: GradleDependency): RegExp { - // prettier-ignore - return new RegExp( - `(group\\s*:\\s*${groovyQuotes}${dependency.group}${groovyQuotes}\\s*,\\s*` + - `name\\s*:\\s*${groovyQuotes}${dependency.name}${groovyQuotes}\\s*,\\s*` + - `version\\s*:\\s*${groovyQuotes})[^{}$"']+?(${groovyQuotes})` - ); +function allMapFormatOrders( + group: string, + name: string, + version: string, + prefix: string, + postfix: string +): RegExp[] { + const comma = '\\s*,\\s*'; + return [ + `${group}${comma}${name}${comma}${version}`, + `${group}${comma}${version}${comma}${name}`, + `${name}${comma}${group}${comma}${version}`, + `${version}${comma}${group}${comma}${name}`, + `${name}${comma}${version}${comma}${group}`, + `${version}${comma}${name}${comma}${group}`, + ].map(regex => new RegExp(`${prefix}${regex}${postfix}`)); +} + +function moduleMapVersionFormatMatch(dependency: GradleDependency): RegExp[] { + // two captures groups: start and end. The version is in between them + const group = `group\\s*:\\s*${groovyQuotes}${dependency.group}${groovyQuotes}`; + const name = `name\\s*:\\s*${groovyQuotes}${dependency.name}${groovyQuotes}`; + const version = `version\\s*:\\s*${groovyQuotes})[^{}$"']+?(${groovyQuotes}`; + return allMapFormatOrders(group, name, version, '(', ')'); } function moduleKotlinNamedArgumentVersionFormatMatch( dependency: GradleDependency -): RegExp { - // prettier-ignore - return new RegExp( - `(group\\s*=\\s*"${dependency.group}"\\s*,\\s*` + - `name\\s*=\\s*"${dependency.name}"\\s*,\\s*` + - `version\\s*=\\s*")[^{}$]*?(")` - ); +): RegExp[] { + // two captures groups: start and end. The version is in between them + const group = `group\\s*=\\s*"${dependency.group}"`; + const name = `name\\s*=\\s*"${dependency.name}"`; + const version = `version\\s*=\\s*")[^{}$]*?("`; + return allMapFormatOrders(group, name, version, '(', ')'); } function moduleMapVariableVersionFormatMatch( dependency: GradleDependency -): RegExp { - // prettier-ignore - return new RegExp( - `group\\s*:\\s*${groovyQuotes}${dependency.group}${groovyQuotes}\\s*,\\s*` + - `name\\s*:\\s*${groovyQuotes}${dependency.name}${groovyQuotes}\\s*,\\s*` + - `version\\s*:\\s*(?:${groovyQuotes}\\$)?{?([^\\s"'{}$)]+)}?${groovyQuotes}?\\s*` - ); +): RegExp[] { + // one capture group: the version variable + const group = `group\\s*:\\s*${groovyQuotes}${dependency.group}${groovyQuotes}`; + const name = `name\\s*:\\s*${groovyQuotes}${dependency.name}${groovyQuotes}`; + const version = `version\\s*:\\s*(?:${groovyQuotes}\\$)?{?([^\\s"'{}$)]+)}?${groovyQuotes}?`; + return allMapFormatOrders(group, name, version, '', ''); } function moduleKotlinNamedArgumentVariableVersionFormatMatch( dependency: GradleDependency -): RegExp { - // prettier-ignore - return new RegExp( - `group\\s*=\\s*"${dependency.group}"\\s*,\\s*` + - `name\\s*=\\s*"${dependency.name}"\\s*,\\s*` + - `version\\s*=\\s*(?:"\\$)?{?([^\\s"{}$]+?)}?"?[\\s\\),]` - ); +): RegExp[] { + // one capture group: the version variable + const group = `group\\s*=\\s*"${dependency.group}"`; + const name = `name\\s*=\\s*"${dependency.name}"`; + const version = `version\\s*=\\s*(?:"\\$)?{?([^\\s"{}$]+?)}?"?`; + return allMapFormatOrders(group, name, version, '', '[\\s),]'); } function moduleStringVariableInterpolationVersionFormatMatch( @@ -121,8 +135,8 @@ export function collectVersionVariables( const regexes = [ moduleStringVariableExpressionVersionFormatMatch(dependency), moduleStringVariableInterpolationVersionFormatMatch(dependency), - moduleMapVariableVersionFormatMatch(dependency), - moduleKotlinNamedArgumentVariableVersionFormatMatch(dependency), + ...moduleMapVariableVersionFormatMatch(dependency), + ...moduleKotlinNamedArgumentVariableVersionFormatMatch(dependency), ]; for (const regex of regexes) { @@ -147,8 +161,8 @@ function updateVersionLiterals( moduleStringVersionFormatMatch(dependency), groovyPluginStringVersionFormatMatch(dependency), kotlinPluginStringVersionFormatMatch(dependency), - moduleMapVersionFormatMatch(dependency), - moduleKotlinNamedArgumentVersionFormatMatch(dependency), + ...moduleMapVersionFormatMatch(dependency), + ...moduleKotlinNamedArgumentVersionFormatMatch(dependency), ]; for (const regex of regexes) { if (buildGradleContent.match(regex)) { @@ -164,10 +178,10 @@ function updateLocalVariables( newVersion: string ): string | null { const regexes: RegExp[] = [ - moduleMapVariableVersionFormatMatch(dependency), + ...moduleMapVariableVersionFormatMatch(dependency), moduleStringVariableInterpolationVersionFormatMatch(dependency), moduleStringVariableExpressionVersionFormatMatch(dependency), - moduleKotlinNamedArgumentVariableVersionFormatMatch(dependency), + ...moduleKotlinNamedArgumentVariableVersionFormatMatch(dependency), ]; for (const regex of regexes) { const match = buildGradleContent.match(regex); diff --git a/test/manager/gradle/build-gradle.spec.ts b/test/manager/gradle/build-gradle.spec.ts index eb4b9ab885c0f975fe81e241bd69dae8a2b91d29..3bc3114329cbcabf807938956cecd56b767e05a9 100644 --- a/test/manager/gradle/build-gradle.spec.ts +++ b/test/manager/gradle/build-gradle.spec.ts @@ -82,6 +82,22 @@ describe('lib/manager/gradle/updateGradleVersion', () => { ); }); + it('returns an updated file if the version in single quotes defined as map is found in a different order', () => { + const gradleFile = `compile name : 'mysql-connector-java', + group : 'mysql', + version: '6.0.5'`; + const updatedGradleFile = updateGradleVersion( + gradleFile, + { group: 'mysql', name: 'mysql-connector-java', version: '6.0.5' }, + '7.0.0' + ); + expect(updatedGradleFile).toEqual( + `compile name : 'mysql-connector-java', + group : 'mysql', + version: '7.0.0'` + ); + }); + it('returns an updated file if the version in double quotes defined as map is found', () => { const gradleFile = `compile group : 'mysql' , name : 'mysql-connector-java', @@ -98,6 +114,22 @@ describe('lib/manager/gradle/updateGradleVersion', () => { ); }); + it('returns an updated file if the version in double quotes defined as map is found in a different order', () => { + const gradleFile = `compile name : 'mysql-connector-java', + version: "6.0.5", + group : 'mysql'`; + const updatedGradleFile = updateGradleVersion( + gradleFile, + { group: 'mysql', name: 'mysql-connector-java', version: '6.0.5' }, + '7.0.0' + ); + expect(updatedGradleFile).toEqual( + `compile name : 'mysql-connector-java', + version: "7.0.0", + group : 'mysql'` + ); + }); + it('returns an updated file if the version in triple single quotes defined as map is found', () => { const gradleFile = `compile group : 'mysql' , name : 'mysql-connector-java', @@ -114,6 +146,22 @@ describe('lib/manager/gradle/updateGradleVersion', () => { ); }); + it('returns an updated file if the version in triple single quotes defined as map is found in a different order', () => { + const gradleFile = `compile version: '''6.0.5''', + group : 'mysql', + name : 'mysql-connector-java'`; + const updatedGradleFile = updateGradleVersion( + gradleFile, + { group: 'mysql', name: 'mysql-connector-java', version: '6.0.5' }, + '7.0.0' + ); + expect(updatedGradleFile).toEqual( + `compile version: '''7.0.0''', + group : 'mysql', + name : 'mysql-connector-java'` + ); + }); + it('returns an updated file if the version in triple double quotes defined as map is found', () => { const gradleFile = `compile group : 'mysql' , name : 'mysql-connector-java', @@ -130,6 +178,22 @@ describe('lib/manager/gradle/updateGradleVersion', () => { ); }); + it('returns an updated file if the version in triple double quotes defined as map is found in a different order', () => { + const gradleFile = `compile version: """6.0.5""", + name : 'mysql-connector-java', + group : 'mysql'`; + const updatedGradleFile = updateGradleVersion( + gradleFile, + { group: 'mysql', name: 'mysql-connector-java', version: '6.0.5' }, + '7.0.0' + ); + expect(updatedGradleFile).toEqual( + `compile version: """7.0.0""", + name : 'mysql-connector-java', + group : 'mysql'` + ); + }); + it('returns a file updated if the version defined as a Kotlin named argument is found', () => { const gradleFile = `compile(group = "mysql" , name = "mysql-connector-java", @@ -146,6 +210,22 @@ describe('lib/manager/gradle/updateGradleVersion', () => { ); }); + it('returns a file updated if the version defined as a Kotlin named argument is found in a different order', () => { + const gradleFile = `compile(group = "mysql", + version = "6.0.5", + name = "mysql-connector-java")`; + const updatedGradleFile = updateGradleVersion( + gradleFile, + { group: 'mysql', name: 'mysql-connector-java', version: '6.0.5' }, + '7.0.0' + ); + expect(updatedGradleFile).toEqual( + `compile(group = "mysql", + version = "7.0.0", + name = "mysql-connector-java")` + ); + }); + it('should returns a file updated if the version defined in a variable as a string is found', () => { const gradleFile = `String mysqlVersion= "6.0.5" runtime ( "mysql:mysql-connector-java:$mysqlVersion" ) @@ -194,6 +274,26 @@ describe('lib/manager/gradle/updateGradleVersion', () => { ); }); + it('should returns a file updated if the version defined in a variable as a map is found in a different order', () => { + const gradleFile = `String mysqlVersion = "6.0.5" + compile name : 'mysql-connector-java', + group : 'mysql' , + version : mysqlVersion + `; + const updatedGradleFile = updateGradleVersion( + gradleFile, + { group: 'mysql', name: 'mysql-connector-java', version: '6.0.5' }, + '7.0.0' + ); + expect(updatedGradleFile).toEqual( + `String mysqlVersion = "7.0.0" + compile name : 'mysql-connector-java', + group : 'mysql' , + version : mysqlVersion + ` + ); + }); + it('returns an updated file if the version defined in a variable in a simple template string without curly braces as a map is found', () => { const gradleFile = `String mysqlVersion = "6.0.5" compile group : 'mysql' , @@ -234,6 +334,26 @@ describe('lib/manager/gradle/updateGradleVersion', () => { ); }); + it('returns an updated file if the version defined in a variable in a simple template string with curly braces as a map is found in a different order', () => { + const gradleFile = `String mysqlVersion = "6.0.5" + compile name : 'mysql-connector-java', + version : "\${mysqlVersion}", + group : 'mysql' + `; + const updatedGradleFile = updateGradleVersion( + gradleFile, + { group: 'mysql', name: 'mysql-connector-java', version: '6.0.5' }, + '7.0.0' + ); + expect(updatedGradleFile).toEqual( + `String mysqlVersion = "7.0.0" + compile name : 'mysql-connector-java', + version : "\${mysqlVersion}", + group : 'mysql' + ` + ); + }); + it('returns an updated file if the version defined in a variable in a triple template string without curly braces as a map is found', () => { const gradleFile = `String mysqlVersion = "6.0.5" compile group : 'mysql' , @@ -294,6 +414,26 @@ describe('lib/manager/gradle/updateGradleVersion', () => { ); }); + it('should returns a file updated if the version defined in a variable as a Kotlin named argument is found in a different order', () => { + const gradleFile = `val mysqlVersion = "6.0.5" + compile(name = "mysql-connector-java", + group = "mysql" , + version = mysqlVersion) + `; + const updatedGradleFile = updateGradleVersion( + gradleFile, + { group: 'mysql', name: 'mysql-connector-java', version: '6.0.5' }, + '7.0.0' + ); + expect(updatedGradleFile).toEqual( + `val mysqlVersion = "7.0.0" + compile(name = "mysql-connector-java", + group = "mysql" , + version = mysqlVersion) + ` + ); + }); + it('returns an updated file if the version defined in a variable in a template string without curly braces as a Kotlin named argument is found', () => { const gradleFile = `val mysqlVersion = "6.0.5" compile(group = "mysql" , @@ -334,6 +474,26 @@ describe('lib/manager/gradle/updateGradleVersion', () => { ); }); + it('returns an updated file if the version defined in a variable in a template string with curly braces as a Kotlin named argument is found in a different order', () => { + const gradleFile = `val mysqlVersion = "6.0.5" + compile(version = "\${mysqlVersion}" , + name = "mysql-connector-java", + group = "mysql") + `; + const updatedGradleFile = updateGradleVersion( + gradleFile, + { group: 'mysql', name: 'mysql-connector-java', version: '6.0.5' }, + '7.0.0' + ); + expect(updatedGradleFile).toEqual( + `val mysqlVersion = "7.0.0" + compile(version = "\${mysqlVersion}" , + name = "mysql-connector-java", + group = "mysql") + ` + ); + }); + it('should replace a external groovy variable assigned to a specific dependency', () => { const gradleFile = 'runtime ( "mysql:mysql-connector-java:${mysqlVersion}" )'; // eslint-disable-line no-template-curly-in-string