Gradle: Is there a way to disallow version ranges in transitive dependencies? -
when i've declared snapshot repository in gradle configuration, there way prevent transitive dependencies version ranges resolving snapshot versions? alternatively, can forbid version ranges in transitive dependencies? example, consider simple gradle project:
class="lang-groovy prettyprint-override">repositories { mavencentral() maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' } } apply plugin: "java" dependencies { compile "org.reactfx:reactfx:1.4" compile "org.fxmisc.undo:undofx:1.0.1" }
this result in version conflict , resolution since undofx
depends on reactfx
version [1.4,1.5)
(the recent 1.4.x version available). here dependency insight reactfx
:
gradlew dependencyinsight --dependency reactfx
class="lang-plain prettyprint-override">org.reactfx:reactfx:1.4.1-snapshot (conflict resolution) org.reactfx:reactfx:1.4 -> 1.4.1-snapshot \--- compile org.reactfx:reactfx:[1.4,1.5) -> 1.4.1-snapshot \--- org.fxmisc.undo:undofx:1.0.1 \--- compile
maven resolve reactfx:1.4.1-snapshot
dependency undofx
. however, appears 1 time reactfx
dependency added project, maven resolves conflict using version i've declared first level dependency. here's maven pom used test it:
<?xml version="1.0" encoding="utf-8"?> <project xmlns="http://maven.apache.org/pom/4.0.0" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xsi:schemalocation="http://maven.apache.org/pom/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelversion>4.0.0</modelversion> <groupid>example</groupid> <artifactid>example</artifactid> <version>1.0-snapshot</version> <repositories> <repository> <id>maven-central</id> <url>http://repo1.maven.org/maven2</url> </repository> <repository> <id>oss-snapshots</id> <url>https://oss.sonatype.org/content/repositories/snapshots/</url> <snapshots> <enabled>true</enabled> </snapshots> </repository> </repositories> <dependencies> <dependency> <groupid>org.fxmisc.undo</groupid> <artifactid>undofx</artifactid> <version>1.0.1</version> </dependency> <dependency> <groupid>org.reactfx</groupid> <artifactid>reactfx</artifactid> <version>1.4</version> </dependency> </dependencies> </project>
that's sort of resolution behavior expecting gradle, based on assumption. figured if undofx
allows 1.4.x
version of reactfx
, other declared version of reactfx
falls in range, conflict resolved using declared version.
however, i'm less interested in conflict resolution in failing build if transitive dependencies using ranged versions. i'd prefer identify dependencies , set them specific versions. don't think i'd have noticed 1 using version range if hadn't created above conflict.
what's easiest way identify , deal transitive dependencies using version ranges?
updatedbased on peter's answer, here finish listing of code i'm using this. take note it's using features of gradle api marked @incubating
.
import org.gradle.api.artifacts.component.modulecomponentselector if(!project.plugins.hasplugin(javaplugin)) { apply plugin: "java" } repositories { mavencentral() maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' } } dependencies { compile "org.fxmisc.undo:undofx:1.0.1" // depends on reactfx:[1.4,1.5) } configurations { //noinspection groovyassignabilitycheck { /* 1 time dependencies in configurations resolved check version of module (not project) components resolved successfully. modules using forced version skipped. */ incoming.afterresolve { // resolvabledependencies it.resolutionresult.alldependencies { // dependencyresult if(it instanceof resolveddependencyresult && it.requested instanceof modulecomponentselector) { if(!it.selected.selectionreason.forced) { checkversion((modulecomponentselector) it.requested) } } } } } } /** * check version of requested module , throw , exception if it's * using version range. * * @param requested module component check. */ void checkversion(modulecomponentselector requested) { def version = requested.version if(version.endswith(")") || version.equals("latest") || version.equals("release")) { throw new gradleexception( "${requested} uses version range. seek force.") } }
you can utilize configuration.getincoming()
api compare declared resolved versions (e.g. in configuration.getincoming().afterresolve()
hook), , fail if aren't same. maven conflict resolution behavior of "declared version wins" (rather gradle's "highest version wins"), can utilize configuration.getresolutionstrategy().force()
api. enforce every version conflict resolved explicitly (using force()
), utilize configuration.getresolutionstrategy().failonversionconflict()
. api details, see gradle build language reference.
gradle
No comments:
Post a Comment