-
Notifications
You must be signed in to change notification settings - Fork 577
[TrimmableTypeMap] Merge library .aar manifests on the legacy merger path #12000
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1436,4 +1436,89 @@ public void AssemblyLevel_ApplicationManageSpaceActivity () | |
| Assert.NotNull (app); | ||
| Assert.Equal ("com.example.app.ManageActivity", (string?)app?.Attribute (AndroidNs + "manageSpaceActivity")); | ||
| } | ||
|
|
||
| [Fact] | ||
| public void LibraryManifests_MergedWithApplicationIdAndRelativeNamesResolved () | ||
| { | ||
| // Mirrors ManifestTest.MergeLibraryManifest: a library (.aar) manifest is merged into the | ||
| // app manifest, ${applicationId} resolves to the app package, and relative component names | ||
| // (".Type") are qualified with the library's own package attribute. | ||
| var libManifest = Path.Combine (Path.GetTempPath (), $"lib-manifest-{Path.GetRandomFileName ()}.xml"); | ||
| File.WriteAllText (libManifest, """ | ||
| <?xml version='1.0'?> | ||
| <manifest xmlns:android='http://schemas.android.com/apk/res/android' package='com.xamarin.test'> | ||
| <uses-sdk android:minSdkVersion='16'/> | ||
| <permission android:name='${applicationId}.permission.C2D_MESSAGE' android:protectionLevel='signature' /> | ||
| <application> | ||
| <activity android:name='.signin.internal.SignInHubActivity' /> | ||
| <provider | ||
| android:authorities='${applicationId}.FacebookInitProvider' | ||
| android:name='.internal.FacebookInitProvider' | ||
| android:exported='false' /> | ||
| <meta-data android:name='android.support.VERSION' android:value='25.4.0' /> | ||
| <meta-data android:name='android.support.VERSION' android:value='25.4.0' /> | ||
| </application> | ||
| </manifest> | ||
| """); | ||
| try { | ||
| var gen = CreateDefaultGenerator (); | ||
| gen.PackageName = "com.xamarin.manifest"; | ||
| gen.LibraryManifests = [libManifest]; | ||
| var template = ParseTemplate (""" | ||
| <?xml version="1.0" encoding="utf-8"?> | ||
| <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.xamarin.manifest"> | ||
| <uses-sdk /> | ||
| <application android:label="App" /> | ||
| </manifest> | ||
| """); | ||
|
|
||
| var doc = GenerateAndLoad (gen, template: template); | ||
|
|
||
| // ${applicationId} resolves to the app package on the merged permission. | ||
| var permission = doc.Root?.Elements ("permission") | ||
| .FirstOrDefault (e => (string?) e.Attribute (AttName) == "com.xamarin.manifest.permission.C2D_MESSAGE"); | ||
| Assert.NotNull (permission); | ||
|
|
||
| var app = doc.Root?.Element ("application"); | ||
| Assert.NotNull (app); | ||
|
|
||
| // Relative ".Type" names are qualified with the library package (com.xamarin.test). | ||
| var activity = app?.Elements ("activity") | ||
| .FirstOrDefault (e => (string?) e.Attribute (AttName) == "com.xamarin.test.signin.internal.SignInHubActivity"); | ||
| Assert.NotNull (activity); | ||
|
|
||
| var provider = app?.Elements ("provider") | ||
| .FirstOrDefault (e => (string?) e.Attribute (AttName) == "com.xamarin.test.internal.FacebookInitProvider"); | ||
| Assert.NotNull (provider); | ||
| // authorities uses ${applicationId} -> app package. | ||
| Assert.Equal ("com.xamarin.manifest.FacebookInitProvider", (string?) provider?.Attribute (AndroidNs + "authorities")); | ||
|
|
||
| // The two identical meta-data elements collapse to a single element. | ||
| var versionMeta = app?.Elements ("meta-data") | ||
| .Where (e => (string?) e.Attribute (AttName) == "android.support.VERSION") | ||
| .ToList (); | ||
| Assert.NotNull (versionMeta); | ||
| Assert.Single (versionMeta); | ||
| } finally { | ||
| File.Delete (libManifest); | ||
| } | ||
| } | ||
|
|
||
| [Fact] | ||
| public void LibraryManifests_MissingFileIgnored () | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🤖 💡 Testing — Good coverage of the successful merge and the missing-file skip. The remaining gap is the merge-failure branch: a malformed library manifest that makes (Rule: Test error paths, not just the happy path) |
||
| { | ||
| // A non-existent library manifest path is skipped without throwing. | ||
| var gen = CreateDefaultGenerator (); | ||
| gen.LibraryManifests = [Path.Combine (Path.GetTempPath (), $"does-not-exist-{Path.GetRandomFileName ()}.xml")]; | ||
| var template = ParseTemplate (""" | ||
| <?xml version="1.0" encoding="utf-8"?> | ||
| <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.app"> | ||
| <uses-sdk /> | ||
| <application android:label="App" /> | ||
| </manifest> | ||
| """); | ||
|
|
||
| var doc = GenerateAndLoad (gen, template: template); | ||
| Assert.NotNull (doc.Root?.Element ("application")); | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤖 💡 Patterns —
Warnwas widened toAction<int, string>?and now multiplexes two unrelated diagnostics through magic codes (0= ignore,4302= surface asXA4302).ManifestGeneratoralready models exactly this case with a dedicatedAction<string>? WarnInvalidPlaceholder; a parallelAction<string>? WarnLibraryManifestMergewould drop the0sentinel and thisif (code == ...)routing, and keep the two warnings independently wireable.Separately: the
code == 0path (theAssemblyLevelElementBuilder"Could not resolve ... type" warning) stays silently swallowed on the trimmable path. It was already dropped before this PR, so this is not a regression — but if that suppression is deliberate, a one-line note on why would save the next reader a spelunk.(Consistency with the existing
WarnInvalidPlaceholdercallback)