| File: EnvironmentProvider.cs | Web Access |
| Project: src\sdk\src\Cli\Microsoft.DotNet.Cli.Utils\Microsoft.DotNet.Cli.Utils.csproj (Microsoft.DotNet.Cli.Utils) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics.CodeAnalysis; using Microsoft.DotNet.Cli.Utils.Extensions; namespace Microsoft.DotNet.Cli.Utils; public class EnvironmentProvider( IEnumerable<string>? extensionsOverride = null, IEnumerable<string>? searchPathsOverride = null) : IEnvironmentProvider { private static char[] s_pathSeparator = [Path.PathSeparator]; private static char[] s_quote = ['"']; private IEnumerable<string>? _searchPaths = searchPathsOverride; private readonly Lazy<string> _userHomeDirectory = new(() => Environment.GetEnvironmentVariable("HOME") ?? string.Empty); private IEnumerable<string>? _executableExtensions = extensionsOverride; public IEnumerable<string> ExecutableExtensions { get { if (_executableExtensions == null) { _executableExtensions = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? Environment.GetEnvironmentVariable("PATHEXT")? .Split(';') .Select(e => e.ToLower().Trim('"')) ?? [string.Empty] : [string.Empty]; } return _executableExtensions; } } private IEnumerable<string> SearchPaths { get { if (_searchPaths == null) { var searchPaths = new List<string> { AppContext.BaseDirectory }; searchPaths.AddRange(Environment .GetEnvironmentVariable("PATH")? .Split(s_pathSeparator) .Select(p => p.Trim(s_quote)) .Where(p => !string.IsNullOrWhiteSpace(p)) .Select(p => ExpandTildeSlash(p)) ?? []); _searchPaths = searchPaths; } return _searchPaths; } } private string ExpandTildeSlash(string path) { const string tildeSlash = "~/"; if (path.StartsWith(tildeSlash, StringComparison.Ordinal) && !string.IsNullOrEmpty(_userHomeDirectory.Value)) { return Path.Combine(_userHomeDirectory.Value, path.Substring(tildeSlash.Length)); } else { return path; } } public string? GetCommandPath(string commandName, params string[] extensions) { if (!extensions.Any()) { extensions = [.. ExecutableExtensions]; } var commandPath = SearchPaths.Join( extensions, p => true, s => true, (p, s) => Path.Combine(p, commandName + s)) .FirstOrDefault(File.Exists); return commandPath; } public string? GetCommandPathFromRootPath(string rootPath, string commandName, params string[] extensions) { if (!extensions.Any()) { extensions = [.. ExecutableExtensions]; } var commandPath = extensions.Select(e => Path.Combine(rootPath, commandName + e)) .FirstOrDefault(File.Exists); return commandPath; } public string? GetCommandPathFromRootPath(string rootPath, string commandName, IEnumerable<string> extensions) { var extensionsArr = extensions.OrEmptyIfNull().ToArray(); return GetCommandPathFromRootPath(rootPath, commandName, extensionsArr); } public string? GetEnvironmentVariable(string name) { return Environment.GetEnvironmentVariable(name); } public bool GetEnvironmentVariableAsBool(string name, bool defaultValue) { var str = Environment.GetEnvironmentVariable(name); if (string.IsNullOrEmpty(str)) { return defaultValue; } switch (str.ToLowerInvariant()) { case "true": case "1": case "yes": return true; case "false": case "0": case "no": return false; default: return defaultValue; } } public string? GetEnvironmentVariable(string variable, EnvironmentVariableTarget target) { return Environment.GetEnvironmentVariable(variable, target); } public bool TryGetEnvironmentVariable(string name, [NotNullWhen(true)] out string? value) { value = Environment.GetEnvironmentVariable(name); return value != null; } public void SetEnvironmentVariable(string variable, string value, EnvironmentVariableTarget target) { Environment.SetEnvironmentVariable(variable, value, target); } public int? GetEnvironmentVariableAsNullableInt(string variable) { if (Environment.GetEnvironmentVariable(variable) is string strValue && int.TryParse(strValue, out int intValue)) { return intValue; } return null; } public bool TryGetEnvironmentVariableAsBool(string name, [NotNullWhen(true)] out bool value) { if (TryGetEnvironmentVariable(name, out string? strValue) && (bool.TryParse(strValue, out bool boolValue) || TryParseNonBoolConstantStringAsBool(strValue, out boolValue))) { value = boolValue; return true; } else { value = false; return false; } } /// <summary> /// Parses non-boolean constant strings like "1", "0", "yes", "no", "on", "off" as boolean values. /// </summary> private static bool TryParseNonBoolConstantStringAsBool(string? strValue, out bool value) { switch (strValue?.ToLowerInvariant()) { case "1": case "yes": case "on": value = true; return true; case "0": case "no": case "off": value = false; return true; default: value = false; return false; } } public bool TryGetEnvironmentVariableAsInt(string name, [NotNullWhen(true)] out int value) { if (TryGetEnvironmentVariable(name, out string? strValue) && int.TryParse(strValue, out int intValue)) { value = intValue; return true; } else { value = -1; return false; } } }