From 8edf1afc281e332968d262d333620a9f63194bf9 Mon Sep 17 00:00:00 2001 From: "Brett V. Forsgren" Date: Fri, 22 May 2026 10:15:46 -0600 Subject: [PATCH] Add circular dependency detection to MSBuildHelper.ThrowOnError Add a new ThrowOnCircularDependency helper that matches the pattern 'Circular dependency detected ''..''' in MSBuild output and throws a plain Exception with the message 'Circular dependency detected' to enable proper grouping in telemetry. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../Utilities/MSBuildHelperTests.cs | 8 ++++++++ .../NuGetUpdater.Core/Utilities/MSBuildHelper.cs | 10 ++++++++++ 2 files changed, 18 insertions(+) diff --git a/nuget/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/MSBuildHelperTests.cs b/nuget/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/MSBuildHelperTests.cs index d4899e4de65..97cb972ae07 100644 --- a/nuget/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/MSBuildHelperTests.cs +++ b/nuget/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/MSBuildHelperTests.cs @@ -646,5 +646,13 @@ Using Msbuild from '/usr/local/dotnet/current/sdk/9.0.311'. // expectedError new DependencyFileNotParseable("/path/to/packages.config", "Unexpected XML declaration. The XML declaration must be the first node in the document, and no whitespace characters are allowed to appear before it. Line 1, position 5.") ]; + + yield return + [ + // output + "Circular dependency detected 'ReactiveProperty 3.6.0 => System.Reactive 3.1.1 => System.Reactive.PlatformServices 6.1.0 => System.Reactive 3.1.1'.", + // expectedError + new UnknownError(new Exception("Circular dependency detected"), "TEST-JOB-ID"), + ]; } } diff --git a/nuget/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/MSBuildHelper.cs b/nuget/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/MSBuildHelper.cs index 9c9424eee17..5d098e5d349 100644 --- a/nuget/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/MSBuildHelper.cs +++ b/nuget/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/MSBuildHelper.cs @@ -646,6 +646,7 @@ internal static void ThrowOnError(string output) ThrowOnBadResponse(output); ThrowOnUnparseableFile(output); ThrowOnMultipleProjectsForPackagesConfig(output); + ThrowOnCircularDependency(output); } private static void ThrowOnUnauthenticatedFeed(string stdout) @@ -788,6 +789,15 @@ private static void ThrowOnMultipleProjectsForPackagesConfig(string output) } } + private static void ThrowOnCircularDependency(string output) + { + var pattern = new Regex(@"Circular dependency detected '.*'"); + if (pattern.IsMatch(output)) + { + throw new Exception("Circular dependency detected"); + } + } + internal static bool TryGetGlobalJsonPath(string repoRootPath, string workspacePath, [NotNullWhen(returnValue: true)] out string? globalJsonPath) { globalJsonPath = PathHelper.GetFileInDirectoryOrParent(workspacePath, repoRootPath, "global.json", caseSensitive: false);