Skip to content

Commit

Permalink
feat(gradle): gradle plugin dependency versions in variables (#6063) (#…
Browse files Browse the repository at this point in the history
…6064)

* feat(gradle): gradle plugin dependency versions in variables (#6063)

* chore: Replace uses of RegExp with util/regEx in build-gradle.ts

Co-authored-by: Jamie Magee <JamieMagee@users.noreply.github.com>
  • Loading branch information
Janosch Hildebrand and JamieMagee committed Apr 29, 2020
1 parent 4f79d79 commit 324ce13
Show file tree
Hide file tree
Showing 2 changed files with 143 additions and 26 deletions.
83 changes: 83 additions & 0 deletions lib/manager/gradle/build-gradle.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,70 @@ describe('lib/manager/gradle/updateGradleVersion', () => {
);
});

it('returns an updated file if the plugin version defined in a variable is found', () => {
const gradleFile = `val mysqlVersion = "6.0.5"
id("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"
id("mysql") version mysqlVersion
`
);
});

it('returns an updated file if the plugin version defined in a variable in a template string without curly braces is found', () => {
const gradleFile = `val mysqlVersion = "6.0.5"
id("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"
id("mysql") version "$mysqlVersion"
`
);
});

it('returns an updated file if the plugin version defined in a variable in a template string with curly braces is found', () => {
const gradleFile = `val mysqlVersion = "6.0.5"
id("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"
id("mysql") version "\${mysqlVersion}"
`
);
});

it('returns an updated file if the plugin version defined in a variable in a template string with triple double quotes is found', () => {
const gradleFile = `String mysqlVersion = "6.0.5"
id '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"
id 'mysql' version """$mysqlVersion"""
`
);
});

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
Expand Down Expand Up @@ -706,4 +770,23 @@ describe('lib/manager/gradle/updateGradleVersion', () => {
);
expect(updatedGradleFile).toEqual('val mysqlVersion by extra { "7.0.0" }');
});

it('should replace a external variable assigned to a plugin dependency', () => {
const gradleFile = 'id("mysql") version "$mysqlVersion";';
const mysqlDependency = {
group: 'mysql',
depGroup: 'mysql',
name: 'mysql-connector-java',
version: '6.0.5',
};
collectVersionVariables([mysqlDependency], gradleFile);

const gradleWithVersionFile = 'String mysqlVersion = "6.0.5"';
const updatedGradleFile = updateGradleVersion(
gradleWithVersionFile,
mysqlDependency,
'7.0.0'
);
expect(updatedGradleFile).toEqual('String mysqlVersion = "7.0.0"');
});
});
86 changes: 60 additions & 26 deletions lib/manager/gradle/build-gradle.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { BuildDependency } from './gradle-updates-report';
import { regEx } from '../../util/regex';

/**
* Functions adapted/ported from https://github.com/patrikerdes/gradle-use-latest-versions-plugin
Expand All @@ -23,28 +24,28 @@ interface UpdateFunction {
}

const groovyQuotes = `(?:["'](?:""|'')?)`;
const groovyVersionVariable = `(?:${groovyQuotes}\\$)?{?([^\\s"'{}$)]+)}?${groovyQuotes}?`;
const kotlinVersionVariable = `(?:"\\$)?{?([^\\s"{}$]+?)}?"?`;

// https://github.com/patrikerdes/gradle-use-latest-versions-plugin/blob/8cf9c3917b8b04ba41038923cab270d2adda3aa6/src/main/groovy/se/patrikerdes/DependencyUpdate.groovy#L27-L29
function moduleStringVersionFormatMatch(dependency: GradleDependency): RegExp {
return new RegExp(
return regEx(
`(${groovyQuotes}${dependency.group}:${dependency.name}:)[^$].*?(([:@].*?)?${groovyQuotes})`
);
}

function groovyPluginStringVersionFormatMatch(
dependency: GradleDependency
): RegExp {
return new RegExp(
`(id\\s+${groovyQuotes}${dependency.group}${groovyQuotes}\\s+version\\s+${groovyQuotes})[^$].*?(${groovyQuotes})`
return regEx(
`(id\\s+${groovyQuotes}${dependency.group}${groovyQuotes}\\s+version\\s+${groovyQuotes})[^"$].*?(${groovyQuotes})`
);
}

function kotlinPluginStringVersionFormatMatch(
dependency: GradleDependency
): RegExp {
return new RegExp(
`(id\\("${dependency.group}"\\)\\s+version\\s+")[^$].*?(")`
);
return regEx(`(id\\("${dependency.group}"\\)\\s+version\\s+")[^$].*?(")`);
}

function allMapFormatOrders(
Expand All @@ -62,7 +63,7 @@ function allMapFormatOrders(
`${version}${comma}${group}${comma}${name}`,
`${name}${comma}${version}${comma}${group}`,
`${version}${comma}${name}${comma}${group}`,
].map((regex) => new RegExp(`${prefix}${regex}${postfix}`));
].map((regex) => regEx(`${prefix}${regex}${postfix}`));
}

function moduleMapVersionFormatMatch(dependency: GradleDependency): RegExp[] {
Expand All @@ -89,7 +90,7 @@ function moduleMapVariableVersionFormatMatch(
// 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}?`;
const version = `version\\s*:\\s*${groovyVersionVariable}`;
return allMapFormatOrders(group, name, version, '', '');
}

Expand All @@ -99,36 +100,52 @@ function moduleKotlinNamedArgumentVariableVersionFormatMatch(
// 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"{}$]+?)}?"?`;
const version = `version\\s*=\\s*${kotlinVersionVariable}`;
return allMapFormatOrders(group, name, version, '', '[\\s),]');
}

function moduleStringVariableInterpolationVersionFormatMatch(
dependency: GradleDependency
): RegExp {
return new RegExp(
return regEx(
`${groovyQuotes}${dependency.group}:${dependency.name}:\\$([^{].*?)${groovyQuotes}`
);
}

function moduleStringVariableExpressionVersionFormatMatch(
dependency: GradleDependency
): RegExp {
return new RegExp(
return regEx(
`${groovyQuotes}${dependency.group}:${dependency.name}:\\$` +
`{([^{].*?)}${groovyQuotes}`
);
}

function groovyPluginVariableVersionFormatMatch(
dependency: GradleDependency
): RegExp {
return regEx(
`id\\s+${groovyQuotes}${dependency.group}${groovyQuotes}\\s+version\\s+${groovyVersionVariable}(?:\\s|;|})`
);
}

function kotlinPluginVariableVersionFormatMatch(
dependency: GradleDependency
): RegExp {
return regEx(
`id\\("${dependency.group}"\\)\\s+version\\s+${kotlinVersionVariable}(?:\\s|;|})`
);
}

function variableDefinitionFormatMatch(variable: string): RegExp {
return new RegExp(`(${variable}\\s*=\\s*?["'])(.*)(["'])`);
return regEx(`(${variable}\\s*=\\s*?["'])(.*)(["'])`);
}

function variableMapDefinitionFormatMatch(
variable: string,
version: string
): RegExp {
return new RegExp(`(${variable}\\s*:\\s*?["'])(${version})(["'])`);
return regEx(`(${variable}\\s*:\\s*?["'])(${version})(["'])`);
}

export function collectVersionVariables(
Expand All @@ -143,6 +160,8 @@ export function collectVersionVariables(
const regexes = [
moduleStringVariableExpressionVersionFormatMatch(dependency),
moduleStringVariableInterpolationVersionFormatMatch(dependency),
groovyPluginVariableVersionFormatMatch(dependency),
kotlinPluginVariableVersionFormatMatch(dependency),
...moduleMapVariableVersionFormatMatch(dependency),
...moduleKotlinNamedArgumentVariableVersionFormatMatch(dependency),
];
Expand Down Expand Up @@ -173,8 +192,12 @@ function updateVersionLiterals(
...moduleKotlinNamedArgumentVersionFormatMatch(dependency),
];
for (const regex of regexes) {
if (regex.test(buildGradleContent)) {
return buildGradleContent.replace(regex, `$1${newVersion}$2`);
const match = regex.exec(buildGradleContent);
if (match) {
return buildGradleContent.replace(
match[0],
`${match[1]}${newVersion}${match[2]}`
);
}
}
return null;
Expand All @@ -189,15 +212,23 @@ function updateLocalVariables(
...moduleMapVariableVersionFormatMatch(dependency),
moduleStringVariableInterpolationVersionFormatMatch(dependency),
moduleStringVariableExpressionVersionFormatMatch(dependency),
groovyPluginVariableVersionFormatMatch(dependency),
kotlinPluginVariableVersionFormatMatch(dependency),
...moduleKotlinNamedArgumentVariableVersionFormatMatch(dependency),
];
for (const regex of regexes) {
const match = regex.exec(buildGradleContent);
if (match) {
return buildGradleContent.replace(
variableDefinitionFormatMatch(match[1]),
`$1${newVersion}$3`
const variableDefinitionRegex = variableDefinitionFormatMatch(match[1]);
const variableDefinitionMatch = variableDefinitionRegex.exec(
buildGradleContent
);
if (variableDefinitionMatch) {
return buildGradleContent.replace(
variableDefinitionMatch[0],
`${variableDefinitionMatch[1]}${newVersion}${variableDefinitionMatch[3]}`
);
}
}
}
return null;
Expand All @@ -214,8 +245,8 @@ function updateGlobalVariables(
const match = regex.exec(buildGradleContent);
if (match) {
return buildGradleContent.replace(
variableDefinitionFormatMatch(variable),
`$1${newVersion}$3`
match[0],
`${match[1]}${newVersion}${match[3]}`
);
}
}
Expand All @@ -237,8 +268,8 @@ function updateGlobalMapVariables(
const match = regex.exec(buildGradleContent);
if (match) {
return buildGradleContent.replace(
variableMapDefinitionFormatMatch(variable, dependency.version),
`$1${newVersion}$3`
match[0],
`${match[1]}${newVersion}${match[3]}`
);
}

Expand All @@ -256,12 +287,15 @@ function updateKotlinVariablesByExtra(
): string | null {
const variable = variables[`${dependency.group}:${dependency.name}`];
if (variable) {
const regex = new RegExp(
const regex = regEx(
`(val ${variable} by extra(?: {|\\()\\s*")(.*)("\\s*[})])`
);
const match = regex.exec(buildGradleContent);
if (match) {
return buildGradleContent.replace(regex, `$1${newVersion}$3`);
return buildGradleContent.replace(
match[0],
`${match[1]}${newVersion}${match[3]}`
);
}
}
return null;
Expand All @@ -274,10 +308,10 @@ function updatePropertyFileGlobalVariables(
): string | null {
const variable = variables[`${dependency.group}:${dependency.name}`];
if (variable) {
const regex = new RegExp(`(${variable}\\s*=\\s*)(.*)`);
const regex = regEx(`(${variable}\\s*=\\s*)(.*)`);
const match = regex.exec(buildGradleContent);
if (match) {
return buildGradleContent.replace(regex, `$1${newVersion}`);
return buildGradleContent.replace(match[0], `${match[1]}${newVersion}`);
}
}
return null;
Expand Down

0 comments on commit 324ce13

Please sign in to comment.