diff --git a/README.md b/README.md index 73493de..50df934 100644 --- a/README.md +++ b/README.md @@ -165,6 +165,15 @@ successfully updated. will check the *.gradle files as they were when the gradle build started, which means that it can not pick up the changes applied by `useLatestVersions`. +## Updating only specific dependencies +If your Gradle version is 4.6 or higher, you can pass the `--update-dependency` flag to `useLatestVersions` and +`useLatestVersionsCheck` with a value in the format `$GROUP:$NAME`. Multiple dependencies can be updated by passing +the flag multiple times. + +```bash +# gradle useLatestVersions --update-dependency junit:junit --update-dependency com.google.guava:guava && gradle useLatestVersionsCheck --update-dependency junit:junit --update-dependency com.google.guava:guava +``` + ## Supported dependency formats Dependencies stated in the following formats should cause the version to be successfully updated by the diff --git a/src/main/groovy/se/patrikerdes/UseLatestVersionsCheckTask.groovy b/src/main/groovy/se/patrikerdes/UseLatestVersionsCheckTask.groovy index d853548..6a80d3b 100644 --- a/src/main/groovy/se/patrikerdes/UseLatestVersionsCheckTask.groovy +++ b/src/main/groovy/se/patrikerdes/UseLatestVersionsCheckTask.groovy @@ -5,10 +5,15 @@ 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 @CompileStatic class UseLatestVersionsCheckTask extends DefaultTask { + @Option(option='update-dependency', + description = 'The same argument that was passed to useLatestVersions') + List updateWhitelist = Collections.emptyList() + UseLatestVersionsCheckTask() { description = 'Check if all available updates were successfully applied by the useLatestVersions task.' group = 'Help' @@ -31,12 +36,16 @@ class UseLatestVersionsCheckTask extends DefaultTask { List wasUpdateable = getOutDatedDependencies(previousDependencyUpdatesJson) List leftToUpdate = getOutDatedDependencies(currentDependencyUpdatesJson) - int failedCount = leftToUpdate.size() + int skippedCount = updateWhitelist.empty ? 0 : + leftToUpdate.count { !updateWhitelist.contains(it.groupAndName()) } as int + int failedCount = leftToUpdate.size() - skippedCount if (failedCount > 0) { println("useLatestVersions failed to update $failedCount ${deps(failedCount)} " + 'to the latest version:') for (dependencyUpdate in leftToUpdate) { - println(' - ' + dependencyUpdate) + if (skippedCount == 0 || updateWhitelist.contains(dependencyUpdate.groupAndName())) { + println(' - ' + dependencyUpdate) + } } } @@ -61,6 +70,16 @@ class UseLatestVersionsCheckTask extends DefaultTask { } } + if (skippedCount > 0) { + println("useLatestVersions skipped updating $skippedCount ${deps(skippedCount)} " + + 'not in --dependency-update:') + for (dependencyLeftToUpdate in leftToUpdate) { + if (!updateWhitelist.contains(dependencyLeftToUpdate.groupAndName())) { + println(' - ' + dependencyLeftToUpdate) + } + } + } + if (updatedCount == 0 && failedCount == 0) { println('useLatestVersions successfully did nothing; there was nothing to update') } diff --git a/src/main/groovy/se/patrikerdes/UseLatestVersionsTask.groovy b/src/main/groovy/se/patrikerdes/UseLatestVersionsTask.groovy index 0b8824c..f0150aa 100644 --- a/src/main/groovy/se/patrikerdes/UseLatestVersionsTask.groovy +++ b/src/main/groovy/se/patrikerdes/UseLatestVersionsTask.groovy @@ -6,6 +6,7 @@ import static se.patrikerdes.Common.getOutDatedDependencies import groovy.json.JsonSlurper import groovy.transform.CompileStatic import org.gradle.api.DefaultTask +import org.gradle.api.tasks.options.Option import org.gradle.api.tasks.TaskAction import java.nio.file.Files @@ -15,6 +16,10 @@ import java.util.regex.Pattern @CompileStatic class UseLatestVersionsTask extends DefaultTask { + @Option(option='update-dependency', + description = 'A whitelist of dependencies to update, in the format of group:name') + List updateWhitelist = Collections.emptyList() + UseLatestVersionsTask() { description = 'Updates module and plugin versions in all *.gradle and *.gradle.kts files to the latest ' + 'available versions.' @@ -53,7 +58,10 @@ class UseLatestVersionsTask extends DefaultTask { Object dependencyUpdatesJson = new JsonSlurper().parse(dependencyUpdatesJsonReportFile) - List dependecyUpdates = getOutDatedDependencies(dependencyUpdatesJson) + List dependencyUpdates = getOutDatedDependencies(dependencyUpdatesJson) + if (!updateWhitelist.empty) { + dependencyUpdates = dependencyUpdates.findAll { updateWhitelist.contains(it.groupAndName()) } + } List dependencyStables = getCurrentDependencies(dependencyUpdatesJson) @@ -64,9 +72,9 @@ class UseLatestVersionsTask extends DefaultTask { gradleFileContents[dotGradleFileName] = currentGradleFileContents } - updateModuleVersions(gradleFileContents, dotGradleFileNames, dependecyUpdates) - updatePluginVersions(gradleFileContents, dotGradleFileNames, dependecyUpdates) - updateVariables(gradleFileContents, dotGradleFileNames, dependecyUpdates, dependencyStables) + updateModuleVersions(gradleFileContents, dotGradleFileNames, dependencyUpdates) + updatePluginVersions(gradleFileContents, dotGradleFileNames, dependencyUpdates) + updateVariables(gradleFileContents, dotGradleFileNames, dependencyUpdates, dependencyStables) // Write all files back for (dotGradleFileName in dotGradleFileNames) { diff --git a/src/test/groovy/se/patrikerdes/BaseFunctionalTest.groovy b/src/test/groovy/se/patrikerdes/BaseFunctionalTest.groovy index ccf96c4..2781bb5 100644 --- a/src/test/groovy/se/patrikerdes/BaseFunctionalTest.groovy +++ b/src/test/groovy/se/patrikerdes/BaseFunctionalTest.groovy @@ -24,6 +24,20 @@ class BaseFunctionalTest extends Specification { .build() } + BuildResult useLatestVersionsOnly(String update) { + useLatestVersionsOnly([update]) + } + + BuildResult useLatestVersionsOnly(List updates) { + List arguments = ['useLatestVersions'] + updates.each { arguments << '--update-dependency' << it } + GradleRunner.create() + .withProjectDir(testProjectDir.root) + .withArguments(arguments) + .withPluginClasspath() + .build() + } + BuildResult useLatestVersions(String gradleVersion) { GradleRunner.create() .withProjectDir(testProjectDir.root) @@ -57,6 +71,20 @@ class BaseFunctionalTest extends Specification { .buildAndFail() } + BuildResult useLatestVersionsCheckOnly(String update) { + useLatestVersionsCheckOnly([update]) + } + + BuildResult useLatestVersionsCheckOnly(List updates) { + List arguments = ['useLatestVersionsCheck'] + updates.each { arguments << '--update-dependency' << it } + GradleRunner.create() + .withProjectDir(testProjectDir.root) + .withArguments(arguments) + .withPluginClasspath() + .build() + } + BuildResult clean() { GradleRunner.create() .withProjectDir(testProjectDir.root) diff --git a/src/test/groovy/se/patrikerdes/CheckFunctionalTest.groovy b/src/test/groovy/se/patrikerdes/CheckFunctionalTest.groovy index 620a4e3..dde2cb6 100644 --- a/src/test/groovy/se/patrikerdes/CheckFunctionalTest.groovy +++ b/src/test/groovy/se/patrikerdes/CheckFunctionalTest.groovy @@ -215,6 +215,38 @@ class CheckFunctionalTest extends BaseFunctionalTest { result.output.contains("- log4j:log4j [1.2.16 -> $CurrentVersions.LOG4J]") } + void "useLatestVersionsCheck notes skipped updates due to not being in --update-dependency"() { + given: + buildFile << """ + plugins { + id 'se.patrikerdes.use-latest-versions' + id 'com.github.ben-manes.versions' version '$CurrentVersions.VERSIONS' + } + + apply plugin: 'java' + + repositories { + mavenCentral() + } + + dependencies { + compile "log4j:log4j:1.2.16" + testCompile "junit:junit:3.0" + } + """ + + when: + useLatestVersionsOnly('log4j:log4j') + BuildResult result = useLatestVersionsCheckOnly('log4j:log4j') + + then: + result.task(':useLatestVersionsCheck').outcome == SUCCESS + result.output.contains("""useLatestVersions successfully updated 1 dependency to the latest version: + - log4j:log4j [1.2.16 -> $CurrentVersions.LOG4J]""") + result.output.contains("""useLatestVersions skipped updating 1 dependency not in --dependency-update: + - junit:junit [3.0 -> $CurrentVersions.JUNIT]""") + } + void "useLatestVersionsCheck outputs a special message when there was nothing to update"() { given: buildFile << """ diff --git a/src/test/groovy/se/patrikerdes/ModuleUpdatesFunctionalTest.groovy b/src/test/groovy/se/patrikerdes/ModuleUpdatesFunctionalTest.groovy index e101831..e2d6153 100644 --- a/src/test/groovy/se/patrikerdes/ModuleUpdatesFunctionalTest.groovy +++ b/src/test/groovy/se/patrikerdes/ModuleUpdatesFunctionalTest.groovy @@ -331,4 +331,33 @@ class ModuleUpdatesFunctionalTest extends BaseFunctionalTest { updatedBuildFile.contains("dependency \"junit:junit:$CurrentVersions.JUNIT\"") updatedBuildFile.contains("dependencySet(group: 'log4j', version: \"$CurrentVersions.LOG4J\")") } + + void "only updates whitelisted dependencies with --update-dependency"() { + 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:4.0:javadoc@jar" + compile "log4j:log4j:1.2.16" + } + """ + + when: + useLatestVersionsOnly('log4j:log4j') + String updatedBuildFile = buildFile.getText('UTF-8') + + then: + updatedBuildFile.contains('testCompile \"junit:junit:4.0:javadoc@jar\"') + updatedBuildFile.contains("compile \"log4j:log4j:$CurrentVersions.LOG4J\"") + } }