From 092837a6d40f36e47c2becd0b032b00687bfb02d Mon Sep 17 00:00:00 2001 From: Jean-Michel Fayard Date: Mon, 9 Sep 2019 23:39:51 +0200 Subject: [PATCH] Implement #325 rejectVersionIf --- README.md | 116 +++++++++++++----- .../updates/DependencyUpdatesTask.groovy | 15 +++ .../resolutionstrategy/ComponentFilter.groovy | 7 ++ .../ComponentSelectionWithCurrent.groovy | 45 ++++++- 4 files changed, 150 insertions(+), 33 deletions(-) create mode 100644 src/main/groovy/com/github/benmanes/gradle/versions/updates/resolutionstrategy/ComponentFilter.groovy diff --git a/README.md b/README.md index a0c79da5..b4d9264f 100644 --- a/README.md +++ b/README.md @@ -86,47 +86,107 @@ The strategy can be specified either on the task or as a system property for ad gradle dependencyUpdates -Drevision=release ``` -The latest versions can be further filtered using [Component Selection Rules][component_selection_rules]. -The current version of a component can be retrieved with `currentVersion` property. For example, to -disallow release candidates as upgradable versions from stable versions, a selection rule could be -defined as: +The latest versions can be further filtered using [Component Selection Rules][component_selection_rules]. +To do that, you need to define what does not constitute a stable version for your project: + +
+Groovy ```groovy -dependencyUpdates.resolutionStrategy { - componentSelection { rules -> - rules.all { ComponentSelection selection -> - def isNonStable = { String version -> - ['alpha', 'beta', 'rc', 'cr', 'm', 'preview', 'b', 'ea'].any { qualifier -> - version ==~ /(?i).*[.-]$qualifier[.\d-+]*/ - } - } +def isNonStable = { String version -> + def stableKeyword = ['RELEASE', 'FINAL', 'GA'].any { it -> version.toUpperCase().contains(it) } + def regex = /^[0-9,.v-]+$/ + return !stableKeyword && !(version ==~ /^[0-9,.v-]+$/) +} +``` - if (isNonStable(candidate.version) && !isNonStable(currentVersion)) { - selection.reject('Release candidate') - } - } +
+
+Kotlin + +```kotlin +fun isNonStable(version: String): Boolean { + val stableKeyword = listOf("RELEASE", "FINAL", "GA").any { version.toUpperCase().contains(it) } + val regex = "^[0-9,.v-]+$".toRegex() + val isStable = stableKeyword || regex.matches(version) + return isStable.not() +} +``` + +
+ + + +
+Groovy + +```groovy +dependencyUpdates { + // Example 1: reject all non stable versions + rejectVersionIf { selection -> + isNonStable(candidate.version) + } + + // Example 2: disallow release candidates as upgradable versions from stable versions + rejectVersionIf { selection -> + isNonStable(candidate.version) && !isNonStable(currentVersion) + } + + // Example 3: using the full syntax + resolutionStrategy { + componentSelection { rules -> + rules.all { ComponentSelection selection -> + if (isNonStable(candidate.version) && !isNonStable(currentVersion)) { + selection.reject('Release candidate') + } + } + } } } ``` -If using Gradle's [kotlin-dsl][kotlin_dsl], you could configure the `dependencyUpdates` like this: +
+
+Kotlin ```kotlin import com.github.benmanes.gradle.versions.updates.DependencyUpdatesTask -tasks.named("dependencyUpdates") { - resolutionStrategy { - componentSelection { - all { - fun isNonStable(version: String) = listOf("alpha", "beta", "rc", "cr", "m", "preview", "b", "ea").any { qualifier -> - version.matches(Regex("(?i).*[.-]$qualifier[.\\d-+]*")) - } - if (isNonStable(candidate.version) && !isNonStable(currentVersion)) { - reject("Release candidate") +tasks.withType { + // Example 1: reject all non stable versions + rejectVersionIf { selection -> + isNonStable(selection.candidate.version) + } + + // Example 2: disallow release candidates as upgradable versions from stable versions + rejectVersionIf { selection -> + isNonStable(selection.candidate.version) && !isNonStable(selection.currentVersion) + } + + // Example 3: using the full syntax + resolutionStrategy { + componentSelection { + all { + if (isNonStable(candidate.version) && !isNonStable(currentVersion)) { + reject("Release candidate") + } + } } - } } - } +} +``` + +
+ +#### Kotlin DSL + +If using Gradle's [kotlin-dsl][kotlin_dsl], you could configure the `dependencyUpdates` like this: + +```kotlin +import com.github.benmanes.gradle.versions.updates.DependencyUpdatesTask + +tasks.withType { + // optional parameters checkForGradleUpdate = true outputFormatter = "json" diff --git a/src/main/groovy/com/github/benmanes/gradle/versions/updates/DependencyUpdatesTask.groovy b/src/main/groovy/com/github/benmanes/gradle/versions/updates/DependencyUpdatesTask.groovy index 92606ac7..f9a8f7c4 100644 --- a/src/main/groovy/com/github/benmanes/gradle/versions/updates/DependencyUpdatesTask.groovy +++ b/src/main/groovy/com/github/benmanes/gradle/versions/updates/DependencyUpdatesTask.groovy @@ -15,6 +15,9 @@ */ package com.github.benmanes.gradle.versions.updates +import com.github.benmanes.gradle.versions.updates.resolutionstrategy.ComponentFilter +import com.github.benmanes.gradle.versions.updates.resolutionstrategy.ComponentSelectionRulesWithCurrent +import com.github.benmanes.gradle.versions.updates.resolutionstrategy.ComponentSelectionWithCurrent import com.github.benmanes.gradle.versions.updates.resolutionstrategy.ResolutionStrategyWithCurrent import groovy.transform.TypeChecked import org.gradle.api.Action @@ -91,6 +94,18 @@ class DependencyUpdatesTask extends DefaultTask { this.resolutionStrategy = null } + void rejectVersionIf(final ComponentFilter filter) { + resolutionStrategy { ResolutionStrategyWithCurrent strategy -> + strategy.componentSelection { ComponentSelectionRulesWithCurrent selection -> + selection.all { ComponentSelectionWithCurrent current -> + if (filter.reject(current)) { + current.reject("Rejected by rejectVersionIf ") + } + } + } + } + } + /** Returns the resolution revision level. */ String revisionLevel() { System.properties['revision'] ?: revision } diff --git a/src/main/groovy/com/github/benmanes/gradle/versions/updates/resolutionstrategy/ComponentFilter.groovy b/src/main/groovy/com/github/benmanes/gradle/versions/updates/resolutionstrategy/ComponentFilter.groovy new file mode 100644 index 00000000..81a0ef81 --- /dev/null +++ b/src/main/groovy/com/github/benmanes/gradle/versions/updates/resolutionstrategy/ComponentFilter.groovy @@ -0,0 +1,7 @@ +package com.github.benmanes.gradle.versions.updates.resolutionstrategy + +interface ComponentFilter { + + boolean reject(ComponentSelectionWithCurrent candidate) + +} diff --git a/src/main/groovy/com/github/benmanes/gradle/versions/updates/resolutionstrategy/ComponentSelectionWithCurrent.groovy b/src/main/groovy/com/github/benmanes/gradle/versions/updates/resolutionstrategy/ComponentSelectionWithCurrent.groovy index 61bb201b..399354af 100644 --- a/src/main/groovy/com/github/benmanes/gradle/versions/updates/resolutionstrategy/ComponentSelectionWithCurrent.groovy +++ b/src/main/groovy/com/github/benmanes/gradle/versions/updates/resolutionstrategy/ComponentSelectionWithCurrent.groovy @@ -1,13 +1,48 @@ package com.github.benmanes.gradle.versions.updates.resolutionstrategy -import groovy.transform.TupleConstructor +import com.thoughtworks.xstream.mapper.Mapper +import org.gradle.api.artifacts.ComponentMetadata import org.gradle.api.artifacts.ComponentSelection +import org.gradle.api.artifacts.component.ModuleComponentIdentifier -@TupleConstructor(includeFields=true) -class ComponentSelectionWithCurrent { +import javax.annotation.Nullable - final String currentVersion +class ComponentSelectionWithCurrent implements ComponentSelection { + + ComponentSelectionWithCurrent(String currentVersion, ComponentSelection delegate) { + this.currentVersion = currentVersion + this.delegate = delegate + } - @Delegate + final String currentVersion private final ComponentSelection delegate + + ModuleComponentIdentifier getCandidate() { + return delegate.candidate + } + + @Nullable + ComponentMetadata getMetadata() { + return delegate.metadata + } + + def T getDescriptor(Class descriptorClass) { + return delegate.getDescriptor(descriptorClass) + } + + void reject(String reason) { + delegate.reject(reason) + } + + + @Override + public String toString() { + final StringBuffer sb = new StringBuffer("ComponentSelectionWithCurrent{"); + sb.append("group=").append(getCandidate().group); + sb.append(", module=").append(getCandidate().module); + sb.append(", version=").append(getCandidate().version) + sb.append(", currentVersion='").append(currentVersion).append('\''); + sb.append('}'); + return sb.toString(); + } }