gradle - listing multiple subprojects for 'project' - gradle

Is there a way to list multiple projects for a common dependency. I tried as follows, it doesn't work. I don't want to list individually for a better maintenance.
project(':com.example.bundle1', ':com.example.bundle2') {
dependencies {
compile project(':com.example.common')
}
}

you can leverage groovy list support here:
[':com.example.bundle1', ':com.example.bundle2'].each {
project(it) {
dependencies {
compile project(':com.example.common')
}
}
}

Related

gradle subproject dependencies as list of other subprojects

How can I get list of a subproject dependecies as list of Project object?
subproject.dependencies gives list of DependencyHandler objects. And I can't find how extract Project from DependencyHandler.
After a short have found solution myself :)
subprojects {
configurations.all {
allDependencies.each {
if (it instanceof ProjectDependency) {
println it.dependencyProject
}
}
}
}

no build output compiled for common module of Kotlin Multiplatform project

I'm trying to figure out why dependent projects for my Kotlin MPP library don't see any provided modules in their common modules even though the targets (jvm, android) can see them.
Published via maven-publish.
The /build directory for the library contains nothing I can identify as an intermediate representation of my common modules, leading me to think that I need to explicitly tell Gradle to produce the files to be included as common in the published package.
As it is, the .aar and .jar files produced in the android and desktop (jvm) modules each look normal, but the published common module is empty.
I need that common module to be populated before I can code against it inside the common module of dependent projects.
Here is the relevant section of my build.gradle.kts. I omit the repository config as it appears to work.
I basically followed the instructions from kotlinlang.org.
I've looked at the maven-publish plugin configuration, the settings for the kotlin-multiplatformm plugin, and the configured project structure.
kotlin version is 1.6.10, unable to update due to Jetbrains Compose dependency.
plugins {
kotlin("multiplatform")
id("com.android.library")
id("maven-publish")
}
kotlin {
android {
publishLibraryVariants = listOf("release", "debug")
}
jvm("desktop") {
compilations.all {
kotlinOptions {
jvmTarget = "11"
}
}
}
val publicationsFromMainHost = listOf(jvm("desktop").name, "kotlinMultiplatform")
publishing {
publications {
matching { it.name in publicationsFromMainHost }.all {
val targetPublication = this#all
tasks.withType<AbstractPublishToMaven>()
.matching { it.publication == targetPublication }
}
}
}
sourceSets {
val commonMain by getting {
dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.3.2")
}
}
val commonTest by getting {
dependencies {
implementation(kotlin("test"))
}
}
val androidMain by getting {
dependencies {
implementation("androidx.startup:startup-runtime:1.1.1")
}
}
val androidTest by getting {
dependencies {
implementation("junit:junit:4.13.2")
implementation("androidx.test:core:1.4.0")
implementation("androidx.test:runner:1.4.0")
implementation("androidx.test:rules:1.4.0")
implementation("org.robolectric:robolectric:4.6.1")
}
}
val desktopMain by getting
val desktopTest by getting {
dependencies {
implementation("junit:junit:4.13.2")
}
}
}
}
The answer is to manually supply the Kotlin stdlib dependency, rather than relying on the gradle plugin to add it.
When there are only jvm-based builds present, commonMain will be built with platform type of jdk8 rather than common. By making an explicit dependency on stdlib-common, it will be coerced back to the common platform, and then the correct metadata will be created and published.
kotlin {
sourceSets {
val commonMain by getting {
dependencies {
implementation(kotlin("stdlib-common"))
}
}
}
}

Is there a way to include a specific module from a group while excluding rest in gradle?

I am using a library which has a transitive dependency on a module lets assume "abc.xyz:abc-module:1.1.1", the problem is, however, all of the modules from that group are excluded in my build.gradle for some reason using
configurations {
compile.exclude group: "abc.xyz"
}
It causes that transitive dependency to be ignored as expected. Is there a way I can specify only to include abc-module while excluding the remaining one as previously?
I think you should be able to do what you want with a component selection rule like
configurations {
compile {
resolutionStrategy {
componentSelection {
all { ComponentSelection selection ->
if (selection.candidate.group == 'abc.xyz' && selection.candidate.module != 'abc-module') {
selection.reject('Dependencies from group "abc.xyz" except of "abc-module" are not allowed.')
}
}
}
}
}
}

Gradle copy build script dependency to folder

We are building one of our applications with gradle and part of the distribution I want to include an external jar which is not a run time dependency in a config folder. That jar is needed as part of the application install and it contains some custom ant tasks.
Our build script dependency looks like below:
buildscript {
...
dependencies {
classpath 'org.jfrog.buildinfo:build-info-extractor-gradle:3.1.1'
classpath 'my-group:custom-tasks:1.2.3'
}
}
How would I access and copy the custom-task-1.2.3.jar into a certain folder so I can include it in my distribution? Something like below:
task copyCustomTasks {
doLast {
copy {
// This below is a make up to express what I want
from buildscript.dependencies
include 'custom-tasks*.jar'
into "$buildDir/config"
}
}
}
If this is not the gradle way of doing things please let me know what alternatives I have.
Thank you in advance for your help.
UPDATE
I solved my problem in a different way by creating an extra configuration. However I would still be interested to find out how you can access build script dependencies at run time. Thanks again for your inputs.
configurations {
install {
description = "application install classpath"
transitive = true
}
}
...
dependencies {
...
install('my-group:custom-tasks:1.2.3')
...
}
...
task copyInstallDeps {
doLast {
copy {
from configurations.install
into "$buildDir/config"
}
}
}
You're quite close:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.google.guava:guava:18.0'
}
}
task copyLibs(type: Copy) {
from buildscript.configurations.classpath
into 'lib'
}

Extract specific JARs from dependencies

I am new to gradle but learning quickly. I need to get some specific JARs from logback into a new directory in my release task. The dependencies are resolving OK, but I can't figure out how, in the release task, to extract just logback-core-1.0.6.jar and logback-access-1.0.6.jar into a directory called 'lib/ext'. Here are the relevant excerpts from my build.gradle.
dependencies {
...
compile 'org.slf4j:slf4j-api:1.6.4'
compile 'ch.qos.logback:logback-core:1.0.6'
compile 'ch.qos.logback:logback-classic:1.0.6'
runtime 'ch.qos.logback:logback-access:1.0.6'
...
}
...
task release(type: Tar, dependsOn: war) {
extension = "tar.gz"
classifier = project.classifier
compression = Compression.GZIP
into('lib') {
from configurations.release.files
from configurations.providedCompile.files
}
into('lib/ext') {
// TODO: Right here I want to extract just logback-core-1.0.6.jar and logback-access-1.0.6.jar
}
...
}
How do I iterated over the dependencies to locate those specific files and drop them in the lib/ext directory created by into('lib/ext')?
Configurations are just (lazy) collections. You can iterate over them, filter them, etc. Note that you typically only want to do this in the execution phase of the build, not in the configuration phase. The code below achieves this by using the lazy FileCollection.filter() method. Another approach would have been to pass a closure to the Tar.from() method.
task release(type: Tar, dependsOn: war) {
...
into('lib/ext') {
from findJar('logback-core')
from findJar('logback-access')
}
}
def findJar(prefix) {
configurations.runtime.filter { it.name.startsWith(prefix) }
}
It is worth nothing that the accepted answer filters the Configuration as a FileCollection so within the collection you can only access the attributes of a file. If you want to filter on the dependency itself (on group, name, or version) rather than its filename in the cache then you can use something like:
task copyToLib(type: Copy) {
from findJarsByGroup(configurations.compile, 'org.apache.avro')
into "$buildSrc/lib"
}
def findJarsByGroup(Configuration config, groupName) {
configurations.compile.files { it.group.equals(groupName) }
}
files takes a dependencySpecClosure which is just a filter function on a Dependency, see: https://gradle.org/docs/current/javadoc/org/gradle/api/artifacts/Dependency.html

Resources