androidgradlehuawei-mobile-serviceshuawei-developersappgallery-connect

com.huawei.agconnect plugin not found


So I'm trying to add AppGallery connect gradle plugin to my android project using new Kotlin DSL syntax. But I'm getting error like this:

org.gradle.internal.exceptions.LocationAwareException: Build file 'D:\#KERJAAN\devbase\sample\build.gradle.kts' line: 3
Plugin [id: 'com.huawei.agconnect', version: '1.6.3.300'] was not found in any of the following sources:
- Gradle Core Plugins (plugin is not in 'org.gradle' namespace)
- Plugin Repositories (could not resolve plugin artifact 'com.huawei.agconnect:com.huawei.agconnect.gradle.plugin:1.6.3.300')
  Searched in the following repositories:
    Gradle Central Plugin Repository
    Google
    MavenRepo
    maven(https://developer.huawei.com/repo/)

What i did was adding repository for plugin like this in settings.gradle.kts:

pluginManagement {
    repositories {
        gradlePluginPortal()
        google()
        mavenCentral()
        maven { setUrl("https://developer.huawei.com/repo/") }
    }
}

And adding the plugin like this in app's build.gradle.kts:

plugins {
   id("com.huawei.agconnect") version "1.6.3.300"
}

Interestingly, It works if using classpath from the root build.gradle.kts. Does anyone know why?


Solution

  • Any Gradle plugin (this is not AGC specific at all) can only be loaded at the root project level, and then usually be applied on the module level. I've just tried to remove the buildscript block (alike in the question), which indeed leads to:

    Plugin [id: 'com.huawei.agconnect', version: '1.7.3.302', apply: false] was not found in any of the following sources:
    maven(https://developer.huawei.com/repo/)
    
    Plugin Repositories (could not resolve plugin artifact 'com.huawei.agconnect:com.huawei.agconnect.gradle.plugin:1.7.3.302')
    

    The plugin dependency won't resolve, while the pluginManagement keeps adding .gradle.plugin. If the repository would know about the full and not only the shorthanded name agcp, this should work out of the box (that's actually the default expected package name, unless changing it):

    com.huawei.agconnect:com.huawei.agconnect.gradle.plugin:1.7.3.302
    

    And this doesn't match:

    com.huawei.agconnect:agcp:1.7.3.302
    

    One can use pluginManagement.resolutionStrategy as a temporary workaround ...

    The settings.gradle is being used to rewrite the wrongfully assumed package name:

    pluginManagement {
        repositories {
            gradlePluginPortal()
            mavenCentral()
            google()
            maven { url 'https://developer.huawei.com/repo/' }
        }
        plugins {}
        resolutionStrategy {
            eachPlugin {
                if (it.requested.id.getNamespace() == 'com.huawei.agconnect') {
                    println ">> ${it.requested.id.id}"
                    if (it.requested.id.id == 'com.huawei.agconnect.agcp') {
                        it.useModule('com.huawei.agconnect:agcp:1.7.3.302')
                    }
                    if (it.requested.id.id == 'com.huawei.agconnect.apms') {
                        it.useModule('com.huawei.agconnect:agconnect-apms-plugin:1.6.1.300')
                    }
                    println ">> ${it.target}"
                } else {
                    println ">  ${it.target}"
                }
            }
        }
    }
    

    plugins have to be defined in build.gradle:

    plugins {
        id "com.android.application" version "7.3.1" apply false
        id "com.android.library" version "7.3.1" apply false
        id "com.huawei.agconnect.agcp" version "1.7.3.302" apply false
        id "com.huawei.agconnect.apms" version "1.6.1.300" apply false
    }
    

    println will output the updated (fake) id to artifact mapping it.target:

    [
        id: 'com.huawei.agconnect.agcp',
        version: '1.7.3.302',
        artifact: 'com.huawei.agconnect:agcp:1.7.3.302',
        apply: false
    ]
    

    When applying it, one still needs to use the real id:

    apply plugin: 'com.huawei.agconnect'
    

    It is just that (as of version 1.7.3.302) APMSTransform has some check in place, which requires to explicitly put AGP on classpath. The buildscript block is "almost" obsolete, if not APMSTransform would wrongfully assume, that it is the only place where the Android Gradle plugin can be loaded.

    /** Still required due to AGCP plugin. */
    buildscript {
        repositories {
            google()
        }
        dependencies {
            classpath 'com.android.tools.build:gradle:7.3.1'
        }
    }
    

    It would also need to check for either of these plugins:

    plugins {
        id "com.android.application" version "7.3.1" apply false
        id "com.android.library" version "7.3.1" apply false
    }
    

    For example:

    project.getPluginManager().hasPlugin('com.android.application') || project.getPluginManager().hasPlugin('com.android.library')
    

    In order to make this work flawlessly (without resolutionStrategy), this would require an updated check, in order not to get com.android.tools.build:gradle is no set in the build.gradle file and also an URL rewrite, which would handle the package name's .gradle.plugin suffix properly, so that com.huawei.agconnect.gradle.plugin and agcp would result in the same package download. resolutionStrategy indeed is the workaround and not the answer.