From 37ec6d52c3af14297c6b08c085b8bc60c1c93b2e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 15 Apr 2026 18:55:47 +0000 Subject: [PATCH 1/2] Initial plan From 2126a0bd32ba534422369f9151228bf8d0e2d0fe Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 15 Apr 2026 19:07:06 +0000 Subject: [PATCH 2/2] Add E2E test for global.json paths-based SDK install directory Agent-Logs-Url: https://github.com/dotnet/sdk/sessions/20dc8a71-2232-4ec2-922d-d455418757c7 Co-authored-by: nagilson <23152278+nagilson@users.noreply.github.com> --- test/dotnetup.Tests/DnupE2Etest.cs | 67 ++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/test/dotnetup.Tests/DnupE2Etest.cs b/test/dotnetup.Tests/DnupE2Etest.cs index 2e1f1183a5e6..1445b12ccf60 100644 --- a/test/dotnetup.Tests/DnupE2Etest.cs +++ b/test/dotnetup.Tests/DnupE2Etest.cs @@ -769,6 +769,73 @@ public void InstallViaGlobalJson_SdkUsesGlobalJsonSource() output.Should().Contain("Explicit", "JSON list output should include Explicit source for runtime"); } + [Fact] + public void InstallViaGlobalJson_PathsDirectsSdkToLocalDirectory() + { + using var testEnv = DotnetupTestUtilities.CreateTestEnvironment(); + + // Create a project subdirectory with a global.json that includes a "paths" entry. + // The "paths" field tells dotnetup where to install the SDK relative to the global.json. + string projectDir = Path.Combine(testEnv.TempRoot, "my-project"); + Directory.CreateDirectory(projectDir); + + string globalJsonPath = Path.Combine(projectDir, "global.json"); + string globalJsonContent = """ + { + "sdk": { + "version": "9.0.103", + "rollForward": "disable", + "paths": [".dotnet"] + } + } + """; + File.WriteAllText(globalJsonPath, globalJsonContent); + + // The expected install path is ".dotnet" resolved relative to the global.json directory. + string expectedInstallPath = Path.GetFullPath(Path.Combine(projectDir, ".dotnet")); + + // Install SDK without providing --install-path so dotnetup resolves the install directory + // from the "paths" field in global.json. + var sdkArgs = new List(["sdk", "install", + "--interactive", "false", + "--no-progress"]); + if (!string.IsNullOrEmpty(testEnv.ManifestPath)) + { + sdkArgs.AddRange(["--manifest-path", testEnv.ManifestPath]); + } + + (int exitCode, string output) = DotnetupTestUtilities.RunDotnetupProcess( + [.. sdkArgs], captureOutput: true, workingDirectory: projectDir); + exitCode.Should().Be(0, $"SDK install via global.json paths failed. Output:\n{output}"); + + // Verify the SDK was installed into the directory specified by the "paths" field. + var sdkVersionDir = Path.Combine(expectedInstallPath, "sdk", "9.0.103"); + Directory.Exists(sdkVersionDir).Should().BeTrue( + $"SDK should be installed in the directory specified by global.json paths: {sdkVersionDir}"); + + // Verify the manifest records the install spec with GlobalJson source under the correct root. + List installSpecs; + using (var mutex = new ScopedMutex(Constants.MutexNames.ModifyInstallationStates)) + { + var manifest = new DotnetupSharedManifest(testEnv.ManifestPath); + var manifestData = manifest.ReadManifest(); + installSpecs = manifestData.DotnetRoots + .Where(r => DotnetupUtilities.PathsEqual(r.Path, expectedInstallPath)) + .SelectMany(r => r.InstallSpecs) + .ToList(); + } + + installSpecs.Should().ContainSingle(s => s.Component == InstallComponent.SDK, + "SDK should be tracked in the manifest under the global.json-specified install path"); + var sdkSpec = installSpecs.First(s => s.Component == InstallComponent.SDK); + sdkSpec.InstallSource.Should().Be(InstallSource.GlobalJson, + "SDK installed via global.json paths should have GlobalJson source"); + sdkSpec.GlobalJsonPath.Should().NotBeNullOrEmpty( + "SDK install spec should record the global.json path"); + sdkSpec.GlobalJsonPath.Should().Be(globalJsonPath, + "SDK install spec should record the correct global.json path"); + } + [Fact] public void InstallThenUninstall_FolderIsCleanedUp() {