xamarin / AndroidX

AndroidX bindings for .NET for Android
MIT License
173 stars 42 forks source link

Add support for exact version NuGet dependencies #770

Closed jpobst closed 8 months ago

jpobst commented 11 months ago

Context: https://github.com/xamarin/AndroidX/issues/764

Today, binderator enforces "exact dependencies" specified in POM files. If you do not fulfill them you get this error:

System.Exception: 
No matching artifact config found for: 
    androidx.preference.preference:[1.2.0]
to satisfy dependency of: 
    androidx.preference.preference-ktx:1.2.0

However, when we create NuGets we ignore this requirement and instead allow a "greater than or equal to" dependency. When types move from one package to another and the package versions are not kept locked, it can result in errors like Type androidx.lifecycle.DispatchQueue is defined multiple times. (https://github.com/xamarin/AndroidX/issues/764)

A wrinkle is that we generally use <ProjectReference> to create our dependency tree and it does not currently support specifying an "exact" version dependency. https://github.com/NuGet/Home/issues/5556

A workaround is to use a custom target in Directory.Build.targets that allows a ExactVersion="true" attribute to be added to a <ProjectReference>. This attribute is then taken into account when NuGet pack is run.

Some references are dependencyOnly: true. These are specified using <PackageReference> so we also need to support specifying exact references there as well.

This should help mitigate future errors caused by types moving between Java packages that should always have synced versions.

An additional requirement is that the exact version should only apply to the Java version piece of our NuGet versions. That is, if the Java version is locked to [1.2.0], we should still allow the user to use NuGet versions like 1.2.0.7. This will be expressed as [1.2.0,1.3.0).

CI Example of <ProjectReference>:

image

CI Example of <PackageReference>:

image