Skip to content

Commit

Permalink
Implements #325 rejectVersionIf { ... } (#340)
Browse files Browse the repository at this point in the history
Implements #325 rejectVersionIf { ... }
  • Loading branch information
Jean-Michel Fayard authored Sep 10, 2019
2 parents f8d60b3 + cd340d9 commit 5f89fa2
Show file tree
Hide file tree
Showing 11 changed files with 205 additions and 38 deletions.
119 changes: 100 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,48 +85,116 @@ The strategy can be specified either on the task or as a system property for ad
```groovy
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:
To further define which version to accept, you need to define what means an unstable version. Sadly, there are
no agreed standard on this, but this is a good starting point:

<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 ==~ regex)
}
```

</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>

You can then configure [Component Selection Rules][component_selection_rules].
The current version of a component can be retrieved with the `currentVersion` property.
You can either use the simplified syntax `rejectVersionIf { ... }` or configure a complete resolution strategy.

if (isNonStable(candidate.version) && !isNonStable(currentVersion)) {
selection.reject('Release candidate')

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

<!-- Always modify first examples/groovy and make sure that it works. THEN modify the README -->

```groovy
dependencyUpdates {
// 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')
}
}
}
}
}
```

If using Gradle's [kotlin-dsl][kotlin_dsl], you could configure the `dependencyUpdates` like this:
</details>
<details>
<summary>Kotlin</summary>

<!-- Always modify first examples/kotlin and make sure that it works. THEN modify the README -->

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

tasks.named<DependencyUpdatesTask>("dependencyUpdates") {
tasks.withType<DependencyUpdatesTask> {
// Example 1: reject all non stable versions
rejectVersionIf {
isNonStable(candidate.version)
}

// Example 2: disallow release candidates as upgradable versions from stable versions
rejectVersionIf {
isNonStable(candidate.version) && !isNonStable(currentVersion)
}

// Example 3: using the full syntax
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")
}
}
}
}
}
```

</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 All @@ -137,6 +205,19 @@ tasks.named<DependencyUpdatesTask>("dependencyUpdates") {

Note: Do use the `plugins { .. }` syntax if you use the Kotlin DSL.

#### Try out the samples

Have a look at [`examples/groovy`](https://github.com/ben-manes/gradle-versions-plugin/tree/master/examples/groovy) and [`examples/kotlin`](https://github.com/ben-manes/gradle-versions-plugin/tree/master/examples/kotlin)

```bash
# Publish the latest version of the plugin to mavenLocal()
$ ./gradlew install

# Try out the samples
$ ./gradlew -p examples/groovy dependencyUpdate
$ ./gradlew -p examples/kotlin dependencyUpdate
```

#### Report format

The task property `outputFormatter` controls the report output format. The following values are supported:
Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ apply plugin: 'nexus'
apply plugin: 'codenarc'

group = 'com.github.ben-manes'
version = '0.24.0'
version = '0.25.0'

sourceCompatibility = '1.6'

Expand Down
1 change: 0 additions & 1 deletion examples/.gitignore

This file was deleted.

31 changes: 23 additions & 8 deletions examples/build.gradle → examples/groovy/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ defaultTasks 'dependencyUpdates'
buildscript {
repositories {
// Use 'gradle install' to install latest
jcenter()
mavenLocal()
jcenter()
}

dependencies {
Expand All @@ -29,16 +29,31 @@ configurations {
unresolvable2
}

def isNonStable = { String version ->
def stableKeyword = ['RELEASE', 'FINAL', 'GA'].any { it -> version.toUpperCase().contains(it) }
def regex = /^[0-9,.v-]+$/
return !stableKeyword && !(version ==~ regex)
}

dependencyUpdates {
checkForGradleUpdate = true

// Example 1: reject all non stable versions
rejectVersionIf {
isNonStable(candidate.version)
}

// Example 2: disallow release candidates as upgradable versions from stable versions
rejectVersionIf {
isNonStable(candidate.version) && !isNonStable(currentVersion)
}

// Example 3: using the full syntax
resolutionStrategy {
componentSelection { rules ->
rules.all { ComponentSelection selection ->
boolean rejected = ['alpha', 'beta', 'rc', 'cr', 'm', 'preview', 'b', 'ea'].any { qualifier ->
selection.candidate.version ==~ /(?i).*[.-]$qualifier[.\d-+]*/
}
if (rejected) {
selection.reject('Release candidate')
componentSelection {
all {
if (isNonStable(candidate.version) && !isNonStable(currentVersion)) {
reject('Release candidate')
}
}
}
Expand Down
3 changes: 3 additions & 0 deletions examples/groovy/settings.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
rootProject.name = 'gradle-versions-sample-groovy'
enableFeaturePreview("IMPROVED_POM_SUPPORT")

33 changes: 26 additions & 7 deletions examples/kotlin/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import com.github.benmanes.gradle.versions.updates.DependencyUpdatesTask

// Use 'gradle install' to install latest plugin version
plugins {
id("com.github.ben-manes.versions") version "0.20.0"
id("com.github.ben-manes.versions") version "0.25.0"
}


repositories {
jcenter()
}
Expand All @@ -19,19 +19,38 @@ configurations {
register("unresolvable2")
}

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



tasks.withType<DependencyUpdatesTask> {

// Example 1: reject all non stable versions
rejectVersionIf {
isNonStable(candidate.version)
}

// Example 2: disallow release candidates as upgradable versions from stable versions
rejectVersionIf {
isNonStable(candidate.version) && !isNonStable(currentVersion)
}

// Example 3: using the full syntax
resolutionStrategy {
componentSelection {
all {
val rejected = listOf("alpha", "beta", "rc", "cr", "m", "preview", "b", "ea").any { qualifier ->
candidate.version.matches(Regex("(?i).*[.-]$qualifier[.\\d-+]*"))
}
if (rejected) {
if (isNonStable(candidate.version) && !isNonStable(currentVersion)) {
reject("Release candidate")
}
}
}
}

// optional parameters
checkForGradleUpdate = true
outputFormatter = "json"
Expand Down
11 changes: 11 additions & 0 deletions examples/kotlin/settings.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
@file:Suppress("UnstableApiUsage")

// Use 'gradle install' to install latest plugin version
pluginManagement {
repositories {
mavenLocal()
gradlePluginPortal()
}
}
rootProject.name = "gradle-versions-sample-kotlin"

1 change: 0 additions & 1 deletion examples/settings.gradle

This file was deleted.

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,19 @@ class DependencyUpdatesTask extends DefaultTask {
this.resolutionStrategy = null
}

void rejectVersionIf(final ComponentFilter filter) {
resolutionStrategy { ResolutionStrategyWithCurrent strategy ->
strategy.componentSelection { ComponentSelectionRulesWithCurrent selection ->
selection.all { ComponentSelectionWithCurrent current ->
def isNotNull = current.currentVersion != null && current.candidate.version != null
if (isNotNull && 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,10 @@
package com.github.benmanes.gradle.versions.updates.resolutionstrategy

import org.gradle.api.HasImplicitReceiver

@HasImplicitReceiver
interface ComponentFilter {

boolean reject(ComponentSelectionWithCurrent candidate)

}
Original file line number Diff line number Diff line change
@@ -1,13 +1,27 @@
package com.github.benmanes.gradle.versions.updates.resolutionstrategy


import groovy.transform.TupleConstructor
import org.gradle.api.artifacts.ComponentSelection

@TupleConstructor(includeFields=true)
@TupleConstructor(includeFields = true)
class ComponentSelectionWithCurrent {

final String currentVersion

@Delegate
private final ComponentSelection delegate


@Override
public String toString() {
return """\
ComponentSelectionWithCurrent{
group="${candidate.group}",
module="${candidate.module}",
version="${candidate.version}",
currentVersion="$currentVersion",
}"""
}
}

0 comments on commit 5f89fa2

Please sign in to comment.