From 2abfe6b6eac28990169cb8be9b40e2ae2d16bd21 Mon Sep 17 00:00:00 2001 From: Jonathan Pobst Date: Thu, 19 May 2022 14:39:13 -0500 Subject: [PATCH] [ci] Ensure all namespaces are verified in published-namespaces.txt. --- azure-pipelines.yml | 4 + published-namespaces.txt | 478 +++++++++++++++++++++++++++++++++++++++ utilities.cake | 74 ++++++ 3 files changed, 556 insertions(+) create mode 100644 published-namespaces.txt diff --git a/azure-pipelines.yml b/azure-pipelines.yml index b04c9d105..8c56ca480 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -68,6 +68,10 @@ jobs: dotnet tool update --global boots --version $(BootsVersion) boots --url $(LegacyXamarinAndroidVsix) --downgrade-first condition: eq(variables['System.JobName'], 'windows') + + postBuildSteps: + - pwsh: | + dotnet cake utilities.cake -t=verify-namespace-file tools: - 'xamarin.androidbinderator.tool': '$(AndroidBinderatorVersion)' - 'xamarin.androidx.migration.tool': '$(AndroidXMigrationVersion)' diff --git a/published-namespaces.txt b/published-namespaces.txt new file mode 100644 index 000000000..7fa6a7329 --- /dev/null +++ b/published-namespaces.txt @@ -0,0 +1,478 @@ +Android.Support.CustomTabs +Android.Support.Customtabs.Trusted +Android.Support.V4.App +Android.Support.V4.Graphics.Drawable +Android.Support.V4.Media +Android.Support.V4.Media.Session +Android.Support.V4.OS +Android.Support.Wearable.Authentication +Android.Support.Wearable.Notifications +AndroidX.Activity +AndroidX.Activity.ContextAware +AndroidX.Activity.Result +AndroidX.Activity.Result.Contract +AndroidX.Ads.Identifier +AndroidX.Ads.Identifier.Internal +AndroidX.Ads.Identifier.Provider +AndroidX.Ads.Identifier.Provider.Internal +AndroidX.Annotations +AndroidX.Annotations.Experimental +AndroidX.AppCompat.App +AndroidX.AppCompat.Content.Res +AndroidX.AppCompat.Graphics.Drawable +AndroidX.AppCompat.Resources +AndroidX.AppCompat.Text +AndroidX.AppCompat.View +AndroidX.AppCompat.View.Menu +AndroidX.AppCompat.Widget +AndroidX.Arch.Core.Executor +AndroidX.Arch.Core.Internal +AndroidX.Arch.Core.Util +AndroidX.AsyncLayoutInflater.View +AndroidX.AutoFill +AndroidX.AutoFill.Inline +AndroidX.AutoFill.Inline.Common +AndroidX.AutoFill.Inline.V1 +AndroidX.Biometric +AndroidX.Browser.BrowserActions +AndroidX.Browser.CustomTabs +AndroidX.Browser.Trusted +AndroidX.Browser.Trusted.Sharing +AndroidX.Browser.Trusted.Splashscreens +AndroidX.Camera.Camera2 +AndroidX.Camera.Camera2.Internal +AndroidX.Camera.Camera2.Internal.Annotation +AndroidX.Camera.Camera2.Internal.Compat +AndroidX.Camera.Camera2.Internal.Compat.Quirk +AndroidX.Camera.Camera2.Internal.Compat.Workaround +AndroidX.Camera.Camera2.InterOp +AndroidX.Camera.Camera2Internal.Compat.Params +AndroidX.Camera.Core +AndroidX.Camera.Core.Impl +AndroidX.Camera.Core.Impl.Annotation +AndroidX.Camera.Core.Impl.Utils +AndroidX.Camera.Core.Impl.Utils.Executors +AndroidX.Camera.Core.Impl.Utils.Futures +AndroidX.Camera.Core.Internal +AndroidX.Camera.Core.Internal.Compat.Quirk +AndroidX.Camera.Core.Internal.Compat.Workaround +AndroidX.Camera.Core.Internal.Utils +AndroidX.Camera.Lifecycle +AndroidX.Car.App +AndroidX.Car.App.Annotations +AndroidX.Car.App.Connection +AndroidX.Car.App.Constraints +AndroidX.Car.App.Hardware +AndroidX.Car.App.Hardware.Common +AndroidX.Car.App.Hardware.Info +AndroidX.Car.App.Managers +AndroidX.Car.App.Model +AndroidX.Car.App.Model.Constraints +AndroidX.Car.App.Model.SignIn +AndroidX.Car.App.Navigation +AndroidX.Car.App.Navigation.Model +AndroidX.Car.App.Notification +AndroidX.Car.App.Serialization +AndroidX.Car.App.Utils +AndroidX.Car.App.Validation +AndroidX.Car.App.Versioning +AndroidX.Car.Cluster.Navigation +AndroidX.Car.Drawer +AndroidX.Car.Navigation.Utils +AndroidX.Car.Util +AndroidX.Car.UXRestrictions +AndroidX.Car.Widget +AndroidX.Car.Widget.ItemDecorators +AndroidX.CardView.Widget +AndroidX.Collection +AndroidX.Concurrent.Futures +AndroidX.ConstraintLayout.Core +AndroidX.ConstraintLayout.Core.Motion +AndroidX.ConstraintLayout.Core.Motion.Key +AndroidX.ConstraintLayout.Core.Motion.Parse +AndroidX.ConstraintLayout.Core.Motion.Utils +AndroidX.ConstraintLayout.Core.Parser +AndroidX.ConstraintLayout.Core.State +AndroidX.ConstraintLayout.Core.State.Helpers +AndroidX.ConstraintLayout.Core.Widgets +AndroidX.ConstraintLayout.Core.Widgets.Analyzer +AndroidX.ConstraintLayout.Helper.Widget +AndroidX.ConstraintLayout.Motion.Utils +AndroidX.ConstraintLayout.Motion.Widget +AndroidX.ConstraintLayout.Solver +AndroidX.ConstraintLayout.Solver.State +AndroidX.ConstraintLayout.Solver.State.Helpers +AndroidX.ConstraintLayout.Solver.Widgets +AndroidX.ConstraintLayout.Solver.Widgets.Analyzer +AndroidX.ConstraintLayout.Utils.Widget +AndroidX.ConstraintLayout.Widget +AndroidX.ContentPager.Content +AndroidX.CoordinatorLayout.Widget +AndroidX.Core.AccessibilityService +AndroidX.Core.Animation +AndroidX.Core.App +AndroidX.Core.App.UnusedAppRestrictions +AndroidX.Core.Content +AndroidX.Core.Content.PM +AndroidX.Core.Content.Resources +AndroidX.Core.Database +AndroidX.Core.Database.Sqlite +AndroidX.Core.Database.SqlLite +AndroidX.Core.Google.Shortcuts +AndroidX.Core.Google.Shortcuts.Builders +AndroidX.Core.Graphics +AndroidX.Core.Graphics.Drawable +AndroidX.Core.Hardware.Display +AndroidX.Core.Hardware.Fingerprint +AndroidX.Core.Internal.View +AndroidX.Core.Location +AndroidX.Core.Math +AndroidX.Core.Net +AndroidX.Core.OS +AndroidX.Core.Provider +AndroidX.Core.Role +AndroidX.Core.SplashScreen +AndroidX.Core.Telephony +AndroidX.Core.Telephony.Mbms +AndroidX.Core.Text +AndroidX.Core.Text.Util +AndroidX.Core.Transition +AndroidX.Core.Util +AndroidX.Core.View +AndroidX.Core.View.Accessibility +AndroidX.Core.View.Animation +AndroidX.Core.View.InputMethod +AndroidX.Core.Widget +AndroidX.CursorAdapter.Widget +AndroidX.CustomView.View +AndroidX.CustomView.Widget +AndroidX.DataBinding +AndroidX.DataBinding.Adapters +AndroidX.DataBinding.Library +AndroidX.DataBinding.Library.BaseAdapters +AndroidX.DocumentFile.Provider +AndroidX.DrawerLayout.Widget +AndroidX.DynamicAnimation +AndroidX.Emoji.Bundled +AndroidX.Emoji.Text +AndroidX.Emoji.Widget +AndroidX.Emoji2.Text +AndroidX.Emoji2.Text.FlatBuffer +AndroidX.Emoji2.ViewsIntegration +AndroidX.ExifInterface.Media +AndroidX.Fragment.App +AndroidX.Fragment.App.StrictMode +AndroidX.GridLayout.Widget +AndroidX.Heifwriter +AndroidX.Interpolator.View.Animation +AndroidX.Leanback.Animation +AndroidX.Leanback.App +AndroidX.Leanback.Database +AndroidX.Leanback.Graphics +AndroidX.Leanback.Media +AndroidX.Leanback.Preference +AndroidX.Leanback.Preference.Internal +AndroidX.Leanback.System +AndroidX.Leanback.Transition +AndroidX.Leanback.Util +AndroidX.Leanback.Widget +AndroidX.Leanback.Widget.Picker +AndroidX.Legacy.App +AndroidX.Legacy.Content +AndroidX.Legacy.Widget +AndroidX.Lifecycle +AndroidX.Loader.App +AndroidX.Loader.Content +AndroidX.LocalBroadcastManager.Content +AndroidX.Media +AndroidX.Media.App +AndroidX.Media.Session +AndroidX.Media.Utils +AndroidX.Media2.Common +AndroidX.Media2.Session +AndroidX.Media2.Widget +AndroidX.MediaRouter.App +AndroidX.MediaRouter.Media +AndroidX.Navigation +AndroidX.Navigation.Fragment +AndroidX.Navigation.UI +AndroidX.Paging +AndroidX.Paging.RxJava2 +AndroidX.Palette.Graphics +AndroidX.PercentLayout.Widget +AndroidX.Preference +AndroidX.Preference.Internal +AndroidX.Print +AndroidX.ProfileInstallers +AndroidX.Recommendation.App +AndroidX.RecyclerView.Selection +AndroidX.RecyclerView.Widget +AndroidX.ResourceInspection.Annotation +AndroidX.Room +AndroidX.Room.Guava +AndroidX.Room.Migration +AndroidX.Room.RxJava3 +AndroidX.Room.Util +AndroidX.SavedState +AndroidX.Security.Crypto +AndroidX.Slice +AndroidX.Slice.Builders +AndroidX.Slice.Compat +AndroidX.Slice.Core +AndroidX.Slice.Widget +AndroidX.SlidingPaneLayout.Widget +AndroidX.Sqlite.Db +AndroidX.Sqlite.Db.Framework +AndroidX.Startup +AndroidX.SwipeRefreshLayout.Widget +AndroidX.Text.Emoji.FlatBuffer +AndroidX.Tracing +AndroidX.Transitions +AndroidX.TvProvider.Media.Tv +AndroidX.VectorDrawable.Graphics.Drawable +AndroidX.VersionedParcelable +AndroidX.ViewBinding +AndroidX.ViewPager.Widget +AndroidX.ViewPager2.Adapter +AndroidX.ViewPager2.Widget +AndroidX.Wear.Activity +AndroidX.Wear.Ambient +AndroidX.Wear.Input +AndroidX.Wear.Internal.Widget +AndroidX.Wear.Internal.Widget.Drawer +AndroidX.Wear.Ongoing +AndroidX.Wear.Phone.Interactions +AndroidX.Wear.Phone.Interactions.Authentication +AndroidX.Wear.Phone.Interactions.Notifications +AndroidX.Wear.Provider +AndroidX.Wear.Remote.Interactions +AndroidX.Wear.Utils +AndroidX.Wear.Widget +AndroidX.Wear.Widget.Drawer +AndroidX.WebKit +AndroidX.WebKit.ChromiumLibBoundary +AndroidX.WebKit.ChromiumLibBoundary.Util +AndroidX.WebKit.Internal +AndroidX.Window.Core +AndroidX.Window.Embedding +AndroidX.Window.Extensions +AndroidX.Window.Java.Layout +AndroidX.Window.Layout +AndroidX.Work +AndroidX.Work.Impl.Background.Greedy +AndroidX.Work.Impl.Background.SystemJob +AndroidX.Work.Impl.Constraints +AndroidX.Work.Impl.Constraints.Controllers +AndroidX.Work.Impl.Constraints.Trackers +AndroidX.Work.Impl.Diagnostics +AndroidX.Work.Impl.Foreground +AndroidX.Work.Impl.Model +AndroidX.Work.Impl.Utils +AndroidX.Work.Impl.Utils.Futures +AndroidX.Work.Impl.Utils.TaskExecutor +AndroidX.Work.Impl.Workers +AndroidX.Work.MultiProcess +Google.Android.Material.Animation +Google.Android.Material.AppBar +Google.Android.Material.Badge +Google.Android.Material.Behavior +Google.Android.Material.BottomAppBar +Google.Android.Material.BottomNavigation +Google.Android.Material.BottomSheet +Google.Android.Material.Button +Google.Android.Material.Canvas +Google.Android.Material.Card +Google.Android.Material.CheckBox +Google.Android.Material.Chip +Google.Android.Material.CircularReveal +Google.Android.Material.CircularReveal.CardView +Google.Android.Material.CircularReveal.CoordinatorLayout +Google.Android.Material.Color +Google.Android.Material.DatePicker +Google.Android.Material.Dialog +Google.Android.Material.Divider +Google.Android.Material.Drawable +Google.Android.Material.Elevation +Google.Android.Material.Expandable +Google.Android.Material.FloatingActionButton +Google.Android.Material.ImageView +Google.Android.Material.Internal +Google.Android.Material.Math +Google.Android.Material.Motion +Google.Android.Material.Navigation +Google.Android.Material.NavigationRail +Google.Android.Material.ProgressIndicator +Google.Android.Material.RadioButton +Google.Android.Material.Resources +Google.Android.Material.Ripple +Google.Android.Material.Shadow +Google.Android.Material.Shape +Google.Android.Material.Slider +Google.Android.Material.Snackbar +Google.Android.Material.Stateful +Google.Android.Material.SwitchMaterial +Google.Android.Material.Tabs +Google.Android.Material.Tabs.AppCompat.App +Google.Android.Material.TextField +Google.Android.Material.TextView +Google.Android.Material.Theme +Google.Android.Material.Theme.Overlay +Google.Android.Material.TimePicker +Google.Android.Material.Tooltip +Google.Android.Material.Transformation +Google.Android.Material.Transition +Google.Android.Material.Transition.Platform +Google.AutoValue.Annotations +Google.AutoValue.Extension.Serializable +Google.AutoValue.Extension.ToPrettyString +Google.Common.Util.Concurrent +Google.Common.Util.Concurrent.Internal +GoogleGson +GoogleGson.Annotations +GoogleGson.Reflect +GoogleGson.Stream +IntelliJ.Lang.Annotations +Java.Interop +JetBrains.Annotations +Kotlin +Kotlin.Annotation +Kotlin.Collections +Kotlin.Collections.Builders +Kotlin.Collections.Jdk8 +Kotlin.Collections.Unsigned +Kotlin.Comparisons +Kotlin.Concurrent +Kotlin.Contracts +Kotlin.Coroutines +Kotlin.Coroutines.Cancellation +Kotlin.Coroutines.Intrinsics +Kotlin.Coroutines.Jvm.Internal +Kotlin.Experimental +Kotlin.Internal +Kotlin.IO +Kotlin.IO.Path +Kotlin.Jdk7 +Kotlin.JS +Kotlin.Jvm +Kotlin.Jvm.Functions +Kotlin.Jvm.Internal +Kotlin.Jvm.Internal.Markers +Kotlin.Jvm.Internal.Unsafe +Kotlin.Jvm.Jdk8 +Kotlin.Math +Kotlin.Properties +Kotlin.Random +Kotlin.Ranges +Kotlin.Reflect +Kotlin.Reflect.Full +Kotlin.Reflect.Jvm +Kotlin.Sequences +Kotlin.Streams.Jdk8 +Kotlin.System +Kotlin.Text +Kotlin.Text.Jdk8 +Kotlin.Time +Kotlin.Time.Jdk8 +Microsoft.CodeAnalysis +ReactiveStreams +ReactiveX +ReactiveX.Annotations +ReactiveX.Disposables +ReactiveX.Exceptions +ReactiveX.Flowables +ReactiveX.Functions +ReactiveX.Internal.Disposables +ReactiveX.Internal.Functions +ReactiveX.Internal.Fuseable +ReactiveX.Internal.Observers +ReactiveX.Internal.Operators.Completable +ReactiveX.Internal.Operators.Flowable +ReactiveX.Internal.Operators.Maybe +ReactiveX.Internal.Operators.Mixed +ReactiveX.Internal.Operators.Observable +ReactiveX.Internal.Operators.Parallel +ReactiveX.Internal.Operators.Single +ReactiveX.Internal.Queue +ReactiveX.Internal.Schedulers +ReactiveX.Internal.Subscribers +ReactiveX.Internal.Subscriptions +ReactiveX.Internal.Util +ReactiveX.Observables +ReactiveX.Observers +ReactiveX.Parallel +ReactiveX.Plugins +ReactiveX.Processors +ReactiveX.RxJava3.Annotations +ReactiveX.RxJava3.Core +ReactiveX.RxJava3.Disposables +ReactiveX.RxJava3.Exceptions +ReactiveX.RxJava3.Flowables +ReactiveX.RxJava3.Functions +ReactiveX.RxJava3.Internal.Disposables +ReactiveX.RxJava3.Internal.Functions +ReactiveX.RxJava3.Internal.Fuseable +ReactiveX.RxJava3.Internal.JDK8 +ReactiveX.RxJava3.Internal.Observers +ReactiveX.RxJava3.Internal.Operators.Completable +ReactiveX.RxJava3.Internal.Operators.Flowable +ReactiveX.RxJava3.Internal.Operators.Maybe +ReactiveX.RxJava3.Internal.Operators.Mixed +ReactiveX.RxJava3.Internal.Operators.Observable +ReactiveX.RxJava3.Internal.Operators.Parallel +ReactiveX.RxJava3.Internal.Operators.Single +ReactiveX.RxJava3.Internal.Queue +ReactiveX.RxJava3.Internal.Schedulers +ReactiveX.RxJava3.Internal.Subscribers +ReactiveX.RxJava3.Internal.Subscriptions +ReactiveX.RxJava3.Internal.Util +ReactiveX.RxJava3.Observables +ReactiveX.RxJava3.Observers +ReactiveX.RxJava3.Operators +ReactiveX.RxJava3.Parallel +ReactiveX.RxJava3.Plugins +ReactiveX.RxJava3.Processors +ReactiveX.RxJava3.Schedulers +ReactiveX.RxJava3.Subjects +ReactiveX.RxJava3.Subscribers +ReactiveX.Schedulers +ReactiveX.Subjects +ReactiveX.Subscribers +System.Runtime.CompilerServices +System.Runtime.Versioning +Xamarin.Android.ReactiveStreams +Xamarin.Google.Crypto.Tink +Xamarin.Google.Crypto.Tink.Aead +Xamarin.Google.Crypto.Tink.Aead.Subtle +Xamarin.Google.Crypto.Tink.Android +Xamarin.Google.Crypto.Tink.Annotations +Xamarin.Google.Crypto.Tink.Configs +Xamarin.Google.Crypto.Tink.DAead +Xamarin.Google.Crypto.Tink.Hybrid +Xamarin.Google.Crypto.Tink.Hybrid.Subtle +Xamarin.Google.Crypto.Tink.Integration.Android +Xamarin.Google.Crypto.Tink.Mac +Xamarin.Google.Crypto.Tink.Prf +Xamarin.Google.Crypto.Tink.Proto +Xamarin.Google.Crypto.Tink.Shaded.Protobuf +Xamarin.Google.Crypto.Tink.Signature +Xamarin.Google.Crypto.Tink.Signature.Internal +Xamarin.Google.Crypto.Tink.StreamingAead +Xamarin.Google.Crypto.Tink.Subtle +Xamarin.Google.Crypto.Tink.Subtle.Prf +Xamarin.Google.Crypto.Tink.Tinkkey +Xamarin.Kotlin +Xamarin.KotlinX.Coroutines +Xamarin.KotlinX.Coroutines.Channels +Xamarin.KotlinX.Coroutines.CoroutinesAndroid +Xamarin.KotlinX.Coroutines.Flow +Xamarin.KotlinX.Coroutines.Future +Xamarin.KotlinX.Coroutines.Guava +Xamarin.KotlinX.Coroutines.Intrinsics +Xamarin.KotlinX.Coroutines.Reactive +Xamarin.KotlinX.Coroutines.Rx2 +Xamarin.KotlinX.Coroutines.Scheduling +Xamarin.KotlinX.Coroutines.Selects +Xamarin.KotlinX.Coroutines.Stream +Xamarin.KotlinX.Coroutines.Sync +Xamarin.KotlinX.Coroutines.Test +Xamarin.KotlinX.Coroutines.Time diff --git a/utilities.cake b/utilities.cake index a131932d5..3520e42ed 100644 --- a/utilities.cake +++ b/utilities.cake @@ -6,9 +6,11 @@ #addin nuget:?package=WeCantSpell.Hunspell&version=3.0.1 #addin nuget:?package=Newtonsoft.Json&version=12.0.3 #addin nuget:?package=Cake.FileHelpers&version=3.2.1 +#addin nuget:?package=Mono.Cecil&version=0.11.4 using System.Collections.Generic; +using Mono.Cecil; using Newtonsoft.Json; using Newtonsoft.Json.Linq; @@ -818,6 +820,78 @@ Task("dependencies") } ); +Task("generate-namespace-file") + .Does + ( + () => + { + var list = FindNamespacesInDirectory ("./generated"); + System.IO.File.WriteAllLines ("published-namespaces.txt", list); + } + ); + +Task("verify-namespace-file") + .Does + ( + () => + { + var new_list = FindNamespacesInDirectory ("./generated"); + var old_list = System.IO.File.ReadAllLines ("published-namespaces.txt"); + + var unhandled_changes = false; + + var new_ns = new_list.Except (old_list); + + if (new_ns.Any ()) { + unhandled_changes = true; + Console.WriteLine ("New Namespaces"); + Console.WriteLine ("--------------"); + + foreach (var ns in new_ns) + Console.WriteLine (ns); + + Console.WriteLine (); + } + + var removed_ns = old_list.Except (new_list); + + if (removed_ns.Any ()) { + unhandled_changes = true; + Console.WriteLine ("Removed Namespaces"); + Console.WriteLine ("------------------"); + + foreach (var ns in removed_ns) + Console.WriteLine (ns); + } + + if (unhandled_changes) + throw new Exception ("Namespaces were added or removed."); + } + ); + +static List FindNamespacesInDirectory (string directory) +{ + var list = new SortedSet (); + + foreach (var file in System.IO.Directory.EnumerateFiles (directory, "*.dll", SearchOption.AllDirectories)) + foreach (var ns in FindNamespaces (file)) + list.Add (ns); + + return list.ToList (); +} + +static List FindNamespaces (string assembly) +{ + var asm = AssemblyDefinition.ReadAssembly (assembly); + var list = new SortedSet (); + + foreach (var module in asm.Modules) + foreach (var type in module.Types) + if (!string.IsNullOrWhiteSpace (type.Namespace)) + list.Add (type.Namespace); + + return list.ToList (); +} Task ("Default")