From 0ce7e59e75975fb0bf5f3237eb684887cebe76ea Mon Sep 17 00:00:00 2001 From: asodja Date: Tue, 26 May 2020 22:30:04 +0200 Subject: [PATCH] Add support to update root gradle.properties --- README.md | 35 ++- src/main/groovy/se/patrikerdes/Common.groovy | 38 ++- .../InternalAggregateRootTask.groovy | 69 +++++ .../UseLatestVersionsPlugin.groovy | 35 ++- .../patrikerdes/UseLatestVersionsTask.groovy | 70 +++-- .../se/patrikerdes/BaseFunctionalTest.groovy | 8 + .../se/patrikerdes/CurrentVersions.groovy | 1 + .../VariableUpdatesFunctionalTest.groovy | 274 ++++++++++++++++++ 8 files changed, 490 insertions(+), 40 deletions(-) create mode 100644 src/main/groovy/se/patrikerdes/InternalAggregateRootTask.groovy diff --git a/README.md b/README.md index 60d70e1..8adc2db 100644 --- a/README.md +++ b/README.md @@ -75,6 +75,24 @@ apply { ``` +### Multi-project usage +In case you have a Multi-project build and you have some common dependency configuration in some common file in root project +(like *.gradle file), you should apply plugin to all projects. Easiest way to do this is with `allprojects` block like: +``` +plugins { + id 'se.patrikerdes.use-latest-versions' version '0.2.13' + id 'com.github.ben-manes.versions' version '0.21.0' +} + +allprojects { + apply plugin: 'se.patrikerdes.use-latest-versions' + apply plugin: 'com.github.ben-manes.versions' +} +``` +This is because `se.patrikerdes.use-latest-versions` plugin scans files for every project separately. + +In case you handle dependencies per project separately this is not needed and you can apply plugin just to selected projects. + ## Example Given this build.gradle file: @@ -143,7 +161,22 @@ dependencies { ### useLatestVersions ```bash -# gradle useLatestVersions +gradle useLatestVersions + +# Configuration and default values: +useLatestVersions { + # A whitelist of dependencies to update, in the format of group:name + # Equal to command line: --update-dependency=[values] + updateWhitelist = [] + # A blacklist of dependencies to update, in the format of group:name + # Equal to command line: --ignore-dependency=[values] + updateBlacklist = [] + # When enabled, root project gradle.properties will also be populated with + # versions from subprojects in multi-project build + # Equal to command line: --update-root-properties + updateRootProperties = false +} + ``` Updates module and plugin versions in all *.gradle files in the project root folder or any subfolder to the latest diff --git a/src/main/groovy/se/patrikerdes/Common.groovy b/src/main/groovy/se/patrikerdes/Common.groovy index 1fb8786..3c18a11 100644 --- a/src/main/groovy/se/patrikerdes/Common.groovy +++ b/src/main/groovy/se/patrikerdes/Common.groovy @@ -6,6 +6,7 @@ import org.gradle.api.Task import java.nio.file.Paths import java.util.regex.Matcher +import java.util.regex.Pattern @CompileStatic class Common { @@ -48,7 +49,9 @@ class Common { static void getVariablesFromMatches(Matcher variableMatch, Map versionVariables, DependencyUpdate update, Set problemVariables) { - if (variableMatch.size() == 1) { + // File can have more dependencies with same version variable + // We anyway check that versions of dependencies for that variable are the same + if (variableMatch.size() >= 1) { String variableName = ((List) variableMatch[0])[1] if (versionVariables.containsKey(variableName) && versionVariables[variableName as String] != update.newVersion) { @@ -117,5 +120,38 @@ class Common { } outputDir } + + static void updateVersionVariables(Map gradleFileContents, List dotGradleFileNames, + Map versionVariables) { + for (String dotGradleFileName in dotGradleFileNames) { + for (versionVariable in versionVariables) { + gradleFileContents[dotGradleFileName] = + gradleFileContents[dotGradleFileName].replaceAll( + variableDefinitionMatchStringForFileName(versionVariable.key, dotGradleFileName), + newVariableDefinitionString(versionVariable.value)) + } + } + } + + static String variableDefinitionMatchStringForFileName(String variable, String fileName) { + String splitter = File.separator.replace('\\', '\\\\') + if (fileName.split(splitter).last() == 'gradle.properties') { + return gradlePropertiesVariableDefinitionMatchString(variable) + } + variableDefinitionMatchString(variable) + } + + static String variableDefinitionMatchString(String variable) { + '(' + Pattern.quote(variable) + "[ \t]*=[ \t]*[\"'])(.*)([\"'])" + } + + static String gradlePropertiesVariableDefinitionMatchString(String variable) { + '(' + Pattern.quote(variable) + '[ \t]*=[ \t]*)(.*)([ \t]*)' + } + + static String newVariableDefinitionString(String newVersion) { + '$1' + newVersion + '$3' + } + } diff --git a/src/main/groovy/se/patrikerdes/InternalAggregateRootTask.groovy b/src/main/groovy/se/patrikerdes/InternalAggregateRootTask.groovy new file mode 100644 index 0000000..a4fcd49 --- /dev/null +++ b/src/main/groovy/se/patrikerdes/InternalAggregateRootTask.groovy @@ -0,0 +1,69 @@ +package se.patrikerdes + +import static se.patrikerdes.UseLatestVersionsPlugin.USE_LATEST_VERSIONS + +import org.gradle.api.Project +import groovy.json.JsonSlurper +import org.gradle.api.DefaultTask +import org.gradle.api.tasks.TaskAction + +class InternalAggregateRootTask extends DefaultTask { + + InternalAggregateRootTask() { + description = 'Internal task that aggregates versions of all projects to root. ' + + 'Currently it updates just gradle.properties in root. Don\'t run it as separate task' + } + + @TaskAction + void internalAggregateRootTask() { + List versionVariablesFiles = project.gradle.taskGraph.allTasks + .findAll { it.name == USE_LATEST_VERSIONS } + .collectMany { getVersionVariablesFiles(it.project) } + List dotGradleFileNames = + new FileNameFinder().getFileNames(project.projectDir.absolutePath, 'gradle.properties') + + Map gradleFileContents = dotGradleFileNames.collectEntries { + [(it): new File(it).getText('UTF-8')] + } + Map versionVariables = readVersionVariables(versionVariablesFiles) + Common.updateVersionVariables(gradleFileContents, dotGradleFileNames, versionVariables) + + // Write all files back + for (dotGradleFileName in dotGradleFileNames) { + new File(dotGradleFileName).setText(gradleFileContents[dotGradleFileName], 'UTF-8') + } + + // Delete temp files in build folder + for (String versionVariablesFile in versionVariablesFiles) { + new File(versionVariablesFile).delete() + } + } + + List getVersionVariablesFiles(Project project) { + String buildDir = project.buildDir.absolutePath + new FileNameFinder().getFileNames(buildDir, 'useLatestVersions/version-variables.json') + } + + Map readVersionVariables(List versionVariablesFiles) { + Map versionVariables = [:] + List problemVariables = [] + for (String versionVariablesFile in versionVariablesFiles) { + Map variables = new JsonSlurper().parseText(new File(versionVariablesFile).text) + variables.forEach { k, v -> + if (versionVariables.containsKey(k) && versionVariables.get(k) != v) { + println("A problem was detected: the variable '$k' has different updated versions in different " + + "projects.\nNew updated versions are: '${versionVariables.get(k)}' and '$v', " + + "root gradle.properties value won't be be changed.") + problemVariables.add(k) + } else { + versionVariables.put(k, v) + } + } + } + for (problemVariable in problemVariables) { + versionVariables.remove(problemVariable) + } + versionVariables + } + +} diff --git a/src/main/groovy/se/patrikerdes/UseLatestVersionsPlugin.groovy b/src/main/groovy/se/patrikerdes/UseLatestVersionsPlugin.groovy index cf22588..1017982 100644 --- a/src/main/groovy/se/patrikerdes/UseLatestVersionsPlugin.groovy +++ b/src/main/groovy/se/patrikerdes/UseLatestVersionsPlugin.groovy @@ -3,12 +3,43 @@ package se.patrikerdes import groovy.transform.CompileStatic import org.gradle.api.Project import org.gradle.api.Plugin +import org.gradle.api.Task @CompileStatic class UseLatestVersionsPlugin implements Plugin { + + static final String DEPENDENCY_UPDATES = 'dependencyUpdates' + static final String USE_LATEST_VERSIONS = 'useLatestVersions' + static final String USE_LATEST_VERSIONS_CHECK = 'useLatestVersionsCheck' + static final String INTERNAL_ROOT_AGGREGATE = 'internalRootAggregate' + void apply(Project project) { System.setProperty('outputFormatter', 'json,xml,plain') - project.task('useLatestVersions', type: UseLatestVersionsTask, dependsOn: 'dependencyUpdates') - project.task('useLatestVersionsCheck', type: UseLatestVersionsCheckTask, dependsOn: 'dependencyUpdates') + Task rootAggregate = setupRootAggregateTask(project) + setupUseLatestVersions(project, rootAggregate) + setupUseLatestVersionsCheck(project) } + + Task setupRootAggregateTask(Project project) { + Set tasks = project.rootProject.getTasksByName(INTERNAL_ROOT_AGGREGATE, false) + if (tasks.isEmpty()) { + // This handles both cases: when UseLatestVersionsPlugin is applied + // to root project and subprojects or when it is applied only to subprojects + return project.rootProject.task(INTERNAL_ROOT_AGGREGATE, type: InternalAggregateRootTask) + } + tasks[0] + } + + void setupUseLatestVersions(Project project, Task rootAggregate) { + Task useLatestVersions = project.task(USE_LATEST_VERSIONS, type: UseLatestVersionsTask) + useLatestVersions.dependsOn(DEPENDENCY_UPDATES) + useLatestVersions.finalizedBy(rootAggregate) + rootAggregate.mustRunAfter(useLatestVersions) + } + + void setupUseLatestVersionsCheck(Project project) { + Task useLatestVersionCheck = project.task(USE_LATEST_VERSIONS_CHECK, type: UseLatestVersionsCheckTask) + useLatestVersionCheck.dependsOn(DEPENDENCY_UPDATES) + } + } diff --git a/src/main/groovy/se/patrikerdes/UseLatestVersionsTask.groovy b/src/main/groovy/se/patrikerdes/UseLatestVersionsTask.groovy index c044524..8c7c44c 100644 --- a/src/main/groovy/se/patrikerdes/UseLatestVersionsTask.groovy +++ b/src/main/groovy/se/patrikerdes/UseLatestVersionsTask.groovy @@ -5,18 +5,19 @@ import static se.patrikerdes.Common.getCurrentDependencies import static se.patrikerdes.Common.getDependencyUpdatesJsonReportFilePath import static se.patrikerdes.Common.getOutDatedDependencies +import org.gradle.api.Project +import groovy.json.JsonBuilder import groovy.json.JsonSlurper import groovy.transform.CompileStatic import org.gradle.api.DefaultTask import org.gradle.api.GradleException -import org.gradle.api.tasks.options.Option import org.gradle.api.tasks.TaskAction import org.gradle.api.tasks.Input +import org.gradle.api.tasks.options.Option import java.nio.file.Files import java.nio.file.StandardCopyOption import java.util.regex.Matcher -import java.util.regex.Pattern @CompileStatic class UseLatestVersionsTask extends DefaultTask { @@ -30,24 +31,17 @@ class UseLatestVersionsTask extends DefaultTask { description = 'A blacklist of dependencies to update, in the format of group:name') List updateBlacklist = Collections.emptyList() + @Input + @Option(option='update-root-properties', + description = 'Update root project gradle.properties with subprojects versions in multi-project build') + boolean updateRootProperties + UseLatestVersionsTask() { description = 'Updates module and plugin versions in all *.gradle and *.gradle.kts files to the latest ' + 'available versions.' group = 'Help' } - String variableDefinitionMatchString(String variable) { - '(' + Pattern.quote(variable) + "[ \t]*=[ \t]*[\"'])(.*)([\"'])" - } - - String gradlePropertiesVariableDefinitionMatchString(String variable) { - '(' + Pattern.quote(variable) + '[ \t]*=[ \t]*)(.*)([ \t]*)' - } - - String newVariableDefinitionString(String newVersion) { - '$1' + newVersion + '$3' - } - @TaskAction void useLatestVersions() { validateExclusiveWhiteOrBlacklist() @@ -59,6 +53,11 @@ class UseLatestVersionsTask extends DefaultTask { dotGradleFileNames += new FileNameFinder().getFileNames(project.projectDir.absolutePath, '**/*.gradle.kts') dotGradleFileNames += new FileNameFinder().getFileNames(project.projectDir.absolutePath, '**/gradle.properties') dotGradleFileNames += new FileNameFinder().getFileNames(project.projectDir.absolutePath, 'buildSrc/**/*.kt') + String rootGradleProperties = getRootGradlePropertiesPath(project) + if (rootGradleProperties && updateRootProperties && project != project.rootProject) { + // Append so we don't update variables if defined in multiple files + dotGradleFileNames += rootGradleProperties + } // Exclude any files that belong to sub-projects List subprojectPaths = project.subprojects.collect { it.projectDir.absolutePath } @@ -91,11 +90,22 @@ class UseLatestVersionsTask extends DefaultTask { updateModuleVersions(gradleFileContents, dotGradleFileNames, dependencyUpdates) updatePluginVersions(gradleFileContents, dotGradleFileNames, dependencyUpdates) - updateVariables(gradleFileContents, dotGradleFileNames, dependencyUpdates, dependencyStables) + Map versionVariables = getVersionVariables(gradleFileContents, dotGradleFileNames, + dependencyUpdates, dependencyStables) + Common.updateVersionVariables(gradleFileContents, dotGradleFileNames, versionVariables) // Write all files back for (dotGradleFileName in dotGradleFileNames) { - new File(dotGradleFileName).setText(gradleFileContents[dotGradleFileName], 'UTF-8') + if (dotGradleFileName != rootGradleProperties) { + // Root Gradle properties are handled in + // internalAggregateRoot task that reads version-variables.json + new File(dotGradleFileName).setText(gradleFileContents[dotGradleFileName], 'UTF-8') + } + } + + if (project == project.rootProject || updateRootProperties) { + new File(project.buildDir, 'useLatestVersions/version-variables.json') + .write(new JsonBuilder(versionVariables).toPrettyString()) } } @@ -143,12 +153,11 @@ class UseLatestVersionsTask extends DefaultTask { } } - void updateVariables(Map gradleFileContents, List dotGradleFileNames, + Map getVersionVariables(Map gradleFileContents, List dotGradleFileNames, List dependencyUpdates, List dependencyStables) { Set problemVariables = [] Map versionVariables = Common.findVariables(dotGradleFileNames, dependencyUpdates + dependencyStables, gradleFileContents, problemVariables) - for (problemVariable in problemVariables) { versionVariables.remove(problemVariable) } @@ -160,7 +169,7 @@ class UseLatestVersionsTask extends DefaultTask { for (String dotGradleFileName in dotGradleFileNames) { for (variableName in versionVariables.keySet()) { Matcher variableDefinitionMatch = gradleFileContents[dotGradleFileName] =~ - variableDefinitionMatchStringForFileName(variableName, dotGradleFileName) + Common.variableDefinitionMatchStringForFileName(variableName, dotGradleFileName) if (variableDefinitionMatch.size() == 1) { if (variableDefinitions.contains(variableName)) { // The variable is assigned to in more than one file @@ -183,23 +192,7 @@ class UseLatestVersionsTask extends DefaultTask { versionVariables.remove(problemVariable) } - // Update variables - for (String dotGradleFileName in dotGradleFileNames) { - for (versionVariable in versionVariables) { - gradleFileContents[dotGradleFileName] = - gradleFileContents[dotGradleFileName].replaceAll( - variableDefinitionMatchStringForFileName(versionVariable.key, dotGradleFileName), - newVariableDefinitionString(versionVariable.value)) - } - } - } - - String variableDefinitionMatchStringForFileName(String variable, String fileName) { - String splitter = File.separator.replace('\\', '\\\\') - if (fileName.split(splitter).last() == 'gradle.properties') { - return gradlePropertiesVariableDefinitionMatchString(variable) - } - variableDefinitionMatchString(variable) + versionVariables } void saveDependencyUpdatesReport(File dependencyUpdatesJsonReportFile) { @@ -212,6 +205,11 @@ class UseLatestVersionsTask extends DefaultTask { StandardCopyOption.REPLACE_EXISTING) } + private String getRootGradlePropertiesPath(Project project) { + File rootGradleProperties = new File(project.rootDir.absolutePath, 'gradle.properties') + rootGradleProperties.exists() ? rootGradleProperties.absolutePath : null + } + private void validateExclusiveWhiteOrBlacklist() { if (!updateWhitelist.empty && !updateBlacklist.empty) { throw new GradleException(WHITE_BLACKLIST_ERROR_MESSAGE) diff --git a/src/test/groovy/se/patrikerdes/BaseFunctionalTest.groovy b/src/test/groovy/se/patrikerdes/BaseFunctionalTest.groovy index 31b3214..5ddf7b1 100644 --- a/src/test/groovy/se/patrikerdes/BaseFunctionalTest.groovy +++ b/src/test/groovy/se/patrikerdes/BaseFunctionalTest.groovy @@ -63,6 +63,14 @@ class BaseFunctionalTest extends Specification { .buildAndFail() } + BuildResult useLatestVersionsUpdatingRootProperties() { + GradleRunner.create() + .withProjectDir(testProjectDir.root) + .withArguments('useLatestVersions', '--update-root-properties') + .withPluginClasspath() + .build() + } + BuildResult useLatestVersions(String gradleVersion) { GradleRunner.create() .withProjectDir(testProjectDir.root) diff --git a/src/test/groovy/se/patrikerdes/CurrentVersions.groovy b/src/test/groovy/se/patrikerdes/CurrentVersions.groovy index d592756..9666e80 100644 --- a/src/test/groovy/se/patrikerdes/CurrentVersions.groovy +++ b/src/test/groovy/se/patrikerdes/CurrentVersions.groovy @@ -3,5 +3,6 @@ package se.patrikerdes class CurrentVersions { public static final String VERSIONS = '0.28.0' public static final String JUNIT = '4.13' + public static final String JUNIT_DEPS = '4.11' public static final String LOG4J = '1.2.17' } diff --git a/src/test/groovy/se/patrikerdes/VariableUpdatesFunctionalTest.groovy b/src/test/groovy/se/patrikerdes/VariableUpdatesFunctionalTest.groovy index cf2f372..719588d 100644 --- a/src/test/groovy/se/patrikerdes/VariableUpdatesFunctionalTest.groovy +++ b/src/test/groovy/se/patrikerdes/VariableUpdatesFunctionalTest.groovy @@ -451,4 +451,278 @@ class VariableUpdatesFunctionalTest extends BaseFunctionalTest { updatedGradlePropertiesFile.contains("junit_version = $CurrentVersions.JUNIT") updatedGradlePropertiesFile.contains("log4j_version=$CurrentVersions.LOG4J") } + + void "will update variables in gradle properties when specified twice in build gradle"() { + given: + buildFile << """ + plugins { + id 'se.patrikerdes.use-latest-versions' + id 'com.github.ben-manes.versions' version '$CurrentVersions.VERSIONS' + } + + apply plugin: 'java' + + repositories { + mavenCentral() + } + + dependencies { + testCompile "junit:junit:\$junit_version" + testCompile "log4j:log4j:\$log4j_version" + runtimeOnly "log4j:log4j:\$log4j_version" + } + """ + File gradlePropertiesFile = testProjectDir.newFile('gradle.properties') + gradlePropertiesFile << ''' + junit_version = 4.0 + log4j_version=1.2.16 + ''' + + when: + useLatestVersions() + String updatedGradlePropertiesFile = gradlePropertiesFile.getText('UTF-8') + + then: + updatedGradlePropertiesFile.contains("junit_version = $CurrentVersions.JUNIT") + updatedGradlePropertiesFile.contains("log4j_version=$CurrentVersions.LOG4J") + } + + void "will not update variables in root gradle properties in Multi-project without --update-root-properties"() { + given: + buildFile << """ + plugins { + id 'se.patrikerdes.use-latest-versions' + id 'com.github.ben-manes.versions' version '$CurrentVersions.VERSIONS' + } + + allprojects { + apply plugin: 'se.patrikerdes.use-latest-versions' + apply plugin: 'com.github.ben-manes.versions' + apply plugin: 'java' + repositories { + mavenCentral() + } + } + """ + File rootGradlePropertiesFile = testProjectDir.newFile('gradle.properties') + rootGradlePropertiesFile << ''' + junit_version = 4.0 + log4j_version=1.2.16 + ''' + File rootGradleSettingsFile = testProjectDir.newFile('settings.gradle') + rootGradleSettingsFile << ''' + include 'sub-project' + ''' + File subProjectFolder = testProjectDir.newFolder('sub-project') + File subProjectBuildFile = new File(subProjectFolder, 'build.gradle') + subProjectBuildFile << ''' + dependencies { + testCompile "junit:junit:\$junit_version" + compile "log4j:log4j:\$log4j_version" + } + ''' + + when: + useLatestVersions() + + then: + String updatedGradlePropertiesFile = rootGradlePropertiesFile.getText('UTF-8') + updatedGradlePropertiesFile.contains('junit_version = 4.0') + updatedGradlePropertiesFile.contains('log4j_version=1.2.16') + } + + void "will update variables in root gradle properties for Multi-project build"() { + given: + buildFile << """ + plugins { + id 'se.patrikerdes.use-latest-versions' + id 'com.github.ben-manes.versions' version '$CurrentVersions.VERSIONS' + } + + allprojects { + apply plugin: 'se.patrikerdes.use-latest-versions' + apply plugin: 'com.github.ben-manes.versions' + apply plugin: 'java' + repositories { + mavenCentral() + } + } + """ + File rootGradlePropertiesFile = testProjectDir.newFile('gradle.properties') + rootGradlePropertiesFile << ''' + junit_version = 4.0 + log4j_version=1.2.16 + ''' + File rootGradleSettingsFile = testProjectDir.newFile('settings.gradle') + rootGradleSettingsFile << ''' + include 'sub-project' + ''' + File subProjectFolder = testProjectDir.newFolder('sub-project') + File subProjectBuildFile = new File(subProjectFolder, 'build.gradle') + subProjectBuildFile << ''' + dependencies { + testCompile "junit:junit:\$junit_version" + compile "log4j:log4j:\$log4j_version" + } + ''' + + when: + useLatestVersionsUpdatingRootProperties() + + then: + String updatedGradlePropertiesFile = rootGradlePropertiesFile.getText('UTF-8') + updatedGradlePropertiesFile.contains("junit_version = $CurrentVersions.JUNIT") + updatedGradlePropertiesFile.contains("log4j_version=$CurrentVersions.LOG4J") + } + + void "will update variables in root gradle properties for Multi-project when plugin applied to subproject only"() { + given: + buildFile << """ + plugins { + id 'se.patrikerdes.use-latest-versions' apply false + id 'com.github.ben-manes.versions' version '$CurrentVersions.VERSIONS' apply false + } + + subprojects { + apply plugin: 'se.patrikerdes.use-latest-versions' + apply plugin: 'com.github.ben-manes.versions' + apply plugin: 'java' + repositories { + mavenCentral() + } + } + """ + File rootGradlePropertiesFile = testProjectDir.newFile('gradle.properties') + rootGradlePropertiesFile << ''' + junit_version = 4.0 + log4j_version=1.2.16 + ''' + File rootGradleSettingsFile = testProjectDir.newFile('settings.gradle') + rootGradleSettingsFile << ''' + include 'sub-project' + ''' + File subProjectFolder = testProjectDir.newFolder('sub-project') + File subProjectBuildFile = new File(subProjectFolder, 'build.gradle') + subProjectBuildFile << ''' + dependencies { + testCompile "junit:junit:\$junit_version" + compile "log4j:log4j:\$log4j_version" + } + ''' + + when: + useLatestVersionsUpdatingRootProperties() + + then: + String updatedGradlePropertiesFile = rootGradlePropertiesFile.getText('UTF-8') + updatedGradlePropertiesFile.contains("junit_version = $CurrentVersions.JUNIT") + updatedGradlePropertiesFile.contains("log4j_version=$CurrentVersions.LOG4J") + } + + void "will update variables in root gradle properties for Multi-project when present in multiple projects"() { + given: + buildFile << """ + plugins { + id 'se.patrikerdes.use-latest-versions' + id 'com.github.ben-manes.versions' version '$CurrentVersions.VERSIONS' + } + + allprojects { + apply plugin: 'se.patrikerdes.use-latest-versions' + apply plugin: 'com.github.ben-manes.versions' + apply plugin: 'java' + repositories { + mavenCentral() + } + } + """ + File rootGradlePropertiesFile = testProjectDir.newFile('gradle.properties') + rootGradlePropertiesFile << ''' + junit_version = 4.0 + log4j_version=1.2.16 + ''' + File rootGradleSettingsFile = testProjectDir.newFile('settings.gradle') + rootGradleSettingsFile << ''' + include 'first-sub-project' + include 'second-sub-project' + ''' + File firstSubProjectFolder = testProjectDir.newFolder('first-sub-project') + File firstSubProjectBuildFile = new File(firstSubProjectFolder, 'build.gradle') + firstSubProjectBuildFile << ''' + dependencies { + testCompile "junit:junit:\$junit_version" + compile "log4j:log4j:\$log4j_version" + } + ''' + File secondSubProjectFolder = testProjectDir.newFolder('second-sub-project') + File secondSubProjectBuildFile = new File(secondSubProjectFolder, 'build.gradle') + secondSubProjectBuildFile << ''' + dependencies { + testCompile "junit:junit:\$junit_version" + compile "log4j:log4j:\$log4j_version" + } + ''' + + when: + useLatestVersionsUpdatingRootProperties() + + then: + String updatedGradlePropertiesFile = rootGradlePropertiesFile.getText('UTF-8') + updatedGradlePropertiesFile.contains("junit_version = $CurrentVersions.JUNIT") + updatedGradlePropertiesFile.contains("log4j_version=$CurrentVersions.LOG4J") + } + + void "will not update variables in root gradle properties for Multi-project when not resolved to same version"() { + given: + buildFile << """ + plugins { + id 'se.patrikerdes.use-latest-versions' apply false + id 'com.github.ben-manes.versions' version '$CurrentVersions.VERSIONS' apply false + } + + allprojects { + apply plugin: 'se.patrikerdes.use-latest-versions' + apply plugin: 'com.github.ben-manes.versions' + apply plugin: 'java' + repositories { + mavenCentral() + } + } + """ + File rootGradlePropertiesFile = testProjectDir.newFile('gradle.properties') + rootGradlePropertiesFile << ''' + junit_version = 4.0 + log4j_version=1.2.16 + ''' + File rootGradleSettingsFile = testProjectDir.newFile('settings.gradle') + rootGradleSettingsFile << ''' + include 'first-sub-project' + include 'second-sub-project' + ''' + File firstSubProjectFolder = testProjectDir.newFolder('first-sub-project') + File firstSubProjectBuildFile = new File(firstSubProjectFolder, 'build.gradle') + firstSubProjectBuildFile << ''' + dependencies { + testCompile "junit:junit:\$junit_version" + } + ''' + File secondSubProjectFolder = testProjectDir.newFolder('second-sub-project') + File secondSubProjectBuildFile = new File(secondSubProjectFolder, 'build.gradle') + secondSubProjectBuildFile << ''' + dependencies { + testCompile "junit:junit-dep:\$junit_version" + } + ''' + + when: + BuildResult result = useLatestVersionsUpdatingRootProperties() + + then: + String updatedGradlePropertiesFile = rootGradlePropertiesFile.getText('UTF-8') + updatedGradlePropertiesFile.contains('junit_version = 4.0') + result.output.contains("A problem was detected: the variable 'junit_version' has different updated versions " + + "in different projects.\nNew updated versions are: '$CurrentVersions.JUNIT' and " + + "'$CurrentVersions.JUNIT_DEPS', root gradle.properties value won't be be changed.") + } + }