Friday, 15 April 2011

Gradle: Is there a way to disallow version ranges in transitive dependencies? -



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:

class="lang-plain prettyprint-override">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:

class="lang-xml prettyprint-override"><?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?

updated

based on peter's answer, here finish listing of code i'm using this. take note it's using features of gradle api marked @incubating.

class="lang-groovy prettyprint-override">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