Skip to content

Commit

Permalink
Implement ben-manes#325 rejectVersionIf
Browse files Browse the repository at this point in the history
  • Loading branch information
Jean-Michel Fayard committed Sep 9, 2019
1 parent f8d60b3 commit 092837a
Show file tree
Hide file tree
Showing 4 changed files with 150 additions and 33 deletions.
116 changes: 88 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:

<details open>
<summary>Groovy</summary>

```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')
}
}
</details>
<details>
<summary>Kotlin</summary>

```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()
}
```

</details>



<details open>
<summary>Groovy</summary>

```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:
</details>
<details>
<summary>Kotlin</summary>

```kotlin
import com.github.benmanes.gradle.versions.updates.DependencyUpdatesTask

tasks.named<DependencyUpdatesTask>("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<DependencyUpdatesTask> {
// 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")
}
}
}
}
}
}
}
```

</details>

#### 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<DependencyUpdatesTask> {

// optional parameters
checkForGradleUpdate = true
outputFormatter = "json"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 }

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.github.benmanes.gradle.versions.updates.resolutionstrategy

interface ComponentFilter {

boolean reject(ComponentSelectionWithCurrent candidate)

}
Original file line number Diff line number Diff line change
@@ -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> T getDescriptor(Class<T> 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();
}
}

0 comments on commit 092837a

Please sign in to comment.