How to use Gradle's dynamic versions and avoid betas?
Asked Answered
M

5

7

I have this on my build.gradle:

testCompile(group: 'junit', name: 'junit', version: '4.+')

It resolves to:

junit:junit:4.+ -> 4.12-beta-1

I don't want to use beta releases but at the same time I want to use the dynamic version. in this case I want to depend on 4.11 .

Is it possible? How?

Note: Maven "versions" plugin - how to exclude alpha/beta versions from reponse? has an answer for maven but I'm not sure how to translate this in Gradle.

Malediction answered 28/7, 2014 at 12:43 Comment(1)
possible duplicate of Gradle - getting the latest release version of a dependencyMalediction
T
4

You could use ComponentMeta to set the status:

dependencies {
   components {
     eachComponent { ComponentMetadataDetails details ->
         def version = details.id.version
         if (version.contains("beta") || version.contains("alpha")) {
             details.status = "milestone" // default in Gradle
         }
     }
   }
 }

Then use the status range syntax for your dependency:

testCompile(group: 'junit', name: 'junit', version: 'latest.release')

Now Gradle won't consider your beta a "release", and hence it won't match 4.12-beta-1. This won't let you only pick 4.x releases though, i.e. a 5.2 release would also apply.

Tsarina answered 30/7, 2014 at 5:24 Comment(1)
I'm wondering if it is possible to manually trigger the component metadata handler and continue to use the + notation. gradle.org/docs/current/userguide/…Malediction
C
2

Here's how I'm handling this:

    ext {
        excludedVersionPattern = "alpha|beta"  // Default value
    }

    configurations.configureEach {
        resolutionStrategy {
            componentSelection {
                all { ComponentSelection selection ->
                    def dversion = selection.candidate.version
                    if (dversion ==~ /.*[-_.]?(${excludedVersionPattern}).*/) {
                        reject("Rejecting $dversion as it's an excluded version")
                    }
                }
            }
        }
    }
Commensurate answered 19/1, 2024 at 22:49 Comment(1)
This is better than the accepted answer, since it doesn't require changes to the version declaration.Prepositor
P
0

Gradle's dynamic versions don't currently support such excludes.

Polythene answered 28/7, 2014 at 12:46 Comment(0)
O
0

This is the way I've solved this for my own use case. The following allows exclusion rules to be added that filter candidates during dependency resolution. Candidates matching regular expression exclusion rules are rejected.

This is Kotlin DSL, but would probably work just as well if converted to Groovy.

configurations.all {
    resolutionStrategy
        .componentSelection
        .all(object : Action<ComponentSelection> {
            @Mutate
            override fun execute(selection : ComponentSelection) {
                // Add exclusion rules here
                excludeSelectionByRegex(selection, "org\\.jetbrains.*", ".*", ".*-(eap|M).*")
                excludeSelectionByRegex(selection, "org\\.my-group.*", "my-module", ".*-beta")
            }
        })
}

fun excludeSelectionByRegex(selection: ComponentSelection, groupRegex: String, moduleRegex: String, versionRegex: String) {
    if (groupRegex.toRegex().matches(selection.candidate.group) &&
        moduleRegex.toRegex().matches(selection.candidate.module) &&
        versionRegex.toRegex().matches(selection.candidate.version)
    ) {
        selection.reject("Matched exclusion rule")
    }
}
Ortega answered 19/6, 2020 at 7:53 Comment(1)
perhaps a little more DSL-y ... .all { if ( candidate.version.contains("-M") ) reject("no milestone version") }Mariannamarianne
A
0

Using Gradle Kotlin DSL

// build.gradle.kts
// ...
dependencies {
  // ...

  components.all {
    // only considering dependencies marked as release
    if (status == "release") {
      milestoneVersionPatterns
        .find { it.matches(id.version) } // do any patterns match?
        ?.let { // not null means one of the patterns matched
          // this dependency has the wrong status of "release"
          // demote to "milestone" status
          status = "milestone"
        }
    }
  }
}

val milestoneVersionPatterns: List<Regex> = listOf(
  ".*alpha.*",
  ".*-b.*",
  ".*beta.*",
  ".*cr.*",
  ".*m.*",
  ".*rc.*",
  ".*snap.*",
)
  .map { it.toRegex(RegexOption.IGNORE_CASE) }

See also:

Androsphinx answered 28/5, 2024 at 22:17 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.