Skip to content

Publish Gradle Module Metadata and variant info #27

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions android-ktx/gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,4 @@ android.useAndroidX=true
android.enableJetifier=false
android.disableAutomaticComponentCreation=true

kotlin.stdlib.default.dependency=false
39 changes: 23 additions & 16 deletions android-ktx/lib/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -185,10 +185,10 @@ dependencies {
// androidx.work:work-runtime-ktx:2.8.0 requires 1.3.0
compileOnly 'androidx.annotation:annotation:1.3.0'

implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4"
compileOnly "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Jeff: How does this work? Who provides the library at runtime?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is just to filter the coroutines dependency from being published as an explicit runtime dependency in both the .pom and .module, which is what you were doing already when manually filtering the published pom dependencies.

By specifying the dependency as compileOnly, the library consumer needs to provide the dependency if they make use of any of the CBL KTX APIs that depend on coroutines-core APIs (same with work-runtime-ktx). But it makes the dependency optional if they don't use those APIs.

The tests add the dependencies as androidTestImplementation, so they're added to the test binaries.

Again, this is how the behavior was already, this just makes it explicit and allows it to be the same in both the .pom and the .module metadata.


// Work Manager support
implementation "androidx.work:work-runtime-ktx:2.8.1"
compileOnly "androidx.work:work-runtime-ktx:2.8.1"

implementation("com.couchbase.lite:${CBL_ANDROID_LIB}:${BUILD_VERSION}") { changing = true }

Expand All @@ -199,7 +199,10 @@ dependencies {
androidTestImplementation 'androidx.test:rules:1.5.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'

androidTestImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4"

// Work Manager Test support
androidTestImplementation "androidx.work:work-runtime-ktx:2.8.1"
androidTestImplementation "androidx.work:work-testing:2.8.1"
}

Expand Down Expand Up @@ -317,7 +320,7 @@ project.afterEvaluate {
artifactId CBL_ARTIFACT_ID
version BUILD_VERSION

artifact bundleReleaseAar
from components.release
artifact dokkaJar
artifact sourcesJar

Expand All @@ -327,12 +330,14 @@ project.afterEvaluate {
root.appendNode('description', CBL_DESCRIPTION)
root.children().last() + pomConfig

def dependenciesNode = root.appendNode('dependencies')
def dep = dependenciesNode.appendNode('dependency')
dep.appendNode('groupId', CBL_GROUP)
dep.appendNode('artifactId', CBL_ANDROID_LIB)
dep.appendNode('version', BUILD_VERSION)
dep.appendNode('type', CBL_ANDROID_TYPE)
def dependencies = root.dependencies.dependency

// Include only configured dependencies
dependencies.each {
if (CBL_ANDROID_LIB != it.artifactId.last().value().last()) {
it.parent().remove(it)
}
}
}
}

Expand All @@ -341,7 +346,7 @@ project.afterEvaluate {
artifactId CBL_ARTIFACT_ID
version BUILD_VERSION

artifact bundleDebugAar
from components.debug
artifact dokkaJar
artifact sourcesJar

Expand All @@ -351,12 +356,14 @@ project.afterEvaluate {
root.appendNode('description', CBL_DESCRIPTION)
root.children().last() + pomConfig

def dependenciesNode = root.appendNode('dependencies')
def dep = dependenciesNode.appendNode('dependency')
dep.appendNode('groupId', CBL_GROUP)
dep.appendNode('artifactId', CBL_ANDROID_LIB)
dep.appendNode('version', BUILD_VERSION)
dep.appendNode('type', CBL_ANDROID_TYPE)
def dependencies = root.dependencies.dependency

// Include only configured dependencies
dependencies.each {
if (CBL_ANDROID_LIB != it.artifactId.last().value().last()) {
it.parent().remove(it)
}
}
}
}
}
Expand Down
1 change: 1 addition & 0 deletions android/gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,4 @@ android.useAndroidX=true
android.enableJetifier=false
android.disableAutomaticComponentCreation=true

kotlin.stdlib.default.dependency=false
80 changes: 62 additions & 18 deletions android/lib/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@
// Please try to keep this build file as similar to the other family build files
// as is possible.
//

import org.gradle.api.attributes.java.TargetJvmEnvironment
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType

import java.time.Instant
import java.util.regex.Pattern

Expand Down Expand Up @@ -501,32 +505,76 @@ publishing {
}

project.afterEvaluate {
// Include Java variant definition in Gradle Module Metadata
def javaApiConfig = configurations.create("javaApi").tap {
canBeResolved = false
canBeConsumed = true
attributes {
attribute(Category.CATEGORY_ATTRIBUTE, objects.named(Category.class, Category.LIBRARY))
attribute(TargetJvmEnvironment.TARGET_JVM_ENVIRONMENT_ATTRIBUTE, objects.named(TargetJvmEnvironment.class, TargetJvmEnvironment.STANDARD_JVM))
attribute(KotlinPlatformType.attribute, KotlinPlatformType.jvm)
attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage.class, Usage.JAVA_API))
}
}

// Add variant artifact as a dependencies, since it's in another module
dependencies {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this going to work for both the CE and EE versions?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All of this should work the same for both CE and EE, just with the variant artifacts being different for EE. So

javaApi("com.couchbase.lite:couchbase-lite-java-ee:$version")

here and

androidApi("com.couchbase.lite:couchbase-lite-android-ee:$version")

in the Java lib's build.gradle.

It might make sense to use a variable, like CBL_ANDROID_LIB, as is used in other places currently.

javaApi("com.couchbase.lite:couchbase-lite-java:$version")
}

def javaRuntimeConfig = configurations.create("javaRuntime").tap {
extendsFrom(javaApiConfig)
canBeResolved = false
canBeConsumed = true
attributes {
attribute(Category.CATEGORY_ATTRIBUTE, objects.named(Category.class, Category.LIBRARY))
attribute(TargetJvmEnvironment.TARGET_JVM_ENVIRONMENT_ATTRIBUTE, objects.named(TargetJvmEnvironment.class, TargetJvmEnvironment.STANDARD_JVM))
attribute(KotlinPlatformType.attribute, KotlinPlatformType.jvm)
attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage.class, Usage.JAVA_RUNTIME))
}
}

// AdhocComponentWithVariants is wrapped by anonymous component class, find it with reflection
// can be replaced with (components.release as AdhocComponentWithVariants)
// with this fix: https://youtrack.jetbrains.com/issue/KT-58830
def adhocField = components.release.class.getDeclaredFields()
.find { it.getType() == AdhocComponentWithVariants }
adhocField.setAccessible(true)
AdhocComponentWithVariants adhocComponent = adhocField.get(components.release)

adhocComponent.with {
addVariantsFromConfiguration(javaApiConfig) {
mapToMavenScope("compile")
mapToOptional()
}
addVariantsFromConfiguration(javaRuntimeConfig) {
mapToMavenScope("runtime")
mapToOptional()
}
}

publishing {
publications {
libRelease(MavenPublication) {
groupId CBL_GROUP
artifactId CBL_ARTIFACT_ID
version BUILD_VERSION

artifact bundleReleaseAar
from components.release
artifact sourcesJar
artifact javadocJar

// include dependencies
pom.withXml {
def root = asNode()
root.appendNode('description', CBL_DESCRIPTION)
root.children().last() + pomConfig

def dependenciesNode = root.appendNode('dependencies')
def dependencies = root.dependencies.dependency

// Include only configured dependencies
configurations.implementation.allDependencies.each {
if (DEPENDENCIES.contains(it.name)) {
def dep = dependenciesNode.appendNode('dependency')
dep.appendNode('groupId', it.group)
dep.appendNode('artifactId', it.name)
dep.appendNode('version', it.version)
dependencies.each {
if (!DEPENDENCIES.contains(it.artifactId.last().value().last())) {
it.parent().remove(it)
}
}
}
Expand All @@ -537,25 +585,21 @@ project.afterEvaluate {
artifactId CBL_ARTIFACT_ID
version BUILD_VERSION

artifact bundleDebugAar
from components.debug
artifact sourcesJar
artifact javadocJar

// include dependencies
pom.withXml {
def root = asNode()
root.appendNode('description', CBL_DESCRIPTION)
root.children().last() + pomConfig

def dependenciesNode = root.appendNode('dependencies')
def dependencies = root.dependencies.dependency

// Include only configured dependencies
configurations.implementation.allDependencies.each {
if (DEPENDENCIES.contains(it.name)) {
def dep = dependenciesNode.appendNode('dependency')
dep.appendNode('groupId', it.group)
dep.appendNode('artifactId', it.name)
dep.appendNode('version', it.version)
dependencies.each {
if (!DEPENDENCIES.contains(it.artifactId.last().value().last())) {
it.parent().remove(it)
}
}
}
Expand Down
1 change: 1 addition & 0 deletions java/gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,4 @@ org.gradle.jvmargs=-Xmx4608m
# Required to publish to ProGet (see https://github.com/gradle/gradle/issues/11308)
systemProp.org.gradle.internal.publish.checksums.insecure=true

kotlin.stdlib.default.dependency=false
55 changes: 47 additions & 8 deletions java/lib/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@
import com.github.spotbugs.snom.SpotBugsTask

import org.apache.tools.ant.filters.ReplaceTokens
import org.gradle.api.attributes.java.TargetJvmEnvironment
import org.gradle.internal.os.OperatingSystem
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType

import java.util.regex.Pattern

Expand Down Expand Up @@ -603,6 +605,46 @@ project.afterEvaluate {
tasks.withType(Zip) { duplicatesStrategy = DuplicatesStrategy.EXCLUDE }
}

// Include Android variant definition in Gradle Module Metadata
def androidApiConfig = configurations.create("androidApi").tap {
canBeResolved = false
canBeConsumed = true
attributes {
attribute(Category.CATEGORY_ATTRIBUTE, objects.named(Category.class, Category.LIBRARY))
attribute(TargetJvmEnvironment.TARGET_JVM_ENVIRONMENT_ATTRIBUTE, objects.named(TargetJvmEnvironment.class, TargetJvmEnvironment.ANDROID))
attribute(KotlinPlatformType.attribute, KotlinPlatformType.androidJvm)
attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage.class, Usage.JAVA_API))
}
}

// Add variant artifact as a dependencies, since it's in another module
dependencies {
androidApi("com.couchbase.lite:couchbase-lite-android:$version")
}

def androidRuntimeConfig = configurations.create("androidRuntime").tap {
extendsFrom(androidApiConfig)
canBeResolved = false
canBeConsumed = true
attributes {
attribute(Category.CATEGORY_ATTRIBUTE, objects.named(Category.class, Category.LIBRARY))
attribute(TargetJvmEnvironment.TARGET_JVM_ENVIRONMENT_ATTRIBUTE, objects.named(TargetJvmEnvironment.class, TargetJvmEnvironment.ANDROID))
attribute(KotlinPlatformType.attribute, KotlinPlatformType.androidJvm)
attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage.class, Usage.JAVA_RUNTIME))
}
}

(components.java as AdhocComponentWithVariants).with {
addVariantsFromConfiguration(androidApiConfig) {
mapToMavenScope("compile")
mapToOptional()
}
addVariantsFromConfiguration(androidRuntimeConfig) {
mapToMavenScope("runtime")
mapToOptional()
}
}

publishing {
publications {
couchbaseLiteJava(MavenPublication) {
Expand All @@ -612,7 +654,7 @@ publishing {
artifactId "${JAR_ARTIFACT}${suffix}"
version BUILD_VERSION

artifact jar
from components.java
artifact sourcesJar
artifact javadocJar

Expand Down Expand Up @@ -646,15 +688,12 @@ publishing {
}

withXml {
def dependenciesNode = asNode().appendNode('dependencies')
def dependencies = asNode().dependencies.dependency

// Include only configured dependencies
configurations.implementation.allDependencies.each {
if (DEPENDENCIES.contains(it.name)) {
def dep = dependenciesNode.appendNode('dependency')
dep.appendNode('groupId', it.group)
dep.appendNode('artifactId', it.name)
dep.appendNode('version', it.version)
dependencies.each {
if (!DEPENDENCIES.contains(it.artifactId.last().value())) {
it.parent().remove(it)
}
}
}
Expand Down