Skip to content

Commit dd90109

Browse files
authored
Implement GetConfiguredInstallType and GetGlobalJsonInfo (#50408)
2 parents 9f372f7 + 6fcbe43 commit dd90109

File tree

6 files changed

+144
-16
lines changed

6 files changed

+144
-16
lines changed

dnup.slnf

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"solution": {
3+
"path": "sdk.slnx",
4+
"projects": [
5+
"src\\Installer\\dnup\\dnup.csproj",
6+
]
7+
}
8+
}

src/Installer/dnup/Commands/Sdk/Install/SdkInstallCommand.cs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -300,10 +300,7 @@ public GlobalJsonInfo GetGlobalJsonInfo(string initialDirectory)
300300
return new GlobalJsonInfo
301301
{
302302
GlobalJsonPath = Environment.GetEnvironmentVariable("DOTNET_TESTHOOK_GLOBALJSON_PATH"),
303-
SdkVersion = Environment.GetEnvironmentVariable("DOTNET_TESTHOOK_GLOBALJSON_SDK_VERSION"),
304-
AllowPrerelease = Environment.GetEnvironmentVariable("DOTNET_TESTHOOK_GLOBALJSON_ALLOW_PRERELEASE"),
305-
RollForward = Environment.GetEnvironmentVariable("DOTNET_TESTHOOK_GLOBALJSON_ROLLFORWARD"),
306-
SdkPath = Environment.GetEnvironmentVariable("DOTNET_TESTHOOK_GLOBALJSON_SDK_INSTALL_PATH")
303+
GlobalJsonContents = null // Set to null for test mock; update as needed for tests
307304
};
308305
}
309306

@@ -324,7 +321,6 @@ public SdkInstallType GetConfiguredInstallType(out string? currentInstallPath)
324321
return returnValue;
325322
}
326323

327-
328324
public string? GetLatestInstalledAdminVersion()
329325
{
330326
var latestAdminVersion = Environment.GetEnvironmentVariable("DOTNET_TESTHOOK_LATEST_ADMIN_VERSION");
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System;
5+
using System.IO;
6+
using System.Linq;
7+
using System.Text.Json;
8+
using Microsoft.DotNet.Cli.Utils;
9+
10+
namespace Microsoft.DotNet.Tools.Bootstrapper;
11+
12+
public class DotnetInstaller : IDotnetInstaller
13+
{
14+
private readonly IEnvironmentProvider _environmentProvider;
15+
16+
public DotnetInstaller(IEnvironmentProvider? environmentProvider = null)
17+
{
18+
_environmentProvider = environmentProvider ?? new EnvironmentProvider();
19+
}
20+
21+
public SdkInstallType GetConfiguredInstallType(out string? currentInstallPath)
22+
{
23+
currentInstallPath = null;
24+
string? foundDotnet = _environmentProvider.GetCommandPath("dotnet");
25+
if (string.IsNullOrEmpty(foundDotnet))
26+
{
27+
return SdkInstallType.None;
28+
}
29+
30+
string installDir = Path.GetDirectoryName(foundDotnet)!;
31+
currentInstallPath = installDir;
32+
33+
string? dotnetRoot = Environment.GetEnvironmentVariable("DOTNET_ROOT");
34+
string programFiles = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles);
35+
string programFilesX86 = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86);
36+
bool isAdminInstall = installDir.StartsWith(Path.Combine(programFiles, "dotnet"), StringComparison.OrdinalIgnoreCase)
37+
|| installDir.StartsWith(Path.Combine(programFilesX86, "dotnet"), StringComparison.OrdinalIgnoreCase);
38+
39+
if (isAdminInstall)
40+
{
41+
// Admin install: DOTNET_ROOT should not be set, or if set, should match installDir
42+
if (!string.IsNullOrEmpty(dotnetRoot) && !PathsEqual(dotnetRoot, installDir) && !dotnetRoot.StartsWith(Path.Combine(programFiles, "dotnet"), StringComparison.OrdinalIgnoreCase) && !dotnetRoot.StartsWith(Path.Combine(programFilesX86, "dotnet"), StringComparison.OrdinalIgnoreCase))
43+
{
44+
return SdkInstallType.Inconsistent;
45+
}
46+
return SdkInstallType.Admin;
47+
}
48+
else
49+
{
50+
// User install: DOTNET_ROOT must be set and match installDir
51+
if (string.IsNullOrEmpty(dotnetRoot) || !PathsEqual(dotnetRoot, installDir))
52+
{
53+
return SdkInstallType.Inconsistent;
54+
}
55+
return SdkInstallType.User;
56+
}
57+
}
58+
59+
private static bool PathsEqual(string a, string b)
60+
{
61+
return string.Equals(Path.GetFullPath(a).TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar),
62+
Path.GetFullPath(b).TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar),
63+
StringComparison.OrdinalIgnoreCase);
64+
}
65+
66+
public string GetDefaultDotnetInstallPath()
67+
{
68+
return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "dotnet");
69+
}
70+
71+
public GlobalJsonInfo GetGlobalJsonInfo(string initialDirectory)
72+
{
73+
string? directory = initialDirectory;
74+
while (!string.IsNullOrEmpty(directory))
75+
{
76+
string globalJsonPath = Path.Combine(directory, "global.json");
77+
if (File.Exists(globalJsonPath))
78+
{
79+
using var stream = File.OpenRead(globalJsonPath);
80+
var contents = JsonSerializer.Deserialize(
81+
stream,
82+
GlobalJsonContentsJsonContext.Default.GlobalJsonContents);
83+
return new GlobalJsonInfo
84+
{
85+
GlobalJsonPath = globalJsonPath,
86+
GlobalJsonContents = contents
87+
};
88+
}
89+
var parent = Directory.GetParent(directory);
90+
if (parent == null)
91+
break;
92+
directory = parent.FullName;
93+
}
94+
return new GlobalJsonInfo();
95+
}
96+
97+
public string? GetLatestInstalledAdminVersion()
98+
{
99+
// TODO: Implement this
100+
return null;
101+
}
102+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
using System.Text.Json.Serialization;
2+
3+
namespace Microsoft.DotNet.Tools.Bootstrapper;
4+
5+
public class GlobalJsonContents
6+
{
7+
public SdkSection? Sdk { get; set; }
8+
9+
public class SdkSection
10+
{
11+
public string? Version { get; set; }
12+
public bool? AllowPrerelease { get; set; }
13+
public string? RollForward { get; set; }
14+
public string[]? Paths { get; set; }
15+
}
16+
}
17+
18+
[JsonSourceGenerationOptions(WriteIndented = true, PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase)]
19+
[JsonSerializable(typeof(GlobalJsonContents))]
20+
public partial class GlobalJsonContentsJsonContext : JsonSerializerContext
21+
{
22+
}

src/Installer/dnup/IDotnetInstaller.cs

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,16 +30,13 @@ public enum SdkInstallType
3030
public class GlobalJsonInfo
3131
{
3232
public string? GlobalJsonPath { get; set; }
33+
public GlobalJsonContents? GlobalJsonContents { get; set; }
3334

34-
public string? SdkVersion { get; set; }
35-
36-
public string? AllowPrerelease { get; set; }
37-
38-
public string? RollForward { get; set; }
39-
40-
// The sdk.path specified in the global.json, if any
41-
public string? SdkPath { get; set; }
42-
35+
// Convenience properties for compatibility
36+
public string? SdkVersion => GlobalJsonContents?.Sdk?.Version;
37+
public bool? AllowPrerelease => GlobalJsonContents?.Sdk?.AllowPrerelease;
38+
public string? RollForward => GlobalJsonContents?.Sdk?.RollForward;
39+
public string? SdkPath => (GlobalJsonContents?.Sdk?.Paths != null && GlobalJsonContents.Sdk.Paths.Length > 0) ? GlobalJsonContents.Sdk.Paths[0] : null;
4340
}
4441

4542
public interface IReleaseInfoProvider

src/Installer/dnup/dnup.csproj

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,11 @@
1616
</PropertyGroup>
1717

1818
<ItemGroup>
19-
<Compile Include="..\..\Cli\dotnet\Telemetry\CIEnvironmentDetectorForTelemetry.cs" LinkBase="Shared" />
20-
<Compile Include="..\..\Cli\dotnet\Telemetry\ICIEnvironmentDetector.cs" LinkBase="Shared" />
19+
<Compile Include="$(RepoRoot)src\Cli\dotnet\Telemetry\CIEnvironmentDetectorForTelemetry.cs" LinkBase="Shared" />
20+
<Compile Include="$(RepoRoot)src\Cli\dotnet\Telemetry\ICIEnvironmentDetector.cs" LinkBase="Shared" />
21+
<Compile Include="$(RepoRoot)src\Cli\Microsoft.DotNet.Cli.Utils\EnvironmentProvider.cs" LinkBase="Shared" />
22+
<Compile Include="$(RepoRoot)src\Cli\Microsoft.DotNet.Cli.Utils\Extensions\CollectionsExtensions.cs" LinkBase="Shared" />
23+
<Compile Include="$(RepoRoot)src\Cli\Microsoft.DotNet.Cli.Utils\IEnvironmentProvider.cs" LinkBase="Shared" />
2124
</ItemGroup>
2225

2326
<ItemGroup>

0 commit comments

Comments
 (0)