From 7d5f7834d650b8f0e077b02e009ae55e18bddef6 Mon Sep 17 00:00:00 2001 From: David Kallesen Date: Sat, 30 Mar 2024 00:29:19 +0100 Subject: [PATCH 1/2] feat: Extend DotnetProjectType with MauiApp --- src/Atc.DotNet/Enums/DotnetProjectType.cs | 37 ++++++++++++----------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/src/Atc.DotNet/Enums/DotnetProjectType.cs b/src/Atc.DotNet/Enums/DotnetProjectType.cs index a0f8ae16..b6e5b635 100644 --- a/src/Atc.DotNet/Enums/DotnetProjectType.cs +++ b/src/Atc.DotNet/Enums/DotnetProjectType.cs @@ -15,36 +15,37 @@ public enum DotnetProjectType CliApp = 0x000008, BlazorServerApp = 0x000010, BlazorWAsmApp = 0x000020, - IosApp = 0x000040, - UwpApp = 0x000080, - WebApp = 0x000100, - WpfApp = 0x000200, - WinFormApp = 0x000400, + MauiApp = 0x000040, + IosApp = 0x000080, + UwpApp = 0x000100, + WebApp = 0x000200, + WpfApp = 0x000400, + WinFormApp = 0x000800, // Libraries - Library = 0x000800, - RazorLibrary = 0x001000, - UwpLibrary = 0x002000, - WpfLibrary = 0x004000, + Library = 0x001000, + RazorLibrary = 0x002000, + UwpLibrary = 0x004000, + WpfLibrary = 0x008000, // Modules - AzureIotEdgeModule = 0x008000, + AzureIotEdgeModule = 0x010000, // Extensions - VisualStudioExtension = 0x010000, + VisualStudioExtension = 0x020000, // Services - WebApi = 0x020000, - WorkerService = 0x040000, + WebApi = 0x040000, + WorkerService = 0x080000, // Tests - BUnitTest = 0x080000, - MsTest = 0x100000, - NUnitTest = 0x200000, - XUnitTest = 0x400000, + BUnitTest = 0x100000, + MsTest = 0x200000, + NUnitTest = 0x400000, + XUnitTest = 0x800000, // Combined - Apps = AzureFunctionApp | AndroidApp | ConsoleApp | CliApp | BlazorServerApp | BlazorWAsmApp | IosApp | UwpApp | WebApp | WpfApp | WinFormApp, + Apps = AzureFunctionApp | AndroidApp | ConsoleApp | CliApp | BlazorServerApp | BlazorWAsmApp | MauiApp | IosApp | UwpApp | WebApp | WpfApp | WinFormApp, Modules = AzureIotEdgeModule, Libraries = Library | RazorLibrary | UwpLibrary | WpfLibrary, Services = WorkerService | WebApi, From 3087741a8c744e0c232a7ad860c4024274bf68ee Mon Sep 17 00:00:00 2001 From: David Kallesen Date: Sat, 30 Mar 2024 00:37:49 +0100 Subject: [PATCH 2/2] feat: Add support for MauiApp in DotnetCsProjFileHelper and add metode FindAllInPathAndPredictProjectTypes --- docs/CodeDoc/Atc.DotNet/Atc.DotNet.md | 49 ++++++----- docs/CodeDoc/Atc.DotNet/IndexExtended.md | 1 + src/Atc.DotNet/DotnetCsProjFileHelper.cs | 88 +++++++++++++++++-- .../DotnetCsProjFileHelperTests.cs | 45 ++++++++++ 4 files changed, 155 insertions(+), 28 deletions(-) diff --git a/docs/CodeDoc/Atc.DotNet/Atc.DotNet.md b/docs/CodeDoc/Atc.DotNet/Atc.DotNet.md index 91224f87..e894ee11 100644 --- a/docs/CodeDoc/Atc.DotNet/Atc.DotNet.md +++ b/docs/CodeDoc/Atc.DotNet/Atc.DotNet.md @@ -47,6 +47,10 @@ >```csharp >Collection FindAllInPath(DirectoryInfo directoryInfo, SearchOption searchOption = AllDirectories) >``` +#### FindAllInPathAndPredictProjectTypes +>```csharp +>Collection> FindAllInPathAndPredictProjectTypes(DirectoryInfo directoryInfo, SearchOption searchOption = AllDirectories) +>``` #### GetProjectType >```csharp >DotnetProjectType GetProjectType(FileInfo fileInfo) @@ -156,28 +160,29 @@ | 8 | CliApp | Cli App | | | 16 | BlazorServerApp | Blazor Server App | | | 32 | BlazorWAsmApp | Blazor WAsm App | | -| 64 | IosApp | Ios App | | -| 128 | UwpApp | Uwp App | | -| 256 | WebApp | Web App | | -| 512 | WpfApp | Wpf App | | -| 1024 | WinFormApp | Win Form App | | -| 2047 | Apps | Apps | | -| 2048 | Library | Library | | -| 4096 | RazorLibrary | Razor Library | | -| 8192 | UwpLibrary | Uwp Library | | -| 16384 | WpfLibrary | Wpf Library | | -| 30720 | Libraries | Libraries | | -| 32768 | Modules | Azure Iot Edge Module | | -| 32768 | AzureIotEdgeModule | Azure Iot Edge Module | | -| 65536 | VisualStudioExtension | Visual Studio Extension | | -| 131072 | WebApi | Web Api | | -| 262144 | WorkerService | Worker Service | | -| 393216 | Services | Services | | -| 524288 | BUnitTest | BUnit Test | | -| 1048576 | MsTest | Ms Test | | -| 2097152 | NUnitTest | NUnit Test | | -| 4194304 | XUnitTest | XUnit Test | | -| 7864320 | Tests | Tests | | +| 64 | MauiApp | Maui App | | +| 128 | IosApp | Ios App | | +| 256 | UwpApp | Uwp App | | +| 512 | WebApp | Web App | | +| 1024 | WpfApp | Wpf App | | +| 2048 | WinFormApp | Win Form App | | +| 4095 | Apps | Apps | | +| 4096 | Library | Library | | +| 8192 | RazorLibrary | Razor Library | | +| 16384 | UwpLibrary | Uwp Library | | +| 32768 | WpfLibrary | Wpf Library | | +| 61440 | Libraries | Libraries | | +| 65536 | Modules | Azure Iot Edge Module | | +| 65536 | AzureIotEdgeModule | Azure Iot Edge Module | | +| 131072 | VisualStudioExtension | Visual Studio Extension | | +| 262144 | WebApi | Web Api | | +| 524288 | WorkerService | Worker Service | | +| 786432 | Services | Services | | +| 1048576 | BUnitTest | BUnit Test | | +| 2097152 | MsTest | Ms Test | | +| 4194304 | NUnitTest | NUnit Test | | +| 8388608 | XUnitTest | XUnit Test | | +| 15728640 | Tests | Tests | | diff --git a/docs/CodeDoc/Atc.DotNet/IndexExtended.md b/docs/CodeDoc/Atc.DotNet/IndexExtended.md index 340ba01d..cf329cf9 100644 --- a/docs/CodeDoc/Atc.DotNet/IndexExtended.md +++ b/docs/CodeDoc/Atc.DotNet/IndexExtended.md @@ -14,6 +14,7 @@ - [DotnetCsProjFileHelper](Atc.DotNet.md#dotnetcsprojfilehelper) - Static Methods - FindAllInPath(DirectoryInfo directoryInfo, SearchOption searchOption = AllDirectories) + - FindAllInPathAndPredictProjectTypes(DirectoryInfo directoryInfo, SearchOption searchOption = AllDirectories) - GetProjectType(FileInfo fileInfo) - GetProjectType(string fileContent) - PredictProjectType(FileInfo fileInfo) diff --git a/src/Atc.DotNet/DotnetCsProjFileHelper.cs b/src/Atc.DotNet/DotnetCsProjFileHelper.cs index 12bb48e5..ce90227d 100644 --- a/src/Atc.DotNet/DotnetCsProjFileHelper.cs +++ b/src/Atc.DotNet/DotnetCsProjFileHelper.cs @@ -1,6 +1,7 @@ // ReSharper disable ConvertIfStatementToReturnStatement // ReSharper disable ConvertIfStatementToSwitchStatement // ReSharper disable InvertIf +// ReSharper disable LoopCanBeConvertedToQuery // ReSharper disable StringLiteralTypo // ReSharper disable SuggestBaseTypeForParameter namespace Atc.DotNet; @@ -17,10 +18,38 @@ public static Collection FindAllInPath( } var result = new Collection(); - var files = Directory.GetFiles(directoryInfo.FullName, "*.csproj", searchOption); - foreach (var file in files) + + var csprojFiles = Directory + .GetFiles(directoryInfo.FullName, "*.csproj", searchOption) + .Select(x => new FileInfo(x)); + + foreach (var file in csprojFiles) { - result.Add(new FileInfo(file)); + result.Add(file); + } + + return result; + } + + public static Collection<(FileInfo CsProjFile, DotnetProjectType ProjectType)> FindAllInPathAndPredictProjectTypes( + DirectoryInfo directoryInfo, + SearchOption searchOption = SearchOption.AllDirectories) + { + if (directoryInfo is null) + { + throw new ArgumentNullException(nameof(directoryInfo)); + } + + var result = new Collection<(FileInfo, DotnetProjectType)>(); + + var csprojFiles = Directory + .GetFiles(directoryInfo.FullName, "*.csproj", searchOption) + .Select(x => new FileInfo(x)); + + foreach (var file in csprojFiles) + { + var predictProjectType = PredictProjectType(file); + result.Add((file, predictProjectType)); } return result; @@ -74,6 +103,7 @@ public static DotnetProjectType GetProjectType( return GetProjectType(fileContent); } + [SuppressMessage("Performance", "MA0031:Optimize Enumerable.Count() usage", Justification = "OK.")] public static DotnetProjectType GetProjectType( string fileContent) { @@ -82,6 +112,11 @@ public static DotnetProjectType GetProjectType( throw new ArgumentNullException(nameof(fileContent)); } + if (fileContent.Contains("WebAssembly", StringComparison.Ordinal)) + { + return DotnetProjectType.BlazorWAsmApp; + } + try { var rootElement = XElement.Parse(fileContent); @@ -150,7 +185,8 @@ private static DotnetProjectType ProjectElementForSdk( return DotnetProjectType.None; } - if (HasPackageReference(rootElement, "Microsoft.Azure.Devices.Client")) + if (IsProjectCapabilityAzureIoTEdgeModule(rootElement) || + HasPackageReference(rootElement, "Microsoft.Azure.Devices.Client")) { return DotnetProjectType.AzureIotEdgeModule; } @@ -167,6 +203,11 @@ private static DotnetProjectType ProjectElementForSdk( : DotnetProjectType.Library; } + if (IsMaui(rootElement)) + { + return DotnetProjectType.MauiApp; + } + if (IsWpf(rootElement)) { return IsOutputType(rootElement, "WinExe") @@ -388,6 +429,19 @@ private static bool IsWinForms( element.Value.IsTrue(); } + private static bool IsMaui( + XElement rootElement) + { + var element = rootElement + .Elements() + .Where(x => x.Name.LocalName == "PropertyGroup") + .Descendants() + .FirstOrDefault(x => x.Name.LocalName == "UseMaui"); + + return element is not null && + element.Value.IsTrue(); + } + private static bool IsWpf( XElement rootElement) { @@ -401,9 +455,31 @@ private static bool IsWpf( element.Value.IsTrue(); } + private static bool IsProjectCapabilityAzureIoTEdgeModule( + XElement rootElement) + { + var elements = rootElement + .Elements() + .Where(x => x.Name.LocalName == "ItemGroup") + .Descendants() + .Where(x => x.Name.LocalName == "ProjectCapability"); + + foreach (var element in elements) + { + var attribute = element.Attribute("Include"); + if (attribute is not null && + attribute.Value == "AzureIoTEdgeModule") + { + return true; + } + } + + return false; + } + private static bool IsOutputType( - XElement rootElement, - string value) + XElement rootElement, + string value) { var element = rootElement .Elements() diff --git a/test/Atc.DotNet.Tests/DotnetCsProjFileHelperTests.cs b/test/Atc.DotNet.Tests/DotnetCsProjFileHelperTests.cs index 595169c9..d9e1fcac 100644 --- a/test/Atc.DotNet.Tests/DotnetCsProjFileHelperTests.cs +++ b/test/Atc.DotNet.Tests/DotnetCsProjFileHelperTests.cs @@ -36,6 +36,7 @@ public Task DisposeAsync() [InlineData(DotnetProjectType.CliApp, DotnetProjectType.CliApp)] [InlineData(DotnetProjectType.BlazorServerApp, DotnetProjectType.BlazorServerApp)] [InlineData(DotnetProjectType.BlazorWAsmApp, DotnetProjectType.BlazorWAsmApp)] + [InlineData(DotnetProjectType.MauiApp, DotnetProjectType.MauiApp)] [InlineData(DotnetProjectType.IosApp, DotnetProjectType.IosApp)] [InlineData(DotnetProjectType.UwpApp, DotnetProjectType.UwpApp)] [InlineData(DotnetProjectType.WebApp, DotnetProjectType.WebApp)] @@ -80,6 +81,7 @@ public async Task PredictProjectType_FileInfo( [InlineData(DotnetProjectType.CliApp, DotnetProjectType.CliApp)] [InlineData(DotnetProjectType.WebApp, DotnetProjectType.BlazorServerApp)] [InlineData(DotnetProjectType.BlazorWAsmApp, DotnetProjectType.BlazorWAsmApp)] + [InlineData(DotnetProjectType.MauiApp, DotnetProjectType.MauiApp)] [InlineData(DotnetProjectType.IosApp, DotnetProjectType.IosApp)] [InlineData(DotnetProjectType.UwpApp, DotnetProjectType.UwpApp)] [InlineData(DotnetProjectType.WebApp, DotnetProjectType.WebApp)] @@ -119,6 +121,7 @@ public async Task GetProjectType_FileInfo( [InlineData(DotnetProjectType.CliApp, DotnetProjectType.CliApp)] [InlineData(DotnetProjectType.WebApp, DotnetProjectType.BlazorServerApp)] [InlineData(DotnetProjectType.BlazorWAsmApp, DotnetProjectType.BlazorWAsmApp)] + [InlineData(DotnetProjectType.MauiApp, DotnetProjectType.MauiApp)] [InlineData(DotnetProjectType.IosApp, DotnetProjectType.IosApp)] [InlineData(DotnetProjectType.UwpApp, DotnetProjectType.UwpApp)] [InlineData(DotnetProjectType.WebApp, DotnetProjectType.WebApp)] @@ -187,6 +190,9 @@ private static string CreateCsProjFile( case DotnetProjectType.BlazorWAsmApp: CreateCsProjFileBlazorWAsmApp(sb); break; + case DotnetProjectType.MauiApp: + CreateCsProjFileMauiApp(sb); + break; case DotnetProjectType.IosApp: CreateCsProjFileIosApp(sb); break; @@ -254,6 +260,7 @@ private static void CreateCsProjFileAzureIotEdgeModule( outputType: "Exe", packAsTool: false, useAzureFunction: false, + useMaui: false, useWinForm: false, useWpf: false); AppendItemGroupPackageReference( @@ -272,6 +279,7 @@ private static void CreateCsProjFileAzureFunctionApp( outputType: "Library", packAsTool: false, useAzureFunction: true, + useMaui: false, useWinForm: false, useWpf: false); sb.AppendLine(); @@ -301,6 +309,7 @@ private static void CreateCsProjFileCliApp( outputType: "Exe", packAsTool: true, useAzureFunction: false, + useMaui: false, useWinForm: false, useWpf: false); sb.AppendLine(); @@ -316,6 +325,7 @@ private static void CreateCsProjFileConsoleApp( outputType: "Exe", packAsTool: false, useAzureFunction: false, + useMaui: false, useWinForm: false, useWpf: false); sb.AppendLine(); @@ -331,6 +341,7 @@ private static void CreateCsProjFileBlazorServerApp( outputType: null, packAsTool: false, useAzureFunction: false, + useMaui: false, useWinForm: false, useWpf: false); sb.AppendLine(); @@ -346,6 +357,7 @@ private static void CreateCsProjFileBlazorWAsmApp( outputType: null, packAsTool: false, useAzureFunction: false, + useMaui: false, useWinForm: false, useWpf: false); sb.AppendLine(); @@ -366,6 +378,22 @@ private static void CreateCsProjFileIosApp( sb.AppendLine(""); } + private static void CreateCsProjFileMauiApp( + StringBuilder sb) + { + sb.AppendLine(""); + AppendPropertyGroupFirst( + sb, + outputType: "Exe", + packAsTool: false, + useAzureFunction: false, + useMaui: true, + useWinForm: false, + useWpf: false); + sb.AppendLine(); + sb.AppendLine(""); + } + private static void CreateCsProjFileLibrary( StringBuilder sb) { @@ -375,6 +403,7 @@ private static void CreateCsProjFileLibrary( outputType: "Library", packAsTool: false, useAzureFunction: false, + useMaui: false, useWinForm: false, useWpf: false); sb.AppendLine(); @@ -390,6 +419,7 @@ private static void CreateCsProjFileRazorLibrary( outputType: null, packAsTool: false, useAzureFunction: false, + useMaui: false, useWinForm: false, useWpf: false); sb.AppendLine(); @@ -432,6 +462,7 @@ private static void CreateCsProjFileTest( outputType: null, packAsTool: false, useAzureFunction: false, + useMaui: false, useWinForm: false, useWpf: false); AppendItemGroupPackageReference( @@ -466,6 +497,7 @@ private static void CreateCsProjFileWebApi( outputType: null, packAsTool: false, useAzureFunction: false, + useMaui: false, useWinForm: false, useWpf: false); AppendItemGroupPackageReference( @@ -484,6 +516,7 @@ private static void CreateCsProjFileWebApp( outputType: null, packAsTool: false, useAzureFunction: false, + useMaui: false, useWinForm: false, useWpf: false); sb.AppendLine(); @@ -499,6 +532,7 @@ private static void CreateCsProjFileWorkerService( outputType: null, packAsTool: false, useAzureFunction: false, + useMaui: false, useWinForm: false, useWpf: false); sb.AppendLine(); @@ -514,6 +548,7 @@ private static void CreateCsProjFileWinFormApp( outputType: "WinExe", packAsTool: false, useAzureFunction: false, + useMaui: false, useWinForm: true, useWpf: false); sb.AppendLine(); @@ -529,6 +564,7 @@ private static void CreateCsProjFileWpfApp( outputType: "WinExe", packAsTool: false, useAzureFunction: false, + useMaui: false, useWinForm: false, useWpf: true); sb.AppendLine(); @@ -544,6 +580,7 @@ private static void CreateCsProjFileWpfLibrary( outputType: null, packAsTool: false, useAzureFunction: false, + useMaui: false, useWinForm: false, useWpf: true); sb.AppendLine(); @@ -587,6 +624,8 @@ private static string CreateProgramCsFile( break; case DotnetProjectType.WebApp: break; + case DotnetProjectType.MauiApp: + break; case DotnetProjectType.WpfApp: break; case DotnetProjectType.WinFormApp: @@ -653,6 +692,7 @@ private static void AppendPropertyGroupFirst( string? outputType, bool packAsTool, bool useAzureFunction, + bool useMaui, bool useWinForm, bool useWpf) { @@ -675,6 +715,11 @@ private static void AppendPropertyGroupFirst( sb.AppendLine("v4"); } + if (useMaui) + { + sb.AppendLine("true"); + } + if (useWinForm) { sb.AppendLine("true");