google / play-services-plugins

Plugins to help with using Google Play services SDK.
https://developers.google.com/android/guides/overview
Apache License 2.0
471 stars 138 forks source link

Unexpected library version checking error with range dependencies #189

Closed cgwyllie closed 7 months ago

cgwyllie commented 3 years ago

Describe the bug

Applying the google-services-plugin results in an unexpected error when including a dependency that in turn expresses another dependency using a range of versions.

For example:

app -> kumulos-android-debug:11.7.0 -> firebase-messaging:[19.0.0, 22.99.99]

When the google services plugin is applied, the following build error is produced:

In project 'app' a resolved Google Play services library dependency depends on another at an exact version (e.g. "[19.0.
0, 22.99.99]", but isn't being resolved to that version. Behavior exhibited by the library will be unknown.
Dependency failing: com.kumulos.android:kumulos-android-debug:11.7.0 -> com.google.firebase:firebase-messaging@[19.0.0, 
22.99.99], but firebase-messaging version was 22.0.0.
The following dependencies are project dependencies that are direct or have transitive dependencies that lead to the art
ifact with the issue.
-- Project 'app' depends onto com.google.firebase:firebase-bom@{strictly 28.2.0}
-- Project 'app' depends onto com.google.firebase:firebase-bom@28.2.0
-- Project 'app' depends onto com.kumulos.android:kumulos-android-debug@{strictly 11.7.0}
-- Project 'app' depends onto com.google.firebase:firebase-messaging@{strictly 22.0.0}
-- Project 'app' depends on project 'kumulos_sdk_flutter' which depends onto com.kumulos.android:kumulos-android-debug@1
1.7.0

To Reproduce

Steps to reproduce the behavior:

  1. Create an empty Android project in Android Studio
  2. Add the Kumulos dependency to the app's build.gradle:
android {
    // Exclude duplicate files from the build
    packagingOptions {
        exclude 'META-INF/NOTICE'
        exclude 'META-INF/ASL2.0'
        exclude 'META-INF/LICENSE'
    }

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

dependencies {
    // Kumulos debug & release libraries
    debugImplementation 'com.kumulos.android:kumulos-android-debug:11.7.0'
    releaseImplementation 'com.kumulos.android:kumulos-android-release:11.7.0'
}
  1. Apply the google-services gradle plugin and add a google-services.json file
  2. Try to build the project

Expected behavior

The version check should pass because the specific version resolved through BoM in the app project is 22.0.0, which is covered by the supported range of the Kumulos library [19.0.0, 22.99.99].

Desktop (please complete the following information):

Additional context

Perhaps we have misunderstood something about how to declare dependencies, but according to the gradle spec, it seems valid for us to express a range of supported FCM versions in our library. https://docs.gradle.org/current/userguide/single_versions.html

The relevant code doing version checking appears to be: https://github.com/google/play-services-plugins/blob/3f2750e577135a97115db74ef583b20136f1df29/strict-version-matcher-plugin/src/main/java/com/google/android/gms/dependencies/VersionEvaluation.kt#L14-L27

This code mentions handling version ranges, but it then also treats anything with [] as a specific version if strict matching is enabled. This seems like a small logic error, although we don't understand enough about the context of the plugin to say for sure.

I'm one of the maintainers of the Kumulos library so we can make any necessary changes on our side if we've made a mistake declaring supported ranges.

We'd appreciate any insight / resolution on this topic.

Thanks!

wfhm commented 3 years ago

@cgwyllie were you able to resolve this?

cgwyllie commented 3 years ago

@wfhm we were unable to resolve this directly. Our solution was to declare an up-to-date compileOnly dependency, and then have consumers use the Firebase BoM package to delcare the version of the library they want to use at runtime.