From 6653003fa978a0f85ae656b3956410c1365f530c Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Tue, 10 Oct 2023 09:26:26 +0300 Subject: [PATCH 01/11] feat: Add flag to enable analyzers --- .../content/unoapp/.template.config/dotnetcli.host.json | 4 ++++ .../content/unoapp/.template.config/template.json | 7 +++++++ src/Uno.Templates/content/unoapp/Directory.Build.props | 7 +++++++ 3 files changed, 18 insertions(+) diff --git a/src/Uno.Templates/content/unoapp/.template.config/dotnetcli.host.json b/src/Uno.Templates/content/unoapp/.template.config/dotnetcli.host.json index 5d4e85cf..7202916e 100644 --- a/src/Uno.Templates/content/unoapp/.template.config/dotnetcli.host.json +++ b/src/Uno.Templates/content/unoapp/.template.config/dotnetcli.host.json @@ -53,6 +53,10 @@ "longName": "dependency-injection", "shortName": "di" }, + "analyzers": { + "longName": "analyzers", + "shortName": "analyzers" + }, "configuration": { "longName": "configuration", "shortName": "config" diff --git a/src/Uno.Templates/content/unoapp/.template.config/template.json b/src/Uno.Templates/content/unoapp/.template.config/template.json index af86ea8c..a7ea8d98 100644 --- a/src/Uno.Templates/content/unoapp/.template.config/template.json +++ b/src/Uno.Templates/content/unoapp/.template.config/template.json @@ -406,6 +406,13 @@ "type": "parameter", "datatype": "bool" }, + "analyzers": { + "displayName": "Analyzers", + "description": "Enable C# analyzers", + "type": "parameter", + "datatype": "bool", + "defaultValue": "true" + }, "configuration": { "displayName": "Configuration", "description": "Load configuration information from appsettings.json", diff --git a/src/Uno.Templates/content/unoapp/Directory.Build.props b/src/Uno.Templates/content/unoapp/Directory.Build.props index 0023e1b0..2e1e3743 100644 --- a/src/Uno.Templates/content/unoapp/Directory.Build.props +++ b/src/Uno.Templates/content/unoapp/Directory.Build.props @@ -52,6 +52,13 @@ 1.9.0.2 2.6.0.1 + + + true + true + Recommended + true + From a3adac13366b4a9290a7866fa7a267a5379400c3 Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Tue, 10 Oct 2023 09:51:48 +0300 Subject: [PATCH 02/11] chore: Fix analyzer warnings --- src/Uno.Templates/content/unoapp/Directory.Build.props | 4 ++++ .../MyExtensionsApp._1.UITests.csproj | 6 ++++++ .../MyExtensionsApp._1/Infrastructure/DebugHandler.cs | 6 +++--- .../MyExtensionsApp._1/Services/Caching/WeatherCache.cs | 6 +++--- 4 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/Uno.Templates/content/unoapp/Directory.Build.props b/src/Uno.Templates/content/unoapp/Directory.Build.props index 2e1e3743..73b9324f 100644 --- a/src/Uno.Templates/content/unoapp/Directory.Build.props +++ b/src/Uno.Templates/content/unoapp/Directory.Build.props @@ -58,6 +58,10 @@ true Recommended true + + + + $(NoWarn);CA1010;CA1848 diff --git a/src/Uno.Templates/content/unoapp/MyExtensionsApp._1.UITests/MyExtensionsApp._1.UITests.csproj b/src/Uno.Templates/content/unoapp/MyExtensionsApp._1.UITests/MyExtensionsApp._1.UITests.csproj index d17ddb3b..21ad677b 100644 --- a/src/Uno.Templates/content/unoapp/MyExtensionsApp._1.UITests/MyExtensionsApp._1.UITests.csproj +++ b/src/Uno.Templates/content/unoapp/MyExtensionsApp._1.UITests/MyExtensionsApp._1.UITests.csproj @@ -2,6 +2,12 @@ $baseTargetFramework$ + + + + $(NoWarn);CA1707 + + diff --git a/src/Uno.Templates/content/unoapp/MyExtensionsApp._1/Infrastructure/DebugHandler.cs b/src/Uno.Templates/content/unoapp/MyExtensionsApp._1/Infrastructure/DebugHandler.cs index e23b750b..19b7f4de 100644 --- a/src/Uno.Templates/content/unoapp/MyExtensionsApp._1/Infrastructure/DebugHandler.cs +++ b/src/Uno.Templates/content/unoapp/MyExtensionsApp._1/Infrastructure/DebugHandler.cs @@ -1,7 +1,7 @@ //+:cnd:noEmit namespace MyExtensionsApp._1.Infrastructure; -internal class DebugHttpHandler : DelegatingHandler +internal sealed class DebugHttpHandler : DelegatingHandler { #if (useLogging) private readonly ILogger _logger; @@ -40,7 +40,7 @@ protected async override Task SendAsync( _logger.LogDebugMessage($"{key}: {values}"); } - var content = request.Content is not null ? await request.Content.ReadAsStringAsync() : null; + var content = request.Content is not null ? await request.Content.ReadAsStringAsync(cancellationToken) : null; if (!string.IsNullOrEmpty(content)) { _logger.LogDebugMessage(content); @@ -57,7 +57,7 @@ protected async override Task SendAsync( Console.Error.WriteLine($" {key}: {values}"); } - var content = request.Content is not null ? await request.Content.ReadAsStringAsync() : null; + var content = request.Content is not null ? await request.Content.ReadAsStringAsync(cancellationToken) : null; if (!string.IsNullOrEmpty(content)) { Console.Error.WriteLine(content); diff --git a/src/Uno.Templates/content/unoapp/MyExtensionsApp._1/Services/Caching/WeatherCache.cs b/src/Uno.Templates/content/unoapp/MyExtensionsApp._1/Services/Caching/WeatherCache.cs index 5ad2242d..ac64df3e 100644 --- a/src/Uno.Templates/content/unoapp/MyExtensionsApp._1/Services/Caching/WeatherCache.cs +++ b/src/Uno.Templates/content/unoapp/MyExtensionsApp._1/Services/Caching/WeatherCache.cs @@ -23,7 +23,7 @@ public WeatherCache(IApiClient api, ISerializer serializer) } #endif - private bool IsConnected => NetworkInformation.GetInternetConnectionProfile().GetNetworkConnectivityLevel() == NetworkConnectivityLevel.InternetAccess; + private static bool IsConnected => NetworkInformation.GetInternetConnectionProfile().GetNetworkConnectivityLevel() == NetworkConnectivityLevel.InternetAccess; public async ValueTask> GetForecast(CancellationToken token) { @@ -38,7 +38,7 @@ public async ValueTask> GetForecast(Cancellation #if (useLogging) _logger.LogWarning("App is offline and cannot connect to the API."); #endif - throw new Exception("No internet connection"); + throw new InvalidOperationException("No internet connection"); } var response = await _api.GetWeather(token); @@ -62,7 +62,7 @@ public async ValueTask> GetForecast(Cancellation } } - private async ValueTask GetFile(CreationCollisionOption option) => + private static async ValueTask GetFile(CreationCollisionOption option) => await ApplicationData.Current.TemporaryFolder.CreateFileAsync("weather.json", option); private async ValueTask GetCachedWeather() From a2204a14bb5680d4ee8edf02f6ff2fb6933693eb Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Tue, 10 Oct 2023 10:02:14 +0300 Subject: [PATCH 03/11] chore: Progress --- src/Uno.Templates/content/unoapp/.globalconfig | 4 ++++ .../MyExtensionsApp._1/Services/Caching/WeatherCache.cs | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) create mode 100644 src/Uno.Templates/content/unoapp/.globalconfig diff --git a/src/Uno.Templates/content/unoapp/.globalconfig b/src/Uno.Templates/content/unoapp/.globalconfig new file mode 100644 index 00000000..f23746f4 --- /dev/null +++ b/src/Uno.Templates/content/unoapp/.globalconfig @@ -0,0 +1,4 @@ +is_global = true + +# IDE0055: Fix formatting +dotnet_diagnostic.IDE0055.severity = warning diff --git a/src/Uno.Templates/content/unoapp/MyExtensionsApp._1/Services/Caching/WeatherCache.cs b/src/Uno.Templates/content/unoapp/MyExtensionsApp._1/Services/Caching/WeatherCache.cs index ac64df3e..e89b7489 100644 --- a/src/Uno.Templates/content/unoapp/MyExtensionsApp._1/Services/Caching/WeatherCache.cs +++ b/src/Uno.Templates/content/unoapp/MyExtensionsApp._1/Services/Caching/WeatherCache.cs @@ -65,7 +65,7 @@ public async ValueTask> GetForecast(Cancellation private static async ValueTask GetFile(CreationCollisionOption option) => await ApplicationData.Current.TemporaryFolder.CreateFileAsync("weather.json", option); - private async ValueTask GetCachedWeather() + private static async ValueTask GetCachedWeather() { var file = await GetFile(CreationCollisionOption.OpenIfExists); var properties = await file.GetBasicPropertiesAsync(); @@ -84,6 +84,6 @@ private async ValueTask Save(IImmutableList weather, Cancellati { var weatherText = _serializer.ToString(weather); var file = await GetFile(CreationCollisionOption.ReplaceExisting); - await File.WriteAllTextAsync(file.Path, weatherText); + await File.WriteAllTextAsync(file.Path, weatherText, token); } } From 70c5d43cf3ab3b8372ba98039a25f7f514f77cc8 Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Tue, 10 Oct 2023 10:24:20 +0300 Subject: [PATCH 04/11] chore: Fix formatting --- .../content/unoapp/MyExtensionsApp._1/AppResources.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Uno.Templates/content/unoapp/MyExtensionsApp._1/AppResources.cs b/src/Uno.Templates/content/unoapp/MyExtensionsApp._1/AppResources.cs index bb376698..b9f376fb 100644 --- a/src/Uno.Templates/content/unoapp/MyExtensionsApp._1/AppResources.cs +++ b/src/Uno.Templates/content/unoapp/MyExtensionsApp._1/AppResources.cs @@ -14,13 +14,13 @@ public AppResources() #if useToolkit // Load Uno.UI.Toolkit and Material Resources this.Build(r => r.Merged( - new MaterialToolkitTheme( + new MaterialToolkitTheme( new Styles.ColorPaletteOverride(), new Styles.MaterialFontsOverride()))); #else // Load Uno.UI.Toolkit and Material Resources this.Build(r => r.Merged( - new MaterialTheme( + new MaterialTheme( new Styles.ColorPaletteOverride(), new Styles.MaterialFontsOverride()))); #endif From 55c4dd967c0d9b9f3a4ba6389ff6176c356b2eff Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Tue, 10 Oct 2023 10:47:52 +0300 Subject: [PATCH 05/11] chore: Few fixes --- .../MyExtensionsApp._1.MauiControls/UnoImageConverter.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Uno.Templates/content/unoapp/MyExtensionsApp._1.MauiControls/UnoImageConverter.cs b/src/Uno.Templates/content/unoapp/MyExtensionsApp._1.MauiControls/UnoImageConverter.cs index 4134cb9a..bc8d47a8 100644 --- a/src/Uno.Templates/content/unoapp/MyExtensionsApp._1.MauiControls/UnoImageConverter.cs +++ b/src/Uno.Templates/content/unoapp/MyExtensionsApp._1.MauiControls/UnoImageConverter.cs @@ -5,16 +5,16 @@ namespace MyExtensionsApp._1; public class UnoImageConverter : IValueConverter { - public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture) { #if ANDROID - return (value + "").Replace('/','_').Replace('\\','_'); + return (value + "").Replace('/', '_').Replace('\\', '_'); #else return value; #endif } - public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) { throw new NotImplementedException(); } From 07b49ac78f64381215701173396129c230b9d38e Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Tue, 10 Oct 2023 11:45:41 +0300 Subject: [PATCH 06/11] chore: Fix formatting --- .../unoapp/MyExtensionsApp._1/Infrastructure/DebugHandler.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Uno.Templates/content/unoapp/MyExtensionsApp._1/Infrastructure/DebugHandler.cs b/src/Uno.Templates/content/unoapp/MyExtensionsApp._1/Infrastructure/DebugHandler.cs index 19b7f4de..888ffc86 100644 --- a/src/Uno.Templates/content/unoapp/MyExtensionsApp._1/Infrastructure/DebugHandler.cs +++ b/src/Uno.Templates/content/unoapp/MyExtensionsApp._1/Infrastructure/DebugHandler.cs @@ -34,7 +34,7 @@ protected async override Task SendAsync( { _logger.LogDebugMessage($"{request.RequestUri} ({request.Method})"); } - + foreach ((var key, var values) in request.Headers.ToDictionary(x => x.Key, x => string.Join(", ", x.Value))) { _logger.LogDebugMessage($"{key}: {values}"); From f73fe6251b2c4918bd881b879c045f84641f8892 Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Tue, 10 Oct 2023 12:28:32 +0300 Subject: [PATCH 07/11] chore: Fix CA1305 --- .../content/unoapp/MyExtensionsApp._1.Server/Program.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Uno.Templates/content/unoapp/MyExtensionsApp._1.Server/Program.cs b/src/Uno.Templates/content/unoapp/MyExtensionsApp._1.Server/Program.cs index ce5d517f..a547ab7e 100644 --- a/src/Uno.Templates/content/unoapp/MyExtensionsApp._1.Server/Program.cs +++ b/src/Uno.Templates/content/unoapp/MyExtensionsApp._1.Server/Program.cs @@ -1,4 +1,7 @@ //+:cnd:noEmit +#if (useSerilog) +using System.Globalization; +#endif #if (useHttp) using System.Text.Json.Serialization.Metadata; #endif @@ -16,8 +19,8 @@ { #if (useSerilog) Log.Logger = new LoggerConfiguration() - .WriteTo.Console() - .WriteTo.File(Path.Combine("App_Data", "Logs", "log.txt")) + .WriteTo.Console(formatProvider: CultureInfo.InvariantCulture) + .WriteTo.File(Path.Combine("App_Data", "Logs", "log.txt"), formatProvider: CultureInfo.InvariantCulture) .CreateLogger(); #endif var builder = WebApplication.CreateBuilder(args); From 531b720774d40c490ccdd4bc44491dbb9094eb45 Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Tue, 10 Oct 2023 12:36:47 +0300 Subject: [PATCH 08/11] chore: Fix CA1859 --- .../MyExtensionsApp._1.Server/Apis/WeatherForecastApi.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Uno.Templates/content/unoapp/MyExtensionsApp._1.Server/Apis/WeatherForecastApi.cs b/src/Uno.Templates/content/unoapp/MyExtensionsApp._1.Server/Apis/WeatherForecastApi.cs index 30e79cab..2a98fc6f 100644 --- a/src/Uno.Templates/content/unoapp/MyExtensionsApp._1.Server/Apis/WeatherForecastApi.cs +++ b/src/Uno.Templates/content/unoapp/MyExtensionsApp._1.Server/Apis/WeatherForecastApi.cs @@ -41,7 +41,6 @@ private static IEnumerable GetForecast(ILoggerFactory loggerFac { logger.LogInformation("Weather forecast for {Date} is a {Summary} {TemperatureC}°C", x.Date, x.Summary, x.TemperatureC); return x; - }) - .ToArray(); + }); } } From 95ce1e019fae4809d99acb344d36673325cf4e6b Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Tue, 10 Oct 2023 12:58:32 +0300 Subject: [PATCH 09/11] chore: Fix CA1305, CA2016, and formatting --- .../content/unoapp/MyExtensionsApp._1/App.recommended.cs | 6 ++++-- .../unoapp/MyExtensionsApp._1/Presentation/LoginModel.cs | 5 ++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/Uno.Templates/content/unoapp/MyExtensionsApp._1/App.recommended.cs b/src/Uno.Templates/content/unoapp/MyExtensionsApp._1/App.recommended.cs index 1539b740..ae3dfffd 100644 --- a/src/Uno.Templates/content/unoapp/MyExtensionsApp._1/App.recommended.cs +++ b/src/Uno.Templates/content/unoapp/MyExtensionsApp._1/App.recommended.cs @@ -1,4 +1,6 @@ //-:cnd:noEmit +using System.Globalization; + namespace MyExtensionsApp._1; //+:cnd:noEmit @@ -123,7 +125,7 @@ protected async override void OnLaunched(LaunchActivatedEventArgs args) credentials ??= new Dictionary(); credentials[TokenCacheExtensions.AccessTokenKey] = "SampleToken"; credentials[TokenCacheExtensions.RefreshTokenKey] = "RefreshToken"; - credentials["Expiry"] = DateTime.Now.AddMinutes(5).ToString("g"); + credentials["Expiry"] = DateTime.Now.AddMinutes(5).ToString("g", DateTimeFormatInfo.InvariantInfo); return ValueTask.FromResult?>(credentials); } @@ -142,7 +144,7 @@ protected async override void OnLaunched(LaunchActivatedEventArgs args) // Return IDictionary containing any tokens used by service calls or in the app tokenDictionary ??= new Dictionary(); tokenDictionary[TokenCacheExtensions.AccessTokenKey] = "NewSampleToken"; - tokenDictionary["Expiry"] = DateTime.Now.AddMinutes(5).ToString("g"); + tokenDictionary["Expiry"] = DateTime.Now.AddMinutes(5).ToString("g", DateTimeFormatInfo.InvariantInfo); return ValueTask.FromResult?>(tokenDictionary); } diff --git a/src/Uno.Templates/content/unoapp/MyExtensionsApp._1/Presentation/LoginModel.cs b/src/Uno.Templates/content/unoapp/MyExtensionsApp._1/Presentation/LoginModel.cs index 3283122a..62b6c6b5 100644 --- a/src/Uno.Templates/content/unoapp/MyExtensionsApp._1/Presentation/LoginModel.cs +++ b/src/Uno.Templates/content/unoapp/MyExtensionsApp._1/Presentation/LoginModel.cs @@ -7,7 +7,7 @@ public partial record LoginModel(IDispatcher Dispatcher, INavigator Navigator, I //+:cnd:noEmit #if useCustomAuthentication - public IState Username => State.Value(this, () => string.Empty); + public IState Username => State.Value(this, () => string.Empty); public IState Password => State.Value(this, () => string.Empty); #endif @@ -25,8 +25,7 @@ public async ValueTask Login(CancellationToken token) //-:cnd:noEmit if (success) { - await Navigator.NavigateViewModelAsync(this, qualifier: Qualifiers.ClearBackStack); + await Navigator.NavigateViewModelAsync(this, qualifier: Qualifiers.ClearBackStack, token); } } - } From 4e6f864774c13c7e629d73583c3ea7094485f0ee Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Tue, 10 Oct 2023 13:26:33 +0300 Subject: [PATCH 10/11] chore: Pass token correctly --- .../unoapp/MyExtensionsApp._1/Presentation/LoginModel.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Uno.Templates/content/unoapp/MyExtensionsApp._1/Presentation/LoginModel.cs b/src/Uno.Templates/content/unoapp/MyExtensionsApp._1/Presentation/LoginModel.cs index 62b6c6b5..9a445372 100644 --- a/src/Uno.Templates/content/unoapp/MyExtensionsApp._1/Presentation/LoginModel.cs +++ b/src/Uno.Templates/content/unoapp/MyExtensionsApp._1/Presentation/LoginModel.cs @@ -25,7 +25,7 @@ public async ValueTask Login(CancellationToken token) //-:cnd:noEmit if (success) { - await Navigator.NavigateViewModelAsync(this, qualifier: Qualifiers.ClearBackStack, token); + await Navigator.NavigateViewModelAsync(this, qualifier: Qualifiers.ClearBackStack, cancellation: token); } } } From 2707cc5a6844073f660fdce3c928f4e5edbfdab4 Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Tue, 10 Oct 2023 13:41:46 +0300 Subject: [PATCH 11/11] chore: Fix CA1805 --- .../MyExtensionsApp._1.MauiControls/EmbeddedControl.xaml.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Uno.Templates/content/unoapp/MyExtensionsApp._1.MauiControls/EmbeddedControl.xaml.cs b/src/Uno.Templates/content/unoapp/MyExtensionsApp._1.MauiControls/EmbeddedControl.xaml.cs index 08e09657..20e799d5 100644 --- a/src/Uno.Templates/content/unoapp/MyExtensionsApp._1.MauiControls/EmbeddedControl.xaml.cs +++ b/src/Uno.Templates/content/unoapp/MyExtensionsApp._1.MauiControls/EmbeddedControl.xaml.cs @@ -10,7 +10,7 @@ public EmbeddedControl() //+:cnd:noEmit #if (!useMvvmOrMvux) - private int count=0; + private int count; public void CounterClicked(object sender, EventArgs e) { CounterButton.Text = ++count switch