badoo / Reaktive

Kotlin multi-platform implementation of Reactive Extensions
Apache License 2.0
1.17k stars 58 forks source link

Unable to find a matching variant of com.badoo.reaktive #406

Closed mpivchev closed 4 years ago

mpivchev commented 4 years ago

Setting up the dependencies for this lib gives me the following errors:

Unable to find a matching variant of com.badoo.reaktive:reaktive-android:1.1.8:
  - Variant 'android-releaseApiElements' capability com.badoo.reaktive:reaktive-android:1.1.8:
      - Incompatible attributes:
          - Required com.android.build.api.attributes.BuildTypeAttr 'debug' and found incompatible value 'release'.
          - Required org.gradle.usage 'java-runtime' and found incompatible value 'java-api'.
      - Other attributes:
          - Found com.android.build.api.attributes.VariantAttr 'release' but wasn't required.
          - Required com.android.build.gradle.internal.dependency.AndroidTypeAttr 'Aar' and found compatible value 'Aar'.
          - Found org.gradle.status 'release' but wasn't required.
          - Required org.jetbrains.kotlin.platform.type 'androidJvm' and found compatible value 'androidJvm'.
  - Variant 'android-releaseRuntimeElements' capability com.badoo.reaktive:reaktive-android:1.1.8:
      - Incompatible attribute:
          - Required com.android.build.api.attributes.BuildTypeAttr 'debug' and found incompatible value 'release'.
      - Other attributes:
          - Found com.android.build.api.attributes.VariantAttr 'release' but wasn't required.
          - Required com.android.build.gradle.internal.dependency.AndroidTypeAttr 'Aar' and found compatible value 'Aar'.
          - Found org.gradle.status 'release' but wasn't required.
          - Required org.gradle.usage 'java-runtime' and found compatible value 'java-runtime'.
          - Required org.jetbrains.kotlin.platform.type 'androidJvm' and found compatible value 'androidJvm'.
  - Variant 'metadata-api' capability com.badoo.reaktive:reaktive-android:1.1.8:
      - Incompatible attributes:
          - Required org.gradle.usage 'java-runtime' and found incompatible value 'kotlin-api'.
          - Required org.jetbrains.kotlin.platform.type 'androidJvm' and found incompatible value 'common'.
      - Other attributes:
          - Required com.android.build.api.attributes.BuildTypeAttr 'debug' but no value provided.
          - Required com.android.build.gradle.internal.dependency.AndroidTypeAttr 'Aar' but no value provided.
          - Found org.gradle.status 'release' but wasn't required.

It seems something gets confused about the build types?

Here's the multiplatform gradle confiig:

import com.suparnatural.plugins.graphql.suparnaturalGraphQl

val serializationVersion by extra { "0.14.0" }
val coroutinesVersion by extra { "1.3.3" }
val reaktiveVersion by extra { "1.1.8" }
val graphQLVersion by extra { "1.0.9" }

plugins {
    kotlin("multiplatform")
    kotlin("plugin.serialization")
    kotlin("native.cocoapods")
}

buildscript {
    repositories {
        maven(url="https://dl.bintray.com/suparnatural/kotlin-multiplatform")
    }
    dependencies {
        classpath("com.suparnatural.plugins:graphql-plugin:1.0.8")
    }
}

apply(plugin="com.suparnatural.plugins.graphql")

// CocoaPods requires the podspec to have a version.
version = "1.0"

kotlin {
    // Add a platform switching to have an IDE support.
    val buildForDevice = project.findProperty("kotlin.native.cocoapods.target") == "ios_arm"
    if (buildForDevice) {
        iosArm64("iOS64")
        iosArm32("iOS32")

        val iOSMain by sourceSets.creating
        sourceSets["iOS64Main"].dependsOn(iOSMain)
        sourceSets["iOS32Main"].dependsOn(iOSMain)
    } else {
        iosX64("iOS")
    }

    jvm("android")

    sourceSets["commonMain"].dependencies {
        implementation("org.jetbrains.kotlin:kotlin-stdlib-common")
        implementation("org.jetbrains.kotlinx:kotlinx-serialization-runtime-common:$serializationVersion")
        implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core-common:$coroutinesVersion")

        implementation("com.badoo.reaktive:reaktive:$reaktiveVersion")
        implementation("com.badoo.reaktive:reaktive-annotations:$reaktiveVersion")
        implementation("com.badoo.reaktive:coroutines-interop:$reaktiveVersion")

        implementation("suparnatural-kotlin-multiplatform:graphql-metadata:$graphQLVersion")
        implementation("suparnatural-kotlin-multiplatform:rx-runtime-reaktive-metadata:$graphQLVersion")
    }

    sourceSets["androidMain"].dependencies {
        implementation("org.jetbrains.kotlin:kotlin-stdlib")
        implementation("org.jetbrains.kotlinx:kotlinx-serialization-runtime:$serializationVersion")
        implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutinesVersion")

        implementation("com.badoo.reaktive:reaktive-android:$reaktiveVersion")
        implementation("com.badoo.reaktive:reaktive-annotations-android-debug:$reaktiveVersion")
        implementation("com.badoo.reaktive:coroutines-interop-android-debug:$reaktiveVersion")

        implementation("suparnatural-kotlin-multiplatform:graphql-android-debug:$graphQLVersion")
//        implementation("suparnatural-kotlin-multiplatform:graphql-android:$graphQLVersion")
        implementation("suparnatural-kotlin-multiplatform:rx-runtime-reaktive-android-debug:$graphQLVersion")
//        implementation("suparnatural-kotlin-multiplatform:rx-runtime-reaktive-android:$graphQLVersion")
    }

    sourceSets["iOSMain"].dependencies {
        implementation("org.jetbrains.kotlinx:kotlinx-serialization-runtime-native:$serializationVersion")

        val isDevice = System.getenv("SDK_NAME")?.startsWith("iphoneos") == true
        val reaktivePlatform = if (isDevice) "ios64" else "iossim"
        val graphQLPlatform = if (isDevice) "iosarm64" else "iosx64"

        implementation("com.badoo.reaktive:reaktive-$reaktivePlatform:$reaktiveVersion")
        implementation("com.badoo.reaktive:reaktive-annotations-$reaktivePlatform:$reaktiveVersion")
        implementation("com.badoo.reaktive:coroutines-interop-$reaktivePlatform:$reaktiveVersion")

        implementation("suparnatural-kotlin-multiplatform:graphql-$graphQLPlatform:$graphQLVersion")
        implementation("suparnatural-kotlin-multiplatform:rx-runtime-reaktive-$graphQLPlatform:$graphQLVersion")
    }
}

suparnaturalGraphQl {
    packageName = "com.********.********.graphql.models"
    endpointUrl = "http://localhost:3000/graphql"
    documentsPath = "../ios/Sources/**/*.graphql"
    outputDirectoryPath = "src/commonMain/kotlin"
}

The app gradle config:

import org.jetbrains.kotlin.config.KotlinCompilerVersion

plugins {
    id("com.android.application")
    kotlin("android")
    kotlin("android.extensions")
}

android {
    compileSdkVersion(29)
    buildToolsVersion("29.0.2")
    defaultConfig {
        applicationId = "com.**********.******"
        minSdkVersion(15)
        targetSdkVersion(29)
        versionCode = 1
        versionName = "1.0"
        testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        getByName("release") {
            isMinifyEnabled = false
            proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
        }
    }
}

dependencies {
    implementation(project(":mobile-core"))
    implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar"))))
    implementation(kotlin("stdlib-jdk7", KotlinCompilerVersion.VERSION))
    implementation("androidx.appcompat:appcompat:1.1.0")
    implementation("androidx.core:core-ktx:1.1.0")
    implementation("androidx.constraintlayout:constraintlayout:1.1.3")
    implementation("androidx.lifecycle:lifecycle-extensions:2.0.0")
    implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.0.0")
    testImplementation("junit:junit:4.12")
    androidTestImplementation("androidx.test.ext:junit:1.1.1")
    androidTestImplementation("androidx.test.espresso:espresso-core:3.2.0")
}

I tried changing the implementation(project(":mobile-core")) to implementation(project(":mobile-core", configuration = "default")) but that makes it so the Android implementation can't find the shared code.

Any ideas how this can be fixed?

arkivanov commented 4 years ago

Hello, could you please try the following:

  1. Make sure you are using Gradle 5.3 or newer
  2. Try removing Reaktive dependency specifications from platform specific source sets. So only keep Reaktive dependencies for commonMain source set, no need to specify them for any other source set like androidMain or iOSMain.
mpivchev commented 4 years ago

I removed deps from androidMain but now GraphQL cannot resolve. It throws a Unresolved reference: GraphQlOperation. In the docs of GraphQL it says I need to include the android specific Reaktive deps for it to work. Not sure if it's related to this.

Current config:

    sourceSets["commonMain"].dependencies {
        implementation("org.jetbrains.kotlin:kotlin-stdlib-common")
        implementation("org.jetbrains.kotlinx:kotlinx-serialization-runtime-common:$serializationVersion")
        implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core-common:$coroutinesVersion")

        implementation("com.badoo.reaktive:reaktive:$reaktiveVersion")
        implementation("com.badoo.reaktive:reaktive-annotations:$reaktiveVersion")
        implementation("com.badoo.reaktive:coroutines-interop:$reaktiveVersion")

        implementation("suparnatural-kotlin-multiplatform:graphql-metadata:$graphQLVersion")
        implementation("suparnatural-kotlin-multiplatform:rx-runtime-reaktive-metadata:$graphQLVersion")
    }

    sourceSets["androidMain"].dependencies {
        implementation("org.jetbrains.kotlin:kotlin-stdlib")
        implementation("org.jetbrains.kotlinx:kotlinx-serialization-runtime:$serializationVersion")
        implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutinesVersion")

//        implementation("com.badoo.reaktive:reaktive-android:$reaktiveVersion")
//        implementation("com.badoo.reaktive:reaktive-annotations-android-debug:$reaktiveVersion")
//        implementation("com.badoo.reaktive:coroutines-interop-android-debug:$reaktiveVersion")

        implementation("suparnatural-kotlin-multiplatform:graphql-android-debug:$graphQLVersion")
        implementation("suparnatural-kotlin-multiplatform:graphql-android:$graphQLVersion")
//        implementation("suparnatural-kotlin-multiplatform:rx-runtime-reaktive-android-debug:$graphQLVersion")
//        implementation("suparnatural-kotlin-multiplatform:rx-runtime-reaktive-android:$graphQLVersion")
    }
arkivanov commented 4 years ago

Ok, now the configuration of Reaktive is correct. Next, seems that the GraphQL library is published without Gradle Metadata, so separate configurations per source set are required. Your configuration here appears to be correct as well.

What is not correct - you have to apply com.android.library plugin and configure it as described here. You will need to do something like this:

plugins {
    kotlin("multiplatform")
    id("com.android.library")
    // Other plugins
}

android {
    compileSdkVersion(28)
    // More config here
}

// More config here
arkivanov commented 4 years ago

Closing the issue. Feel free to reopen if you have any problem resolving Reaktive dependencies.

Drjacky commented 4 years ago

@arkivanov Still getting the error:

Could not find com.badoo.reaktive:reaktive:1.1.13. Searched in the following locations:

Shared build.gradle:

import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget

plugins {
    kotlin("multiplatform")
}

kotlin {
    jvm("android")

    //select iOS target platform depending on the Xcode environment variables
    val iOSTarget: (String, KotlinNativeTarget.() -> Unit) -> KotlinNativeTarget =
        if (System.getenv("SDK_NAME")?.startsWith("iphoneos") == true)
            ::iosArm64
        else
            ::iosX64

    iOSTarget("ios") {
        binaries {
            framework {
                baseName = "shared"
            }
        }
    }

    sourceSets {
        val commonMain by getting {
            dependencies {
                implementation("org.jetbrains.kotlin:kotlin-stdlib-common")
                implementation("com.badoo.reaktive:reaktive:1.1.13")
            }
        }

        val androidMain by getting {
            dependsOn(commonMain)
            dependencies {
                implementation("org.jetbrains.kotlin:kotlin-stdlib")
            }
        }
    }

}

val packForXcode by tasks.creating(Sync::class) {
    val targetDir = File(buildDir, "xcode-frameworks")
    //selecting the right configuration for the iOS framework depending on the Xcode environment variables
    val mode = System.getenv("CONFIGURATION") ?: "DEBUG"
    val framework = kotlin.targets.getByName<KotlinNativeTarget>("ios").binaries.getFramework(mode)

    inputs.property("mode", mode)
    dependsOn(framework.linkTask)

    from({ framework.outputDirectory })
    into(targetDir)

    /// generate a helpful ./gradlew wrapper with embedded Java path
    doLast {
        val gradlew = File(targetDir, "gradlew")
        gradlew.writeText("#!/bin/bash\nexport 'JAVA_HOME=${System.getProperty("java.home")}'\ncd '${rootProject.rootDir}'\n./gradlew \$@\n")
        gradlew.setExecutable(true)
    }
}

tasks.getByName("build").dependsOn(packForXcode)

Root build.gradle:

buildscript {
    val kotlinVersion: String by extra
    val gradleAndroidVersion: String by extra

    repositories {
        maven("https://kotlin.bintray.com/kotlinx")
        maven("https://dl.bintray.com/jetbrains/kotlin-native-dependencies")
        maven("https://dl.bintray.com/kotlin/kotlin-dev")
        maven("https://dl.bintray.com/badoo/maven")

        google()
        jcenter()
    }
    dependencies {
        classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion")
        classpath("com.android.tools.build:gradle:$gradleAndroidVersion")
    }
}

allprojects {
    repositories {
        mavenCentral()
        maven("https://dl.bintray.com/kotlin/kotlinx")
        maven("https://dl.bintray.com/kotlin/kotlin-dev")

        google()
        jcenter()
    }
}

tasks.register<Delete>("clean") {
    delete(rootProject.buildDir)
}
arkivanov commented 4 years ago

Hey @Drjacky, according to the error Reaktive's repository is not in the list of checked repositories. I think you need to add Reaktive's repository in your root build.gradle as follows:

allprojects {
    repositories {
        ...
        maven("https://dl.bintray.com/badoo/maven")
    }
}

Let me know if you if it helps.

Drjacky commented 4 years ago

@arkivanov Yes, fixed, thanks. My fault, I had put it in buildscript scope not in allprojects.