Skip to content

Commit

Permalink
Merge pull request #26851 from JanKrivanek/GetDotnetDir
Browse files Browse the repository at this point in the history
Remove custom logic of fetching dotnet dir
  • Loading branch information
JanKrivanek authored Sep 9, 2022
2 parents 8c5a2ec + b99e5bb commit 517aa20
Show file tree
Hide file tree
Showing 9 changed files with 109 additions and 51 deletions.
19 changes: 5 additions & 14 deletions src/Cli/dotnet/CommonOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -231,22 +231,13 @@ internal static string ResolveRidShorthandOptionsToRuntimeIdentifier(string os,
return $"{os}-{arch}";
}

public static string GetDotnetExeDirectory()
{
// Alternatively we could use Microsoft.DotNet.NativeWrapper.EnvironmentProvider.GetDotnetExeDirectory here
// (while injecting env resolver so that DOTNET_MSBUILD_SDK_RESOLVER_CLI_DIR is being returned as null)
// However - it first looks on PATH - which can be problematic in environment (e.g. dev) where we have installed and xcopy dotnet versions

var dotnetRootPath = Path.GetDirectoryName(Environment.ProcessPath);
// When running under test the path does not always contain "dotnet".
// The sdk folder is /d/ when run on helix because of space issues
dotnetRootPath = Path.GetFileName(dotnetRootPath).Contains("dotnet") || Path.GetFileName(dotnetRootPath).Contains("x64") || Path.GetFileName(dotnetRootPath).Equals("d") ? dotnetRootPath : Path.Combine(dotnetRootPath, "dotnet");
return dotnetRootPath;
}

public static string GetCurrentRuntimeId()
{
var dotnetRootPath = GetDotnetExeDirectory();
// Get the dotnet directory, while ignoring custom msbuild resolvers
string dotnetRootPath = Microsoft.DotNet.NativeWrapper.EnvironmentProvider.GetDotnetExeDirectory(key =>
key.Equals("DOTNET_MSBUILD_SDK_RESOLVER_CLI_DIR", StringComparison.InvariantCultureIgnoreCase)
? null
: Environment.GetEnvironmentVariable(key));
var ridFileName = "NETCoreSdkRuntimeIdentifierChain.txt";
// When running under test the Product.Version might be empty or point to version not installed in dotnetRootPath.
string runtimeIdentifierChainPath = string.IsNullOrEmpty(Product.Version) || !Directory.Exists(Path.Combine(dotnetRootPath, "sdk", Product.Version)) ?
Expand Down
17 changes: 15 additions & 2 deletions src/Cli/dotnet/commands/dotnet-new/SdkInfoProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,19 @@ namespace Microsoft.DotNet.Tools.New
{
internal class SdkInfoProvider : ISdkInfoProvider
{
private readonly Func<string> _getCurrentProcessPath;

public Guid Id { get; } = Guid.Parse("{A846C4E2-1E85-4BF5-954D-17655D916928}");

public SdkInfoProvider()
: this(null)
{ }

internal SdkInfoProvider(Func<string> getCurrentProcessPath)
{
_getCurrentProcessPath = getCurrentProcessPath;
}

public Task<string> GetCurrentVersionAsync(CancellationToken cancellationToken)
{
return Task.FromResult(Product.Version);
Expand All @@ -29,10 +40,12 @@ public Task<string> GetCurrentVersionAsync(CancellationToken cancellationToken)
public Task<IEnumerable<string>> GetInstalledVersionsAsync(CancellationToken cancellationToken)
{
// Get the dotnet directory, while ignoring custom msbuild resolvers
string dotnetDir = Microsoft.DotNet.NativeWrapper.EnvironmentProvider.GetDotnetExeDirectory(key =>
string dotnetDir = Microsoft.DotNet.NativeWrapper.EnvironmentProvider.GetDotnetExeDirectory(
key =>
key.Equals("DOTNET_MSBUILD_SDK_RESOLVER_CLI_DIR", StringComparison.InvariantCultureIgnoreCase)
? null
: Environment.GetEnvironmentVariable(key));
: Environment.GetEnvironmentVariable(key),
_getCurrentProcessPath);

IEnumerable<string> sdks;
try
Expand Down
8 changes: 5 additions & 3 deletions src/Microsoft.DotNet.TemplateLocator/TemplateLocator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,18 @@ public sealed class TemplateLocator
private IWorkloadResolver? _workloadResolver;
private readonly Lazy<NETCoreSdkResolver> _netCoreSdkResolver;
private readonly Func<string, string> _getEnvironmentVariable;
private readonly Func<string>? _getCurrentProcessPath;
#nullable disable
public TemplateLocator()
: this(Environment.GetEnvironmentVariable, VSSettings.Ambient, null, null)
: this(Environment.GetEnvironmentVariable, null, VSSettings.Ambient, null, null)
{
}
#nullable restore

/// <summary>
/// Test constructor
/// </summary>
public TemplateLocator(Func<string, string> getEnvironmentVariable, VSSettings vsSettings,
public TemplateLocator(Func<string, string> getEnvironmentVariable, Func<string>? getCurrentProcessPath, VSSettings vsSettings,
IWorkloadManifestProvider? workloadManifestProvider, IWorkloadResolver? workloadResolver)
{
_netCoreSdkResolver =
Expand All @@ -36,6 +37,7 @@ public TemplateLocator(Func<string, string> getEnvironmentVariable, VSSettings v
_workloadManifestProvider = workloadManifestProvider;
_workloadResolver = workloadResolver;
_getEnvironmentVariable = getEnvironmentVariable;
_getCurrentProcessPath = getCurrentProcessPath;
}

public IReadOnlyCollection<IOptionalSdkTemplatePackageInfo> GetDotnetSdkTemplatePackages(
Expand Down Expand Up @@ -63,7 +65,7 @@ public IReadOnlyCollection<IOptionalSdkTemplatePackageInfo> GetDotnetSdkTemplate

public bool TryGetDotnetSdkVersionUsedInVs(string vsVersion, out string? sdkVersion)
{
string dotnetExeDir = EnvironmentProvider.GetDotnetExeDirectory(_getEnvironmentVariable);
string dotnetExeDir = EnvironmentProvider.GetDotnetExeDirectory(_getEnvironmentVariable, _getCurrentProcessPath);

if (!Version.TryParse(vsVersion, out var parsedVsVersion))
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,19 +31,21 @@ public sealed class DotNetMSBuildSdkResolver : SdkResolver
public override int Priority => 5000;

private readonly Func<string, string> _getEnvironmentVariable;
private readonly Func<string> _getCurrentProcessPath;
private readonly NETCoreSdkResolver _netCoreSdkResolver;

private static CachingWorkloadResolver _staticWorkloadResolver = new CachingWorkloadResolver();

public DotNetMSBuildSdkResolver()
: this(Environment.GetEnvironmentVariable, VSSettings.Ambient)
: this(Environment.GetEnvironmentVariable, null, VSSettings.Ambient)
{
}

// Test constructor
public DotNetMSBuildSdkResolver(Func<string, string> getEnvironmentVariable, VSSettings vsSettings)
public DotNetMSBuildSdkResolver(Func<string, string> getEnvironmentVariable, Func<string> getCurrentProcessPath, VSSettings vsSettings)
{
_getEnvironmentVariable = getEnvironmentVariable;
_getCurrentProcessPath = getCurrentProcessPath;
_netCoreSdkResolver = new NETCoreSdkResolver(getEnvironmentVariable, vsSettings);
}

Expand Down Expand Up @@ -87,7 +89,7 @@ public override SdkResult Resolve(SdkReference sdkReference, SdkResolverContext

if (msbuildSdksDir == null)
{
dotnetRoot = EnvironmentProvider.GetDotnetExeDirectory(_getEnvironmentVariable);
dotnetRoot = EnvironmentProvider.GetDotnetExeDirectory(_getEnvironmentVariable, _getCurrentProcessPath);
string globalJsonStartDir = GetGlobalJsonStartDir(context);
var resolverResult = _netCoreSdkResolver.ResolveNETCoreSdkDirectory(globalJsonStartDir, context.MSBuildVersion, context.IsRunningInVisualStudio, dotnetRoot);

Expand Down
53 changes: 40 additions & 13 deletions src/Resolvers/Microsoft.DotNet.NativeWrapper/EnvironmentProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,16 @@ public class EnvironmentProvider
private IEnumerable<string> _searchPaths;

private readonly Func<string, string> _getEnvironmentVariable;
private readonly Func<string> _getCurrentProcessPath;

public EnvironmentProvider(Func<string, string> getEnvironmentVariable)
: this(getEnvironmentVariable, GetCurrentProcessPath)
{ }

public EnvironmentProvider(Func<string, string> getEnvironmentVariable, Func<string> getCurrentProcessPath)
{
_getEnvironmentVariable = getEnvironmentVariable;
_getCurrentProcessPath = getCurrentProcessPath;
}

private IEnumerable<string> SearchPaths
Expand Down Expand Up @@ -61,22 +67,24 @@ public string GetDotnetExeDirectory()
return environmentOverride;
}

var dotnetExe = GetCommandPath(Constants.DotNet);
string dotnetExe = _getCurrentProcessPath();

if (dotnetExe != null && !Interop.RunningOnWindows)
if (string.IsNullOrEmpty(dotnetExe) || !Path.GetFileNameWithoutExtension(dotnetExe)
.Equals(Constants.DotNet, StringComparison.InvariantCultureIgnoreCase))
{
// e.g. on Linux the 'dotnet' command from PATH is a symlink so we need to
// resolve it to get the actual path to the binary
dotnetExe = Interop.Unix.realpath(dotnetExe) ?? dotnetExe;
}
string dotnetExeFromPath = GetCommandPath(Constants.DotNet);

if (dotnetExeFromPath != null && !Interop.RunningOnWindows)
{
// e.g. on Linux the 'dotnet' command from PATH is a symlink so we need to
// resolve it to get the actual path to the binary
dotnetExeFromPath = Interop.Unix.realpath(dotnetExeFromPath) ?? dotnetExeFromPath;
}

if (string.IsNullOrWhiteSpace(dotnetExe))
{
#if NET6_0_OR_GREATER
dotnetExe = Environment.ProcessPath;
#else
dotnetExe = Process.GetCurrentProcess().MainModule.FileName;
#endif
if (!string.IsNullOrWhiteSpace(dotnetExeFromPath))
{
dotnetExe = dotnetExeFromPath;
}
}

return Path.GetDirectoryName(dotnetExe);
Expand All @@ -91,5 +99,24 @@ public static string GetDotnetExeDirectory(Func<string, string> getEnvironmentVa
var environmentProvider = new EnvironmentProvider(getEnvironmentVariable);
return environmentProvider.GetDotnetExeDirectory();
}

public static string GetDotnetExeDirectory(Func<string, string> getEnvironmentVariable, Func<string> getCurrentProcessPath)
{
getEnvironmentVariable ??= Environment.GetEnvironmentVariable;
getCurrentProcessPath ??= GetCurrentProcessPath;
var environmentProvider = new EnvironmentProvider(getEnvironmentVariable, getCurrentProcessPath);
return environmentProvider.GetDotnetExeDirectory();
}

private static string GetCurrentProcessPath()
{
string currentProcessPath;
#if NET6_0_OR_GREATER
currentProcessPath = Environment.ProcessPath;
#else
currentProcessPath = Process.GetCurrentProcess().MainModule.FileName;
#endif
return currentProcessPath;
}
}
}
Loading

0 comments on commit 517aa20

Please sign in to comment.