Dependency management in multi-module project on hail

image

Introduction



The article is written with an eye to native android projects, but, since the gradle is a universal assembly system, in principle, it will be suitable for other projects that the gradle can collect. The idea is not mine, I got it from the github project of Jake Wharton SdkSearch - a set of programs for searching the documentation for android sdk.



Problem



A modern application is almost impossible (impractical) to write without using libraries. With the advent of dependencies, the task of managing versioning arises. Perhaps for a single-module android application of the middle hand this is not a problem, then in larger projects with code reuse, the problem is relevant. Especially in version control of support androidx libraries for which versioning is simply beyond reason, you just look at AndroidX versions



Decision



With so many dependencies, it is very important that all modules depend on one version of the library, otherwise surprises in runtime will come out in the most unexpected place.

Gradle uses groovy as a scripting language, which, coupled with dynamic typing, provides a convenient way to organize dependency management.



In the DSL grad, it is possible to add properties to the project using the ext ExtraPropertiesExtension object . Also, inside the module script, you can access the project script (root module), which allows you to declare all versions of the dependencies in the root script, and you can already refer to them from any module inside.



For example, let our android application use the dependencies: kotlin, kotlin stdlib, kotlin junit, facebook sdk, androidx, google material



Root build.gradle:



buildscript { ext { versions = [ 'kotlin': '1.3.50', 'fb': '4.40.0' ] deps = [ 'kotlin': [ 'stdlib': [ 'jdk': "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${versions.kotlin}" ], 'test': [ 'common': "org.jetbrains.kotlin:kotlin-test-common:${versions.kotlin}", 'annotations': "org.jetbrains.kotlin:kotlin-test-annotations-common:${versions.kotlin}", 'jdk': "org.jetbrains.kotlin:kotlin-test-junit:${versions.kotlin}" ] ], 'androidx' : [ 'annotation': "androidx.annotation:annotation:1.1.0", 'appCompat': 'androidx.appcompat:appcompat:1.1.0', 'constraintLayout': 'androidx.constraintlayout:constraintlayout:1.1.3', 'ktx': 'androidx.core:core-ktx:1.1.0', 'dynamicAnimation': 'androidx.dynamicanimation:dynamicanimation:1.0.0', 'gridLayout': 'androidx.gridlayout:gridlayout:1.0.0', 'localBroadcastManager': 'androidx.localbroadcastmanager:localbroadcastmanager:1.0.0', 'multidex': 'androidx.multidex:multidex:2.0.1', 'recyclerView': 'androidx.recyclerview:recyclerview:1.1.0-beta04' ], 'material': 'com.google.android.material:material:1.0.0', 'fb': [ 'core': "com.facebook.android:facebook-core:${versions.fb}", 'login': "com.facebook.android:facebook-login:${versions.fb}", 'share': "com.facebook.android:facebook-share:${versions.fb}" ] ] repositories { google() jcenter() } dependencies { classpath 'com.android.tools.build:gradle:3.6.0-alpha11' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${versions.kotlin}" } }
      
      





A couple of points:

If several dependencies have one version, for example, parts of one large SDK, then the version is added to the versions property, such as with versions of Kotlin and Facebook. If the dependency is in the form of a single line, such as google material, then it is not practical to make a version. Versions of androidx libraries also do not need to be taken out, because Google refused to align versions with each other to speed up releases of individual libraries.



As a result of this definition, in all child modules, the declaration of dependencies becomes a concise hierarchy free from versioning, because now all modules depend on the same library versions.



example of the module dependencies section in build.gradle



 dependencies { implementation deps.kotlin.stdlib.jdk implementation deps.androidx.appCompat implementation deps.androidx.browser implementation deps.androidx.cardView implementation deps.androidx.constraintLayout implementation deps.androidx.ktx implementation deps.androidx.multidex implementation deps.androidx.recyclerView implementation deps.material implementation deps.fb.core implementation deps.fb.login implementation deps.fb.share testImplementation deps.kotlin.test.jdk }
      
      





What happened - the library versions of the modules disappeared, a hierarchy of libraries appeared

It is also worth noting that the module does not have to depend on all the libraries described in the root script, but only on those that are necessary.



As I mentioned above, a working draft using such a scheme is here .



All Articles