From 0aa76719eb2bb5b74bcc311b416baef182a7279e Mon Sep 17 00:00:00 2001 From: Jose Perez Rodriguez Date: Wed, 11 Sep 2024 16:53:37 -0700 Subject: [PATCH 1/9] Fix RID regression by adding a task that calculates the best matching RID for each platform. --- Aspire.sln | 7 ++ Directory.Build.targets | 1 + Directory.Packages.props | 8 ++ eng/BuildTask.Packages.props | 26 +++++ eng/BuildTask.targets | 100 ++++++++++++++++++ eng/dashboardpack/Sdk.in.targets | 4 +- .../Aspire.Hosting.Orchestration.in.targets | 2 +- .../Aspire.Hosting.Sdk.csproj | 21 +++- .../FindBestRidForPlatform.cs | 42 ++++++++ src/Aspire.Hosting.Sdk/NuGetUtils.cs | 50 +++++++++ src/Aspire.Hosting.Sdk/SDK/Sdk.in.targets | 35 +++++- .../Aspire.Hosting.Sdk.Tests.csproj | 19 ++++ .../NuGetUtils.Tests.cs | 37 +++++++ 13 files changed, 345 insertions(+), 7 deletions(-) create mode 100644 eng/BuildTask.Packages.props create mode 100644 eng/BuildTask.targets create mode 100644 src/Aspire.Hosting.Sdk/FindBestRidForPlatform.cs create mode 100644 src/Aspire.Hosting.Sdk/NuGetUtils.cs create mode 100644 tests/Aspire.Hosting.Sdk.Tests/Aspire.Hosting.Sdk.Tests.csproj create mode 100644 tests/Aspire.Hosting.Sdk.Tests/NuGetUtils.Tests.cs diff --git a/Aspire.sln b/Aspire.sln index ad1e0dd2696..419aea051f8 100644 --- a/Aspire.sln +++ b/Aspire.sln @@ -583,6 +583,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Aspire.Hosting.Dapr.Tests", EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Aspire.Hosting.AWS.Tests", "tests\Aspire.Hosting.AWS.Tests\Aspire.Hosting.AWS.Tests.csproj", "{6F71BC73-B703-4E64-98E0-801781302E7A}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Aspire.Hosting.Sdk.Tests", "tests\Aspire.Hosting.Sdk.Tests\Aspire.Hosting.Sdk.Tests.csproj", "{ABDC7DF8-7ACA-430C-9C91-983693DBBCB9}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -1537,6 +1539,10 @@ Global {6F71BC73-B703-4E64-98E0-801781302E7A}.Debug|Any CPU.Build.0 = Debug|Any CPU {6F71BC73-B703-4E64-98E0-801781302E7A}.Release|Any CPU.ActiveCfg = Release|Any CPU {6F71BC73-B703-4E64-98E0-801781302E7A}.Release|Any CPU.Build.0 = Release|Any CPU + {ABDC7DF8-7ACA-430C-9C91-983693DBBCB9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {ABDC7DF8-7ACA-430C-9C91-983693DBBCB9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {ABDC7DF8-7ACA-430C-9C91-983693DBBCB9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {ABDC7DF8-7ACA-430C-9C91-983693DBBCB9}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -1818,6 +1824,7 @@ Global {091EA540-355B-4763-9980-5F83F0BB6F11} = {15966C27-17FA-4A46-A172-55985411540A} {C60C5CFA-5B6D-4432-BFCD-54D1BEEC7DBE} = {830A89EC-4029-4753-B25A-068BAE37DEC7} {6F71BC73-B703-4E64-98E0-801781302E7A} = {830A89EC-4029-4753-B25A-068BAE37DEC7} + {ABDC7DF8-7ACA-430C-9C91-983693DBBCB9} = {4981B3A5-4AFD-4191-BF7D-8692D9783D60} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {6DCEDFEC-988E-4CB3-B45B-191EB5086E0C} diff --git a/Directory.Build.targets b/Directory.Build.targets index 97c52f795e2..a6adea8433f 100644 --- a/Directory.Build.targets +++ b/Directory.Build.targets @@ -24,4 +24,5 @@ + diff --git a/Directory.Packages.props b/Directory.Packages.props index b8d53a4d66e..1e1e8fa30aa 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -92,6 +92,14 @@ + + + + + + + + diff --git a/eng/BuildTask.Packages.props b/eng/BuildTask.Packages.props new file mode 100644 index 00000000000..d51b0f371f2 --- /dev/null +++ b/eng/BuildTask.Packages.props @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/eng/BuildTask.targets b/eng/BuildTask.targets new file mode 100644 index 00000000000..468b751ecf4 --- /dev/null +++ b/eng/BuildTask.targets @@ -0,0 +1,100 @@ + + + + + + false + true + + true + + true + tools + true + $(TargetsForTfmSpecificContentInPackage);_AddBuildOutputToPackageCore;_AddBuildOutputToPackageDesktop + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + runtime + + + + + + + + + + $(TargetFramework) + + + + + + + + + + $(TargetFramework) + + + + + + + \ No newline at end of file diff --git a/eng/dashboardpack/Sdk.in.targets b/eng/dashboardpack/Sdk.in.targets index 4af9f8fb1ce..f903ca475d9 100644 --- a/eng/dashboardpack/Sdk.in.targets +++ b/eng/dashboardpack/Sdk.in.targets @@ -2,7 +2,7 @@ - + $([MSBuild]::NormalizeDirectory($(MSBuildThisFileDirectory), '..', 'tools')) $([MSBuild]::EnsureTrailingSlash('$(AspireDashboardDir)')) $([MSBuild]::NormalizePath($(AspireDashboardDir), 'Aspire.Dashboard')) @@ -10,7 +10,7 @@ $(AspireDashboardPath).dll - + diff --git a/eng/dcppack/Aspire.Hosting.Orchestration.in.targets b/eng/dcppack/Aspire.Hosting.Orchestration.in.targets index 23524cc8d5c..ad698ca042d 100644 --- a/eng/dcppack/Aspire.Hosting.Orchestration.in.targets +++ b/eng/dcppack/Aspire.Hosting.Orchestration.in.targets @@ -1,6 +1,6 @@ - + $([MSBuild]::NormalizeDirectory($(MSBuildThisFileDirectory), '..', 'tools')) $([MSBuild]::EnsureTrailingSlash('$(DcpDir)')) $([MSBuild]::NormalizeDirectory($(DcpDir), 'ext')) diff --git a/src/Aspire.Hosting.Sdk/Aspire.Hosting.Sdk.csproj b/src/Aspire.Hosting.Sdk/Aspire.Hosting.Sdk.csproj index f785b101c2d..f910ce98f58 100644 --- a/src/Aspire.Hosting.Sdk/Aspire.Hosting.Sdk.csproj +++ b/src/Aspire.Hosting.Sdk/Aspire.Hosting.Sdk.csproj @@ -1,10 +1,19 @@ - + + $(DefaultTargetFramework);$(NetFrameworkToolCurrent); aspire hosting sdk .NET Aspire Hosting SDK. Enabled via <IsAspireHost>true</IsAspireHost>. + false + + $(NoWarn);CS1591;CS8002 + true + true @@ -18,4 +27,14 @@ + + + + + + + + + + diff --git a/src/Aspire.Hosting.Sdk/FindBestRidForPlatform.cs b/src/Aspire.Hosting.Sdk/FindBestRidForPlatform.cs new file mode 100644 index 00000000000..7d555fa1f97 --- /dev/null +++ b/src/Aspire.Hosting.Sdk/FindBestRidForPlatform.cs @@ -0,0 +1,42 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Microsoft.Build.Framework; +using NuGet.RuntimeModel; +using Task = Microsoft.Build.Utilities.Task; + +namespace Aspire.Hosting.Sdk; +#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. +public class FindBestRidForPlatform : Task +{ + [Required] + public string RuntimeGraphPath { get; set; } + + [Required] + public ITaskItem[] SupportedRids { get; set; } + + [Required] + public string NETCoreSdkRuntimeIdentifier { get; set; } + + [Output] + public string? BestRidForPlatform { get; set; } + + public override bool Execute() + { + var supportedRids = SupportedRids + .Select(item => item.ItemSpec); + + RuntimeGraph graph = JsonRuntimeFormat.ReadRuntimeGraph(RuntimeGraphPath); + + BestRidForPlatform = NuGetUtils.GetBestMatchingRid(graph, NETCoreSdkRuntimeIdentifier, supportedRids, out bool wasInGraph); + + if (!wasInGraph) + { + base.Log.LogError("Rid {0} was not found in the runtime graph.", NETCoreSdkRuntimeIdentifier); + return false; + } + + return true; + } +} +#pragma warning restore CS8618 diff --git a/src/Aspire.Hosting.Sdk/NuGetUtils.cs b/src/Aspire.Hosting.Sdk/NuGetUtils.cs new file mode 100644 index 00000000000..b00c7c9b08c --- /dev/null +++ b/src/Aspire.Hosting.Sdk/NuGetUtils.cs @@ -0,0 +1,50 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using NuGet.RuntimeModel; + +namespace Aspire.Hosting.Sdk; + +/* + * These utility methods were copied from the sdk repository to mimic the behavior used when selecting the best matching RID + * for a a given runtime identifier. For more information, please see the original source code at: + * https://github.com/dotnet/sdk/blob/e6da8ca6de3ec8f392dc87b8529415e1ef59b7ea/src/Tasks/Microsoft.NET.Build.Tasks/NuGetUtils.NuGet.cs#L76-L109 + */ + +internal static class NuGetUtils +{ + public static string? GetBestMatchingRid(RuntimeGraph runtimeGraph, string runtimeIdentifier, + IEnumerable availableRuntimeIdentifiers, out bool wasInGraph) + { + return GetBestMatchingRidWithExclusion(runtimeGraph, runtimeIdentifier, + runtimeIdentifiersToExclude: null, + availableRuntimeIdentifiers, out wasInGraph); + } + + public static string? GetBestMatchingRidWithExclusion(RuntimeGraph runtimeGraph, string runtimeIdentifier, + IEnumerable? runtimeIdentifiersToExclude, + IEnumerable availableRuntimeIdentifiers, out bool wasInGraph) + { + wasInGraph = runtimeGraph.Runtimes.ContainsKey(runtimeIdentifier); + + string? bestMatch = null; + + HashSet availableRids = new(availableRuntimeIdentifiers, StringComparer.Ordinal); + HashSet? excludedRids = runtimeIdentifiersToExclude switch { null => null, _ => new HashSet(runtimeIdentifiersToExclude, StringComparer.Ordinal) }; + foreach (var candidateRuntimeIdentifier in runtimeGraph.ExpandRuntime(runtimeIdentifier)) + { + if (bestMatch == null && availableRids.Contains(candidateRuntimeIdentifier)) + { + bestMatch = candidateRuntimeIdentifier; + } + + if (excludedRids != null && excludedRids.Contains(candidateRuntimeIdentifier)) + { + // Don't treat this as a match + return null; + } + } + + return bestMatch; + } +} diff --git a/src/Aspire.Hosting.Sdk/SDK/Sdk.in.targets b/src/Aspire.Hosting.Sdk/SDK/Sdk.in.targets index 3987bf67320..c13acf541b0 100644 --- a/src/Aspire.Hosting.Sdk/SDK/Sdk.in.targets +++ b/src/Aspire.Hosting.Sdk/SDK/Sdk.in.targets @@ -43,6 +43,16 @@ + + $(MSBuildThisFileDirectory)..\tools\ + net8.0 + net472 + $(AspireHostingTasksRoot)$(AspireHostingTasksTFM)\ + $(AspireHostingTasksDirectory)Aspire.Hosting.Sdk.dll + + + + + + <_DashboardAndDCPSupportedTargetingRIDs Include="win-x64" /> + <_DashboardAndDCPSupportedTargetingRIDs Include="win-x86" /> + <_DashboardAndDCPSupportedTargetingRIDs Include="win-arm64" /> + <_DashboardAndDCPSupportedTargetingRIDs Include="linux-x64" /> + <_DashboardAndDCPSupportedTargetingRIDs Include="linux-arm64" /> + <_DashboardAndDCPSupportedTargetingRIDs Include="osx-x64" /> + <_DashboardAndDCPSupportedTargetingRIDs Include="osx-arm64" /> + + + + + + + + - - + + - \ No newline at end of file + diff --git a/tests/Aspire.Hosting.Sdk.Tests/Aspire.Hosting.Sdk.Tests.csproj b/tests/Aspire.Hosting.Sdk.Tests/Aspire.Hosting.Sdk.Tests.csproj new file mode 100644 index 00000000000..3c7f3cd928e --- /dev/null +++ b/tests/Aspire.Hosting.Sdk.Tests/Aspire.Hosting.Sdk.Tests.csproj @@ -0,0 +1,19 @@ + + + + $(DefaultTargetFramework) + + + + + + + + + + + + + + + diff --git a/tests/Aspire.Hosting.Sdk.Tests/NuGetUtils.Tests.cs b/tests/Aspire.Hosting.Sdk.Tests/NuGetUtils.Tests.cs new file mode 100644 index 00000000000..46ba5483885 --- /dev/null +++ b/tests/Aspire.Hosting.Sdk.Tests/NuGetUtils.Tests.cs @@ -0,0 +1,37 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using NuGet.RuntimeModel; +using Xunit; + +namespace Aspire.Hosting.Sdk.Tests; + +public class NuGetUtilsTests +{ + [Theory] + // Matching RID cases + [InlineData("win-x64", "win-x64")] + [InlineData("win-x86", "win-x86")] + [InlineData("win-arm64", "win-arm64")] + [InlineData("linux-x64", "linux-x64")] + [InlineData("linux-arm64", "linux-arm64")] + [InlineData("osx-x64", "osx-x64")] + [InlineData("osx-arm64", "osx-arm64")] + + //Compatible RID cases + [InlineData("rhel.8-x64", "linux-x64")] // https://github.com/dotnet/aspire/issues/5486 + [InlineData("ubuntu.23.04-x64", "linux-x64")] + [InlineData("fedora.39-x64", "linux-x64")] + [InlineData("linux-musl-x64", "linux-x64")] + public void RightRIDIsSelected(string inputRID, string expectedRID) + { + RuntimeGraph graph = JsonRuntimeFormat.ReadRuntimeGraph("RuntimeIdentifierGraph.json"); + + var result = NuGetUtils.GetBestMatchingRid(graph, inputRID, new[] { "win-x64", "win-arm64", "win-x86", + "linux-x64", "linux-arm64", + "osx-x64", "osx-arm64"}, out bool wasInGraph); + + Assert.Equal(expectedRID, result); + Assert.True(wasInGraph); + } +} From 2715e03207f832aa9c1ae472d544057809b5e6b2 Mon Sep 17 00:00:00 2001 From: Jose Perez Rodriguez Date: Tue, 17 Sep 2024 13:41:53 -0700 Subject: [PATCH 2/9] Use out-of-proc instead of MSBuild task --- Aspire.sln | 7 ++ Directory.Build.targets | 1 - Directory.Packages.props | 6 -- eng/BuildTask.Packages.props | 26 ----- eng/BuildTask.targets | 100 ------------------ .../Aspire.Hosting.Sdk.csproj | 47 ++++---- .../Aspire.RuntimeIdentifier.Tool.csproj | 16 +++ .../NuGetUtils.cs | 0 .../Aspire.RuntimeIdentifier.Tool/Program.cs | 88 +++++++++++++++ .../FindBestRidForPlatform.cs | 42 -------- src/Aspire.Hosting.Sdk/SDK/Sdk.in.targets | 47 +++++--- .../Aspire.Hosting.Sdk.Tests.csproj | 5 +- 12 files changed, 173 insertions(+), 212 deletions(-) delete mode 100644 eng/BuildTask.Packages.props delete mode 100644 eng/BuildTask.targets create mode 100644 src/Aspire.Hosting.Sdk/Aspire.RuntimeIdentifier.Tool/Aspire.RuntimeIdentifier.Tool.csproj rename src/Aspire.Hosting.Sdk/{ => Aspire.RuntimeIdentifier.Tool}/NuGetUtils.cs (100%) create mode 100644 src/Aspire.Hosting.Sdk/Aspire.RuntimeIdentifier.Tool/Program.cs delete mode 100644 src/Aspire.Hosting.Sdk/FindBestRidForPlatform.cs diff --git a/Aspire.sln b/Aspire.sln index 419aea051f8..fdd5827becf 100644 --- a/Aspire.sln +++ b/Aspire.sln @@ -585,6 +585,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Aspire.Hosting.AWS.Tests", EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Aspire.Hosting.Sdk.Tests", "tests\Aspire.Hosting.Sdk.Tests\Aspire.Hosting.Sdk.Tests.csproj", "{ABDC7DF8-7ACA-430C-9C91-983693DBBCB9}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Aspire.RuntimeIdentifier.Tool", "src\Aspire.Hosting.Sdk\Aspire.RuntimeIdentifier.Tool\Aspire.RuntimeIdentifier.Tool.csproj", "{100A7A22-2517-41AD-8649-68E3E289F537}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -1543,6 +1545,10 @@ Global {ABDC7DF8-7ACA-430C-9C91-983693DBBCB9}.Debug|Any CPU.Build.0 = Debug|Any CPU {ABDC7DF8-7ACA-430C-9C91-983693DBBCB9}.Release|Any CPU.ActiveCfg = Release|Any CPU {ABDC7DF8-7ACA-430C-9C91-983693DBBCB9}.Release|Any CPU.Build.0 = Release|Any CPU + {100A7A22-2517-41AD-8649-68E3E289F537}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {100A7A22-2517-41AD-8649-68E3E289F537}.Debug|Any CPU.Build.0 = Debug|Any CPU + {100A7A22-2517-41AD-8649-68E3E289F537}.Release|Any CPU.ActiveCfg = Release|Any CPU + {100A7A22-2517-41AD-8649-68E3E289F537}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -1825,6 +1831,7 @@ Global {C60C5CFA-5B6D-4432-BFCD-54D1BEEC7DBE} = {830A89EC-4029-4753-B25A-068BAE37DEC7} {6F71BC73-B703-4E64-98E0-801781302E7A} = {830A89EC-4029-4753-B25A-068BAE37DEC7} {ABDC7DF8-7ACA-430C-9C91-983693DBBCB9} = {4981B3A5-4AFD-4191-BF7D-8692D9783D60} + {100A7A22-2517-41AD-8649-68E3E289F537} = {F534D4F8-5E3A-42FC-BCD7-4C2D6060F9C8} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {6DCEDFEC-988E-4CB3-B45B-191EB5086E0C} diff --git a/Directory.Build.targets b/Directory.Build.targets index a6adea8433f..97c52f795e2 100644 --- a/Directory.Build.targets +++ b/Directory.Build.targets @@ -24,5 +24,4 @@ - diff --git a/Directory.Packages.props b/Directory.Packages.props index 1e1e8fa30aa..005f7f7f351 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -94,12 +94,6 @@ - - - - - - diff --git a/eng/BuildTask.Packages.props b/eng/BuildTask.Packages.props deleted file mode 100644 index d51b0f371f2..00000000000 --- a/eng/BuildTask.Packages.props +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/eng/BuildTask.targets b/eng/BuildTask.targets deleted file mode 100644 index 468b751ecf4..00000000000 --- a/eng/BuildTask.targets +++ /dev/null @@ -1,100 +0,0 @@ - - - - - - false - true - - true - - true - tools - true - $(TargetsForTfmSpecificContentInPackage);_AddBuildOutputToPackageCore;_AddBuildOutputToPackageDesktop - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - true - runtime - - - - - - - - - - $(TargetFramework) - - - - - - - - - - $(TargetFramework) - - - - - - - \ No newline at end of file diff --git a/src/Aspire.Hosting.Sdk/Aspire.Hosting.Sdk.csproj b/src/Aspire.Hosting.Sdk/Aspire.Hosting.Sdk.csproj index f910ce98f58..da68bf3582a 100644 --- a/src/Aspire.Hosting.Sdk/Aspire.Hosting.Sdk.csproj +++ b/src/Aspire.Hosting.Sdk/Aspire.Hosting.Sdk.csproj @@ -1,40 +1,49 @@ - + - $(DefaultTargetFramework);$(NetFrameworkToolCurrent); aspire hosting sdk .NET Aspire Hosting SDK. Enabled via <IsAspireHost>true</IsAspireHost>. - false - - $(NoWarn);CS1591;CS8002 - true - true + _PublishAndPackRIDTool;$(TargetsForTfmSpecificContentInPackage) 100 + + + + - - - - - - - - - + + + + + + + <_publishContentToPackage Include="$(DotNetOutputPath)Aspire.RuntimeIdentifier.Tool/$(Configuration)/$(DefaultTargetFramework)/publish/**/*" /> + + + + + + + + diff --git a/src/Aspire.Hosting.Sdk/Aspire.RuntimeIdentifier.Tool/Aspire.RuntimeIdentifier.Tool.csproj b/src/Aspire.Hosting.Sdk/Aspire.RuntimeIdentifier.Tool/Aspire.RuntimeIdentifier.Tool.csproj new file mode 100644 index 00000000000..c7aa6ce7ad4 --- /dev/null +++ b/src/Aspire.Hosting.Sdk/Aspire.RuntimeIdentifier.Tool/Aspire.RuntimeIdentifier.Tool.csproj @@ -0,0 +1,16 @@ + + + + Exe + $(DefaultTargetFramework) + Major + false + false + + + + + + + + diff --git a/src/Aspire.Hosting.Sdk/NuGetUtils.cs b/src/Aspire.Hosting.Sdk/Aspire.RuntimeIdentifier.Tool/NuGetUtils.cs similarity index 100% rename from src/Aspire.Hosting.Sdk/NuGetUtils.cs rename to src/Aspire.Hosting.Sdk/Aspire.RuntimeIdentifier.Tool/NuGetUtils.cs diff --git a/src/Aspire.Hosting.Sdk/Aspire.RuntimeIdentifier.Tool/Program.cs b/src/Aspire.Hosting.Sdk/Aspire.RuntimeIdentifier.Tool/Program.cs new file mode 100644 index 00000000000..0d773372eb5 --- /dev/null +++ b/src/Aspire.Hosting.Sdk/Aspire.RuntimeIdentifier.Tool/Program.cs @@ -0,0 +1,88 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.CommandLine; +using System.CommandLine.Parsing; +using System.Diagnostics; +using System.Reflection; +using Aspire.Hosting.Sdk; +using NuGet.RuntimeModel; + +namespace Aspire.RuntimeIdentifier.Tool; + +sealed class Program +{ + static int Main(string[] args) + { + CliRootCommand rootCommand = new("Aspire.RuntimeIdentifier.Tool v" + FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).ProductVersion) + { + TreatUnmatchedTokensAsErrors = true + }; + + CliOption runtimeGraphPathOption = new("--runtimeGraphPath", "-rgp") + { + Description = "Path to runtime graph path to use for RID mapping.", + Required = true + }; + + CliOption netcoreSdkRuntimeIdentifierOption = new("--netcoreSdkRuntimeIdentifier", "-r") + { + Description = "RID to use for finding the best applicable RID from mapping.", + Required = true + }; + + CliOption supportedRidsOption = new("--supportedRids", "-sr") + { + Description = "List of RIDs that are supported. Comma-separated.", + Required = true, + AllowMultipleArgumentsPerToken = true, + Arity = ArgumentArity.OneOrMore, + CustomParser = ParseSupportedRidsArgument + }; + + rootCommand.Options.Add(runtimeGraphPathOption); + rootCommand.Options.Add(netcoreSdkRuntimeIdentifierOption); + rootCommand.Options.Add(supportedRidsOption); + rootCommand.SetAction((ParseResult parseResult) => + { + string rgp = parseResult.GetValue(runtimeGraphPathOption) ?? throw new InvalidOperationException("The --runtimeGraphPath argument is required."); + + if (!File.Exists(rgp)) + { + throw new FileNotFoundException("File {0} does not exist. Please ensure the runtime graph path exists.", rgp); + } + + RuntimeGraph graph = JsonRuntimeFormat.ReadRuntimeGraph(rgp); + + var ridToUse = parseResult.GetValue(netcoreSdkRuntimeIdentifierOption); + + var supportedRids = parseResult.GetValue(supportedRidsOption); + + string? bestRidForPlatform = NuGetUtils.GetBestMatchingRid(graph, ridToUse!, supportedRids!, out bool wasInGraph); + + if (!wasInGraph) + { +#pragma warning disable CA2201 // Do not raise reserved exception types + throw new ApplicationException("Unable to find the best rid to use"); +#pragma warning restore CA2201 // Do not raise reserved exception types + } + + Console.WriteLine(bestRidForPlatform); + return 0; + }); + + return rootCommand.Parse(args).Invoke(); + } + + private static string[]? ParseSupportedRidsArgument(ArgumentResult result) + { + List args = new(); + + foreach (var token in result.Tokens) + { + args.AddRange(token.Value.Split(',')); + } + + return args.ToArray(); + } +} diff --git a/src/Aspire.Hosting.Sdk/FindBestRidForPlatform.cs b/src/Aspire.Hosting.Sdk/FindBestRidForPlatform.cs deleted file mode 100644 index 7d555fa1f97..00000000000 --- a/src/Aspire.Hosting.Sdk/FindBestRidForPlatform.cs +++ /dev/null @@ -1,42 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Microsoft.Build.Framework; -using NuGet.RuntimeModel; -using Task = Microsoft.Build.Utilities.Task; - -namespace Aspire.Hosting.Sdk; -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. -public class FindBestRidForPlatform : Task -{ - [Required] - public string RuntimeGraphPath { get; set; } - - [Required] - public ITaskItem[] SupportedRids { get; set; } - - [Required] - public string NETCoreSdkRuntimeIdentifier { get; set; } - - [Output] - public string? BestRidForPlatform { get; set; } - - public override bool Execute() - { - var supportedRids = SupportedRids - .Select(item => item.ItemSpec); - - RuntimeGraph graph = JsonRuntimeFormat.ReadRuntimeGraph(RuntimeGraphPath); - - BestRidForPlatform = NuGetUtils.GetBestMatchingRid(graph, NETCoreSdkRuntimeIdentifier, supportedRids, out bool wasInGraph); - - if (!wasInGraph) - { - base.Log.LogError("Rid {0} was not found in the runtime graph.", NETCoreSdkRuntimeIdentifier); - return false; - } - - return true; - } -} -#pragma warning restore CS8618 diff --git a/src/Aspire.Hosting.Sdk/SDK/Sdk.in.targets b/src/Aspire.Hosting.Sdk/SDK/Sdk.in.targets index c13acf541b0..0f27e91b2cf 100644 --- a/src/Aspire.Hosting.Sdk/SDK/Sdk.in.targets +++ b/src/Aspire.Hosting.Sdk/SDK/Sdk.in.targets @@ -44,15 +44,11 @@ - $(MSBuildThisFileDirectory)..\tools\ - net8.0 - net472 - $(AspireHostingTasksRoot)$(AspireHostingTasksTFM)\ - $(AspireHostingTasksDirectory)Aspire.Hosting.Sdk.dll + $(MSBuildThisFileDirectory)..\tools\@DefaultTargetFramework@\ + $([MSBuild]::NormalizePath('$(AspireRidToolRoot)\')) + $(AspireRidToolDirectory)Aspire.RuntimeIdentifier.Tool.dll - - - - - + + + <_DotNetHostPath>$(DOTNET_HOST_PATH) + + + + + <_DotNetHostDirectory>$(NetCoreRoot) + <_DotNetHostFileName>dotnet + <_DotNetHostFileName Condition="'$(OS)' == 'Windows_NT'">dotnet.exe + + <_DotNetHostPath>$(_DotNetHostDirectory)\$(_DotNetHostFileName) + + + + + + + + + + + + <_DashboardAndDcpRID>@(_AspireRidToolOutput) + @@ -119,4 +138,4 @@ - + \ No newline at end of file diff --git a/tests/Aspire.Hosting.Sdk.Tests/Aspire.Hosting.Sdk.Tests.csproj b/tests/Aspire.Hosting.Sdk.Tests/Aspire.Hosting.Sdk.Tests.csproj index 3c7f3cd928e..94cfa109cab 100644 --- a/tests/Aspire.Hosting.Sdk.Tests/Aspire.Hosting.Sdk.Tests.csproj +++ b/tests/Aspire.Hosting.Sdk.Tests/Aspire.Hosting.Sdk.Tests.csproj @@ -5,15 +5,12 @@ - + - - - From 1b7a0f897b1fa4ab9fa4a2e353ea12f8be7995eb Mon Sep 17 00:00:00 2001 From: Jose Perez Rodriguez Date: Tue, 17 Sep 2024 14:24:40 -0700 Subject: [PATCH 3/9] Do not show the output of running the tool as 'High' importance --- src/Aspire.Hosting.Sdk/SDK/Sdk.in.targets | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Aspire.Hosting.Sdk/SDK/Sdk.in.targets b/src/Aspire.Hosting.Sdk/SDK/Sdk.in.targets index 0f27e91b2cf..9d9e580d48b 100644 --- a/src/Aspire.Hosting.Sdk/SDK/Sdk.in.targets +++ b/src/Aspire.Hosting.Sdk/SDK/Sdk.in.targets @@ -119,6 +119,7 @@ From ba9764e370dc07125422c2e05e60939534e7fd1a Mon Sep 17 00:00:00 2001 From: Jose Perez Rodriguez Date: Tue, 17 Sep 2024 16:33:57 -0700 Subject: [PATCH 4/9] PR Feedback --- .../Aspire.RuntimeIdentifier.Tool/NuGetUtils.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Aspire.Hosting.Sdk/Aspire.RuntimeIdentifier.Tool/NuGetUtils.cs b/src/Aspire.Hosting.Sdk/Aspire.RuntimeIdentifier.Tool/NuGetUtils.cs index b00c7c9b08c..00b5782d461 100644 --- a/src/Aspire.Hosting.Sdk/Aspire.RuntimeIdentifier.Tool/NuGetUtils.cs +++ b/src/Aspire.Hosting.Sdk/Aspire.RuntimeIdentifier.Tool/NuGetUtils.cs @@ -7,7 +7,7 @@ namespace Aspire.Hosting.Sdk; /* * These utility methods were copied from the sdk repository to mimic the behavior used when selecting the best matching RID - * for a a given runtime identifier. For more information, please see the original source code at: + * for a given runtime identifier. For more information, please see the original source code at: * https://github.com/dotnet/sdk/blob/e6da8ca6de3ec8f392dc87b8529415e1ef59b7ea/src/Tasks/Microsoft.NET.Build.Tasks/NuGetUtils.NuGet.cs#L76-L109 */ From f2485fbbf56fec0dbde13182def3ba92f0877a82 Mon Sep 17 00:00:00 2001 From: Jose Perez Rodriguez Date: Thu, 19 Sep 2024 13:53:08 -0700 Subject: [PATCH 5/9] PR Feedback --- eng/dashboardpack/Common.projitems | 3 +-- eng/dashboardpack/{Sdk.in.targets => Sdk.targets} | 0 ....targets => Aspire.Hosting.Orchestration.targets} | 0 eng/dcppack/Common.projitems | 2 +- .../Aspire.RuntimeIdentifier.Tool.csproj | 1 + .../Aspire.RuntimeIdentifier.Tool/Program.cs | 12 +++++------- src/Aspire.Hosting.Sdk/SDK/Sdk.in.targets | 2 +- 7 files changed, 9 insertions(+), 11 deletions(-) rename eng/dashboardpack/{Sdk.in.targets => Sdk.targets} (100%) rename eng/dcppack/{Aspire.Hosting.Orchestration.in.targets => Aspire.Hosting.Orchestration.targets} (100%) diff --git a/eng/dashboardpack/Common.projitems b/eng/dashboardpack/Common.projitems index dcefee7e58e..92b712f853e 100644 --- a/eng/dashboardpack/Common.projitems +++ b/eng/dashboardpack/Common.projitems @@ -56,8 +56,7 @@ - + diff --git a/eng/dashboardpack/Sdk.in.targets b/eng/dashboardpack/Sdk.targets similarity index 100% rename from eng/dashboardpack/Sdk.in.targets rename to eng/dashboardpack/Sdk.targets diff --git a/eng/dcppack/Aspire.Hosting.Orchestration.in.targets b/eng/dcppack/Aspire.Hosting.Orchestration.targets similarity index 100% rename from eng/dcppack/Aspire.Hosting.Orchestration.in.targets rename to eng/dcppack/Aspire.Hosting.Orchestration.targets diff --git a/eng/dcppack/Common.projitems b/eng/dcppack/Common.projitems index 2aa23ec83d4..f7430e270b7 100644 --- a/eng/dcppack/Common.projitems +++ b/eng/dcppack/Common.projitems @@ -75,7 +75,7 @@ - + diff --git a/src/Aspire.Hosting.Sdk/Aspire.RuntimeIdentifier.Tool/Aspire.RuntimeIdentifier.Tool.csproj b/src/Aspire.Hosting.Sdk/Aspire.RuntimeIdentifier.Tool/Aspire.RuntimeIdentifier.Tool.csproj index c7aa6ce7ad4..2a2402c0beb 100644 --- a/src/Aspire.Hosting.Sdk/Aspire.RuntimeIdentifier.Tool/Aspire.RuntimeIdentifier.Tool.csproj +++ b/src/Aspire.Hosting.Sdk/Aspire.RuntimeIdentifier.Tool/Aspire.RuntimeIdentifier.Tool.csproj @@ -6,6 +6,7 @@ Major false false + false diff --git a/src/Aspire.Hosting.Sdk/Aspire.RuntimeIdentifier.Tool/Program.cs b/src/Aspire.Hosting.Sdk/Aspire.RuntimeIdentifier.Tool/Program.cs index 0d773372eb5..55a983c9ec8 100644 --- a/src/Aspire.Hosting.Sdk/Aspire.RuntimeIdentifier.Tool/Program.cs +++ b/src/Aspire.Hosting.Sdk/Aspire.RuntimeIdentifier.Tool/Program.cs @@ -19,23 +19,22 @@ static int Main(string[] args) TreatUnmatchedTokensAsErrors = true }; - CliOption runtimeGraphPathOption = new("--runtimeGraphPath", "-rgp") + CliOption runtimeGraphPathOption = new("--runtimeGraphPath") { Description = "Path to runtime graph path to use for RID mapping.", Required = true }; - CliOption netcoreSdkRuntimeIdentifierOption = new("--netcoreSdkRuntimeIdentifier", "-r") + CliOption netcoreSdkRuntimeIdentifierOption = new("--netcoreSdkRuntimeIdentifier") { Description = "RID to use for finding the best applicable RID from mapping.", Required = true }; - CliOption supportedRidsOption = new("--supportedRids", "-sr") + CliOption supportedRidsOption = new("--supportedRids") { Description = "List of RIDs that are supported. Comma-separated.", Required = true, - AllowMultipleArgumentsPerToken = true, Arity = ArgumentArity.OneOrMore, CustomParser = ParseSupportedRidsArgument }; @@ -62,9 +61,8 @@ static int Main(string[] args) if (!wasInGraph) { -#pragma warning disable CA2201 // Do not raise reserved exception types - throw new ApplicationException("Unable to find the best rid to use"); -#pragma warning restore CA2201 // Do not raise reserved exception types + Console.WriteLine("Unable to find the best rid to use"); + return -1; } Console.WriteLine(bestRidForPlatform); diff --git a/src/Aspire.Hosting.Sdk/SDK/Sdk.in.targets b/src/Aspire.Hosting.Sdk/SDK/Sdk.in.targets index 9d9e580d48b..1ce3b25dd79 100644 --- a/src/Aspire.Hosting.Sdk/SDK/Sdk.in.targets +++ b/src/Aspire.Hosting.Sdk/SDK/Sdk.in.targets @@ -117,7 +117,7 @@ - From 2d0196b5c31350cf35e2bce8e2263d5ce965793d Mon Sep 17 00:00:00 2001 From: Jose Perez Rodriguez Date: Thu, 19 Sep 2024 15:48:18 -0700 Subject: [PATCH 6/9] Fix package authoring --- eng/dashboardpack/Common.projitems | 3 ++- eng/dcppack/Common.projitems | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/eng/dashboardpack/Common.projitems b/eng/dashboardpack/Common.projitems index 92b712f853e..89b793bb47a 100644 --- a/eng/dashboardpack/Common.projitems +++ b/eng/dashboardpack/Common.projitems @@ -10,6 +10,7 @@ true true + false false $(ArtifactsShippingPackagesDir) @@ -24,7 +25,7 @@ - + diff --git a/eng/dcppack/Common.projitems b/eng/dcppack/Common.projitems index f7430e270b7..5754e5eead2 100644 --- a/eng/dcppack/Common.projitems +++ b/eng/dcppack/Common.projitems @@ -11,6 +11,7 @@ true true false + false $(ArtifactsShippingPackagesDir) $(TargetsForTfmSpecificContentInPackage);AddPackageFiles @@ -30,7 +31,7 @@ - + @@ -75,7 +76,7 @@ - + From d9e2e9b087b98c28c4ff41257a03a50d320c19ad Mon Sep 17 00:00:00 2001 From: Jose Perez Rodriguez Date: Fri, 20 Sep 2024 14:04:36 -0700 Subject: [PATCH 7/9] Fix TFM on rid tool --- .../Aspire.RuntimeIdentifier.Tool.csproj | 2 +- tests/Aspire.Hosting.Sdk.Tests/Aspire.Hosting.Sdk.Tests.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Aspire.Hosting.Sdk/Aspire.RuntimeIdentifier.Tool/Aspire.RuntimeIdentifier.Tool.csproj b/src/Aspire.Hosting.Sdk/Aspire.RuntimeIdentifier.Tool/Aspire.RuntimeIdentifier.Tool.csproj index 2a2402c0beb..ccf58834294 100644 --- a/src/Aspire.Hosting.Sdk/Aspire.RuntimeIdentifier.Tool/Aspire.RuntimeIdentifier.Tool.csproj +++ b/src/Aspire.Hosting.Sdk/Aspire.RuntimeIdentifier.Tool/Aspire.RuntimeIdentifier.Tool.csproj @@ -2,7 +2,7 @@ Exe - $(DefaultTargetFramework) + $(NetCurrent) Major false false diff --git a/tests/Aspire.Hosting.Sdk.Tests/Aspire.Hosting.Sdk.Tests.csproj b/tests/Aspire.Hosting.Sdk.Tests/Aspire.Hosting.Sdk.Tests.csproj index 94cfa109cab..c1d17f2fa6f 100644 --- a/tests/Aspire.Hosting.Sdk.Tests/Aspire.Hosting.Sdk.Tests.csproj +++ b/tests/Aspire.Hosting.Sdk.Tests/Aspire.Hosting.Sdk.Tests.csproj @@ -1,7 +1,7 @@ - $(DefaultTargetFramework) + $(NetCurrent) From ce4ae318eab0fe61978320483561a39282bf4dae Mon Sep 17 00:00:00 2001 From: Jose Perez Rodriguez Date: Sat, 21 Sep 2024 00:07:59 -0700 Subject: [PATCH 8/9] Fix issues with wrong variable names --- src/Aspire.Hosting.Sdk/Aspire.Hosting.Sdk.csproj | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Aspire.Hosting.Sdk/Aspire.Hosting.Sdk.csproj b/src/Aspire.Hosting.Sdk/Aspire.Hosting.Sdk.csproj index da68bf3582a..4be1db33cbe 100644 --- a/src/Aspire.Hosting.Sdk/Aspire.Hosting.Sdk.csproj +++ b/src/Aspire.Hosting.Sdk/Aspire.Hosting.Sdk.csproj @@ -13,7 +13,7 @@ - + @@ -36,12 +36,12 @@ Properties="Configuration=$(Configuration);Platform=$(Platform)" /> - <_publishContentToPackage Include="$(DotNetOutputPath)Aspire.RuntimeIdentifier.Tool/$(Configuration)/$(DefaultTargetFramework)/publish/**/*" /> + <_publishContentToPackage Include="$(DotNetOutputPath)Aspire.RuntimeIdentifier.Tool/$(Configuration)/$(NetCurrent)/publish/**/*" /> + PackagePath="tools/$(NetCurrent)/%(_publishContentToPackage.RecursiveDir)" /> From 6c5cda90ee113d75d00780975c9183edc45e13d2 Mon Sep 17 00:00:00 2001 From: Jose Perez Rodriguez Date: Sat, 21 Sep 2024 09:25:05 -0700 Subject: [PATCH 9/9] Address PR feedback --- .../Aspire.RuntimeIdentifier.Tool/Program.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Aspire.Hosting.Sdk/Aspire.RuntimeIdentifier.Tool/Program.cs b/src/Aspire.Hosting.Sdk/Aspire.RuntimeIdentifier.Tool/Program.cs index 55a983c9ec8..d8215c49b7d 100644 --- a/src/Aspire.Hosting.Sdk/Aspire.RuntimeIdentifier.Tool/Program.cs +++ b/src/Aspire.Hosting.Sdk/Aspire.RuntimeIdentifier.Tool/Program.cs @@ -48,7 +48,8 @@ static int Main(string[] args) if (!File.Exists(rgp)) { - throw new FileNotFoundException("File {0} does not exist. Please ensure the runtime graph path exists.", rgp); + Console.WriteLine($"File {rgp} does not exist. Please ensure the runtime graph path exists."); + return -1; } RuntimeGraph graph = JsonRuntimeFormat.ReadRuntimeGraph(rgp);