| File: GitDataReader\GitEnvironment.cs | Web Access |
| Project: src\sourcelink\src\Microsoft.Build.Tasks.Git\Microsoft.Build.Tasks.Git.csproj (Microsoft.Build.Tasks.Git) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the License.txt file in the project root for more information. using System; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; namespace Microsoft.Build.Tasks.Git { internal sealed class GitEnvironment { private const string LocalConfigurationScopeName = "local"; private const string GitRepositoryConfigurationScopeName = "GitRepositoryConfigurationScope"; public static readonly GitEnvironment Empty = new GitEnvironment(); public string? HomeDirectory { get; } public string? XdgConfigHomeDirectory { get; } public string? ProgramDataDirectory { get; } public string? SystemDirectory { get; } // TODO: https://github.com/dotnet/sourcelink/issues/301 // consider adding environment variables: GIT_DIR, GIT_DISCOVERY_ACROSS_FILESYSTEM, GIT_CEILING_DIRECTORIES // https://git-scm.com/docs/git#Documentation/git.txt-codeGITDIRcode // https://git-scm.com/docs/git#Documentation/git.txt-codeGITCEILINGDIRECTORIEScode // https://git-scm.com/docs/git#Documentation/git.txt-codeGITDISCOVERYACROSSFILESYSTEMcode // // if GIT_COMMON_DIR is set config worktree is ignored // https://git-scm.com/docs/git#Documentation/git.txt-codeGITCOMMONDIRcode // // GIT_WORK_TREE overrides all other work tree settings: // https://git-scm.com/docs/git#Documentation/git.txt-codeGITWORKTREEcode public GitEnvironment( string? homeDirectory = null, string? xdgConfigHomeDirectory = null, string? programDataDirectory = null, string? systemDirectory = null) { if (!string.IsNullOrWhiteSpace(homeDirectory)) { HomeDirectory = homeDirectory; } if (!string.IsNullOrWhiteSpace(xdgConfigHomeDirectory)) { XdgConfigHomeDirectory = xdgConfigHomeDirectory; } if (!string.IsNullOrWhiteSpace(programDataDirectory)) { ProgramDataDirectory = programDataDirectory; } if (!string.IsNullOrWhiteSpace(systemDirectory)) { SystemDirectory = systemDirectory; } } public static GitEnvironment Create(string? configurationScope) { if (NullableString.IsNullOrEmpty(configurationScope)) { return CreateFromProcessEnvironment(); } if (string.Equals(configurationScope, LocalConfigurationScopeName, StringComparison.OrdinalIgnoreCase)) { return Empty; } throw new NotSupportedException(string.Format(Resources.ValueOfIsNotValidConfigurationScope, GitRepositoryConfigurationScopeName, configurationScope)); } public static GitEnvironment CreateFromProcessEnvironment() { static string? getVariable(string name) { try { return Environment.GetEnvironmentVariable(name); } catch { return null; } } string? homeDirectory; try { homeDirectory = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile, Environment.SpecialFolderOption.DoNotVerify); } catch { homeDirectory = null; } return new GitEnvironment( homeDirectory: homeDirectory, xdgConfigHomeDirectory: getVariable("XDG_CONFIG_HOME"), programDataDirectory: getVariable("PROGRAMDATA"), systemDirectory: FindSystemDirectory(getVariable("PATH"), getVariable("MICROSOFT_SOURCELINK_TEST_ENVIRONMENT_ETC_DIR"))); } // internal for testing internal static string? FindSystemDirectory(string? pathList, string? unixEtcDir) { if (PathUtils.IsUnixLikePlatform) { return string.IsNullOrEmpty(unixEtcDir) ? "/etc" : unixEtcDir; } var gitInstallDir = FindWindowsGitInstallation(pathList); if (gitInstallDir != null) { return Path.Combine(gitInstallDir, "etc"); } return null; } private static string? FindWindowsGitInstallation(string? pathList) { Debug.Assert(!PathUtils.IsUnixLikePlatform); if (NullableString.IsNullOrEmpty(pathList)) { return null; } var paths = pathList.Split(Path.PathSeparator); var gitExe = paths.FirstOrDefault(dir => !string.IsNullOrWhiteSpace(dir) && File.Exists(PathUtils.CombinePaths(dir, "git.exe"))); if (gitExe != null) { return Path.GetDirectoryName(gitExe); } var gitCmd = paths.FirstOrDefault(dir => !string.IsNullOrWhiteSpace(dir) && File.Exists(PathUtils.CombinePaths(dir, "git.cmd"))); if (gitCmd != null) { return Path.GetDirectoryName(gitCmd); } return null; } internal string GetHomeDirectoryForPathExpansion(string path) => HomeDirectory ?? throw new NotSupportedException( string.Format(Resources.HomeRelativePathsAreNotAllowed, GitRepositoryConfigurationScopeName, LocalConfigurationScopeName, path)); } }