From 5f9c4c3ff992ec3e80145f91a2a0602fe54394f4 Mon Sep 17 00:00:00 2001 From: Max Desiatov Date: Fri, 23 Feb 2024 17:50:01 +0000 Subject: [PATCH] Update `Git` type for `ProcessEnvironmentBlock` Previous implementation did not account for case insensitivity on Windows and made it hard to remove deprecation warnings in clients of TSC. --- Sources/TSCUtility/Git.swift | 85 ++++++++++++++++-------------------- 1 file changed, 38 insertions(+), 47 deletions(-) diff --git a/Sources/TSCUtility/Git.swift b/Sources/TSCUtility/Git.swift index 8da5746f..176e5a54 100644 --- a/Sources/TSCUtility/Git.swift +++ b/Sources/TSCUtility/Git.swift @@ -11,51 +11,7 @@ import class Foundation.ProcessInfo import TSCBasic -extension Version { - // FIXME: deprecate 2/2021 (used below), remove once clients transitioned - @available(*, deprecated, message: "moved to SwiftPM") - init?(tag: String) { - if tag.first == "v" { - self.init(string: String(tag.dropFirst())) - } else { - self.init(string: tag) - } - } -} - public enum Git { - // FIXME: deprecate 2/2021, remove once clients transitioned - @available(*, deprecated, message: "moved to SwiftPM") - public static func convertTagsToVersionMap(_ tags: [String]) -> [Version: [String]] { - // First, check if we need to restrict the tag set to version-specific tags. - var knownVersions: [Version: [String]] = [:] - var versionSpecificKnownVersions: [Version: [String]] = [:] - - for tag in tags { - for versionSpecificKey in Versioning.currentVersionSpecificKeys { - if tag.hasSuffix(versionSpecificKey) { - let trimmedTag = String(tag.dropLast(versionSpecificKey.count)) - if let version = Version(tag: trimmedTag) { - versionSpecificKnownVersions[version, default: []].append(tag) - } - break - } - } - - if let version = Version(tag: tag) { - knownVersions[version, default: []].append(tag) - } - } - // Check if any version specific tags were found. - // If true, then return the version specific tags, - // or else return the version independent tags. - if !versionSpecificKnownVersions.isEmpty { - return versionSpecificKnownVersions - } else { - return knownVersions - } - } - /// A shell command to run for Git. Can be either a name or a path. /// - Note: modification is not thread safe, designed for testing only public static var tool: String = "git\(executableFileSuffix)" @@ -70,20 +26,55 @@ public enum Git { } } - private static var _gitEnvironment = ProcessInfo.processInfo.environment + private static var _gitEnvironment = ProcessEnv.block + + @available(*, + deprecated, + renamed: "environmentBlock", + message: "Previous `[String: String]` representation did not account for case insensitivity on Windows." + ) + public static var environment: [String: String] { + get { + var env = Self._gitEnvironment + + // These variables are inserted into the environment when shelling out + // to git if not already present. + let underrideVariables: ProcessEnvironmentBlock = [ + // Disable terminal prompts in git. This will make git error out and return + // when it needs a user/pass etc instead of hanging the terminal (SR-3981). + "GIT_TERMINAL_PROMPT": "0", + + // The above is env variable is not enough. However, ssh_config's batch + // mode is made for this purpose. see: https://linux.die.net/man/5/ssh_config + "GIT_SSH_COMMAND": "ssh -oBatchMode=yes", + ] + + for (key, value) in underrideVariables { + // Skip this key is already present in the env. + if env.keys.contains(key) { continue } + + env[key] = value + } + + return Dictionary(env.map { ($0.value, $1) }, uniquingKeysWith: { $1 }) + } + set { + Self._gitEnvironment = .init(newValue) + } + } /// Returns the environment variables for launching the git subprocess. /// /// This contains the current environment with custom overrides for using /// git from swift build. /// - Note: modification is not thread safe, designed for testing only - public static var environment: [String: String] { + public static var environmentBlock: ProcessEnvironmentBlock { get { var env = Self._gitEnvironment // These variables are inserted into the environment when shelling out // to git if not already present. - let underrideVariables = [ + let underrideVariables: ProcessEnvironmentBlock = [ // Disable terminal prompts in git. This will make git error out and return // when it needs a user/pass etc instead of hanging the terminal (SR-3981). "GIT_TERMINAL_PROMPT": "0",