Dans Gradle, comment déclarer les dépendances courantes en un seul endroit?

109

Dans Maven, il existe une fonctionnalité très utile lorsque vous pouvez définir une dépendance dans la <dependencyManagement>section du POM parent et référencer cette dépendance à partir de modules enfants sans spécifier la version ou la portée ou autre.

Quelles sont les alternatives à Gradle?

Stanislav Bashkyrtsev
la source

Réponses:

179

Vous pouvez déclarer des dépendances courantes dans un script parent:

ext.libraries = [ // Groovy map literal
    spring_core: "org.springframework:spring-core:3.1",
    junit: "junit:junit:4.10"
]

À partir d'un script enfant, vous pouvez ensuite utiliser les déclarations de dépendance comme ceci:

dependencies {
    compile libraries.spring_core
    testCompile libraries.junit
}

Pour partager des déclarations de dépendance avec des options de configuration avancées, vous pouvez utiliser DependencyHandler.create:

libraries = [
    spring_core: dependencies.create("org.springframework:spring-core:3.1") {
        exclude module: "commons-logging"
        force = true
    }
]

Plusieurs dépendances peuvent être partagées sous le même nom:

libraries = [
    spring: [ // Groovy list literal
        "org.springframework:spring-core:3.1", 
        "org.springframework:spring-jdbc:3.1"
    ]
]

dependencies { compile libraries.spring } ajoutera ensuite les deux dépendances à la fois.

La seule information que vous ne pouvez pas partager de cette manière est la configuration ( portée en termes Maven) à laquelle une dépendance doit être affectée. Cependant, d'après mon expérience, il vaut mieux être explicite à ce sujet de toute façon.

Peter Niederwieser
la source
3
Merci, cela résout ma question, mais j'ai quand même un problème .. Dans Maven, nous pouvons laisser la version vide et s'il s'agit d'une bibliothèque, c'est pratique car vous pouvez l'utiliser dans notre application et faire dependencyManagement pour définir quelle version de la lib cela devrait prendre. Comment feriez-vous la même chose avec Gradle?
Stanislav Bashkyrtsev
Je ne comprends pas la question. Veuillez donner un exemple.
Peter Niederwieser
4
Peter, ce que ctapobep dit, c'est que dans maven, vous pouvez déclarer des dépendances avec la version (et la portée) dans un pom parent (ou agrégateur) dans la section dependencyManagement. Ensuite, dans le pom "concret", vous n'avez pas besoin de re-déclarer la version; juste artefact et groupId. Fondamentalement, il dit à maven "J'ai besoin de X: Y, mais utilisez la version que le parent a configurée."
Michael Campbell
2
Pour éviter ce genre de double emploi, j'ai tendance à créer un distinct dependencies.gradlescénario où je toutes mes dépendances définir comme propriétés, par exemple: ext.GROOVY = 'org.codehaus.groovy:groovy-all:2.1.6'. Dans le projet racine build.gradle, j'inclus allprojects { apply from: "$rootDir/dependencies.gradle" }. Ensuite, toutes les dépendances sont définies dans un fichier au lieu de les répartir, et plus de constantes «faciles à lire» sont utilisées dans les configurations de dépendances.
Steinar
1
C'est exactement ce que j'ai fait ci-dessus. Vous n'avez pas besoin de postuler allprojectscar les propriétés supplémentaires au niveau du projet sont visibles pour les sous-projets.
Peter Niederwieser
7

C'est une réponse tardive, mais vous voudrez peut-être aussi jeter un œil à: http://plugins.gradle.org/plugin/io.spring.dependency-management Il offre la possibilité d'importer un maven 'bom' et de réutiliser les définitions défini dans le «bom». C'est certainement une aide précieuse lors de la migration progressive de maven à gradle! Profiter maintenant.

chambresg
la source
c'est même un incontournable lorsque vous souhaitez partager les mêmes dépendances sur plusieurs (multi) projets.
roomsg
7
Bien que pratique, ce plugin peut avoir une empreinte de performances significative. Pour 30 sous-projets avec plus de 200 dépendances, cela ajoute jusqu'à 1 minute à la phase de résolution des dépendances. Pour les petits projets, cela fonctionne comme un charme, cependant
Jk1
il remplace également les versions de dépendance transitive, disons que vous avez déclaré la version 3.0.0 dans la gestion des dépendances, mais pour l'un des sous-projets, vous devez utiliser une version plus ancienne, par exemple 2.5.0, alors si vous avez un projet dépendant de cet ancien projet, le la dépendance transitive sera écrasée de 2.5.0 à ce qui est déclaré dans le plugin de gestion des dépendances donc 3.0.0 dans ce cas un comportement très étrange
KameeCoding
7

Depuis Gradle 4.6, les contraintes de dépendance sont suggérées dans la documentation comme moyen d'y parvenir. Depuis https://docs.gradle.org/current/userguide/declaring_dependencies.html#declaring_a_dependency_without_version :

Une pratique recommandée pour les projets plus volumineux consiste à déclarer des dépendances sans versions et à utiliser des contraintes de dépendance pour la déclaration de version. L'avantage est que les contraintes de dépendance vous permettent de gérer les versions de toutes les dépendances, y compris celles transitives, en un seul endroit.

Dans votre build.gradledossier parent :

allprojects {
  plugins.withType(JavaPlugin).whenPluginAdded {
    dependencies {
      constraints {
        implementation("com.google.guava:guava:27.0.1-jre")
      }
    }
  }
}

Enveloppant le bloc de dépendances avec une vérification du plugin Java (... whenPluginAdded {) n'est pas strictement nécessaire, mais cela gérera alors l'ajout d'un projet non Java à la même construction.

Ensuite, dans un projet gradle enfant, vous pouvez simplement omettre la version:

apply plugin: "java"

dependencies {
  implementation("com.google.guava:guava")
}

Les versions enfants peuvent toujours choisir de spécifier une version supérieure. Si une version inférieure est spécifiée, elle est automatiquement mise à niveau vers la version de la contrainte.

Adrian Baker
la source
1
Des contraintes de dépendance ont été ajoutées dans Gralde 4.6, donc cela fonctionnera avec Gradle 4.6 ou supérieur.
Jim Hurne
Je pense que Gradle prévoit que le plugin Java Platform est utilisé dans ce cas. Cependant, la documentation Gradle n'est pas très claire à ce stade. Je suppose que l'utilisation de allprojectsest bien aussi.
JojOatXGME
Je veux déclarer les contraintes dans le projet racine mais uniquement dans l'un de mes sous-projets, je veux charger toutes ces dépendances qui ont des contraintes définies.
dtc le
2

io.spring.gradle:dependency-management-pluginLe plugin a des problèmes avec la nouvelle série Gradle 3.x mais stable pour la série 2.x. Pour référence, regardez le rapport de bogue Drop support pour Gradle 3 # 115

En cas de Spring ( principal promoteur de l'utilisation de la nomenclature ), vous pouvez terminer par:

buildscript {
    repositories {
        mavenLocal()
        jcenter()
    }
    dependencies {
        classpath 'io.spring.gradle:dependency-management-plugin:1.0.0.RELEASE'
    }
}

repositories {
    mavenLocal()
    jcenter()
}

apply plugin: 'java'
apply plugin: 'io.spring.dependency-management'

dependencyManagement {
    imports {
        mavenBom 'io.spring.platform:platform-bom:Athens-SR3'
    }
}

dependencies {
    compile 'org.springframework.boot:spring-boot-starter-web'

    testCompile 'org.springframework.boot:spring-boot-starter-test'
}

Notez que io.spring.platform:platform-bomhave org.springframework.boot:spring-boot-starter-parentcomme parent donc il est compatible avec Spring Boot

Vous pouvez vérifier la résolution réelle des dépendances via:

$ gradle dependencies
$ gradle dependencies --configuration compile
$ gradle dependencies -p $SUBPROJ

$ gradle buildEnvironment
$ gradle buildEnvironment -p $SUBPROJ

ou avec tâche:

task showMeCache {
    configurations.compile.each { println it }
}

Lire l'article du blog officiel de Soring Une meilleure gestion des dépendances pour Gradle afin de comprendre la raison de l'introduction io.spring.gradle:dependency-management-plugin.

gavenkoa
la source
1

Vous pouvez centraliser une dépendance en utilisant le code ci-dessous:

Dans gradle.properties

COMPILE_SDK_VERSION=26
BUILD_TOOLS_VERSION=26.0.1
TARGET_SDK_VERSION=26
MIN_SDK_VERSION=14

ANDROID_SUPPORT_VERSION=26.0.2

Dans chaque module, ajoutez à build.gradle:

android {
    compileSdkVersion COMPILE_SDK_VERSION as int
    buildToolsVersion BUILD_TOOLS_VERSION as String

    defaultConfig {
        minSdkVersion MIN_SDK_VERSION as int
        targetSdkVersion TARGET_SDK_VERSION as int
        versionCode 1
        versionName "1.0"

    }

}

dependencies {
 compile "com.android.support:appcompat-v7:${ANDROID_SUPPORT_VERSION}"
 compile "com.android.support:support-v4:${ANDROID_SUPPORT_VERSION}"
 compile "com.android.support:support-annotations:${ANDROID_SUPPORT_VERSION}"
 compile "com.android.support:support-vector-drawable:${ANDROID_SUPPORT_VERSION}"
 compile "com.android.support:design:${ANDROID_SUPPORT_VERSION}"
}
Dhaval Jivani
la source
1

Cet article de blog suggère de gérer les dépendances et les groupes en tant que configurations: https://www.javacodegeeks.com/2016/05/manage-dependencies-gradle-multi-project-build.html

Je ne l'ai pas essayé moi-même, mais cela semble intéressant.

Projet racine build.gradle

subprojects {
  configurations {
    commonsIo
  }

  dependencies {
    commonsIo 'commons-io:commons-io:2.5'
  }
}

Sous-projet build.gradle

configurations {
  compile.extendsFrom commonsIo
}
tkruse
la source
0

Pour garder votre fichier de gradation propre, nous pouvons regrouper les dépendances dans un tableau et les implémenter plus tard.

  1. Ajoutez une version de bibliothèques comme celle-ci dans build.gradle (au niveau de l'application) en dehors du bloc de dépendance :

// déclarer les versions de la bibliothèque

final RetrofitVersion = '2.3.0'
final OkHttpVersion = '3.9.1'
  1. Créez un tableau de dépendances associées pour pouvoir le retrouver facilement plus tard. Ajoutez-le dans build.gradle (au niveau de l'application) en dehors du bloc de dépendance :

// Utilisation de la version dans la bibliothèque et ajout de la dépendance avec le nom d'accès (comme retrofit (premier))

final networkDependencies = [
        retrofit             : "com.squareup.retrofit2:retrofit:${RetrofitVersion}",
        retrofitGsonConverter: "com.squareup.retrofit2:converter-gson:${RetrofitVersion}",
        retrofitRxJavaAdapter: "com.squareup.retrofit2:adapter-rxjava2:${RetrofitVersion}",
        okHttp3              : "com.squareup.okhttp3:okhttp:${OkHttpVersion}",
        okHttp3Logging       : "com.squareup.okhttp3:logging-interceptor:${OkHttpVersion}"
]
  1. Et dans le bloc de dépendance :

// Implémente toutes les dépendances du tableau

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])

    implementation networkDependencies.values()
}

Le code final ressemblera donc à ceci:

final RetrofitVersion = '2.3.0'
final OkHttpVersion = '3.9.1'

final networkDependencies = [
        retrofit             : "com.squareup.retrofit2:retrofit:${RetrofitVersion}",
        retrofitGsonConverter: "com.squareup.retrofit2:converter-gson:${RetrofitVersion}",
        retrofitRxJavaAdapter: "com.squareup.retrofit2:adapter-rxjava2:${RetrofitVersion}",
        okHttp3              : "com.squareup.okhttp3:okhttp:${OkHttpVersion}",
        okHttp3Logging       : "com.squareup.okhttp3:logging-interceptor:${OkHttpVersion}"
]

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])

    implementation networkDependencies.values()
}
Suraj Vaishnav
la source
comment inclure le processeur d'annotation par ceci ?? comme dans le cas de lombok
Pritish Joshi