Skip to content

Commit 06ffeb7

Browse files
committed
use newer environment type
1 parent 0f683e2 commit 06ffeb7

File tree

81 files changed

+1041
-417
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

81 files changed

+1041
-417
lines changed

CONTRIBUTORS.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,7 @@ needs to be listed here.
291291
- Quinn McHenry <quinn@jqm.us>
292292
- Rahul Malik <rmalik@pinterest.com>
293293
- Randy Becker <81446220+randy-becker@users.noreply.github.com>
294-
- Rauhul Varma <rauhul@users.noreply.github.com>
294+
- Rauhul Varma <rauhul@apple.com>
295295
- Renzo Crisóstomo <renzo.crisostomo@xing.com>
296296
- Rich Ellis <rich@richellis.net>
297297
- Rick Ballard <rballard@apple.com>

Package.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,9 +184,12 @@ let package = Package(
184184

185185
.systemLibrary(name: "SPMSQLite3", pkgConfig: systemSQLitePkgConfig),
186186

187+
.target(name: "Environment"),
188+
187189
.target(
188190
name: "Basics",
189191
dependencies: [
192+
"Environment",
190193
"SPMSQLite3",
191194
.product(name: "DequeModule", package: "swift-collections"),
192195
.product(name: "OrderedCollections", package: "swift-collections"),
@@ -622,6 +625,10 @@ let package = Package(
622625
]
623626
),
624627

628+
.testTarget(
629+
name: "EnvironmentTests",
630+
dependencies: ["Environment"]),
631+
625632
.testTarget(
626633
name: "BasicsTests",
627634
dependencies: ["Basics", "SPMTestSupport", "tsan_utils"],

Sources/Basics/Archiver/TarArchiver.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ public struct TarArchiver: Archiver {
9393

9494
let process = TSCBasic.Process(
9595
arguments: [self.tarCommand, "acf", destinationPath.pathString, directory.basename],
96+
environment: .current,
9697
workingDirectory: directory.parentDirectory.underlying
9798
)
9899

Sources/Basics/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ add_library(Basics
2525
Concurrency/ThreadSafeKeyValueStore.swift
2626
Concurrency/TokenBucket.swift
2727
DispatchTimeInterval+Extensions.swift
28-
EnvironmentVariables.swift
28+
Environment.swift
2929
Errors.swift
3030
FileSystem/AbsolutePath.swift
3131
FileSystem/FileSystem+Extensions.swift

Sources/Basics/Concurrency/ConcurrencyHelpers.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,11 @@ import Dispatch
1515
import class Foundation.NSLock
1616
import class Foundation.ProcessInfo
1717
import struct Foundation.URL
18-
import enum TSCBasic.ProcessEnv
1918
import func TSCBasic.tsc_await
2019

2120
public enum Concurrency {
2221
public static var maxOperations: Int {
23-
ProcessEnv.block["SWIFTPM_MAX_CONCURRENT_OPERATIONS"].flatMap(Int.init) ?? ProcessInfo.processInfo
22+
Environment.current["SWIFTPM_MAX_CONCURRENT_OPERATIONS"].flatMap(Int.init) ?? ProcessInfo.processInfo
2423
.activeProcessorCount
2524
}
2625
}

Sources/Basics/EnvironmentVariables.swift

Lines changed: 122 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -10,99 +10,149 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13-
import Foundation
14-
import class Foundation.ProcessInfo
13+
@_exported import Environment
1514
import struct TSCBasic.ProcessEnvironmentBlock
16-
import struct TSCBasic.ProcessEnvironmentKey
17-
import enum TSCBasic.ProcessEnv
1815

19-
public typealias ProcessEnvironmentBlock = TSCBasic.ProcessEnvironmentBlock
16+
import class TSCBasic.Process
17+
import struct TSCBasic.ProcessResult
18+
import struct TSCBasic.AbsolutePath
2019

21-
extension ProcessEnvironmentBlock {
22-
public static var current: ProcessEnvironmentBlock { ProcessEnv.block }
20+
import Dispatch
2321

24-
public mutating func prependPath(value: String) {
25-
if let existing = self[Self.pathKey] {
26-
self[Self.pathKey] = "\(value):\(existing)"
27-
} else {
28-
self[Self.pathKey] = value
22+
// FIXME: remove ProcessEnvironmentBlockShims
23+
// only needed outside this module for Git
24+
extension Environment {
25+
@_spi(ProcessEnvironmentBlockShim)
26+
public init(_ processEnvironmentBlock: ProcessEnvironmentBlock) {
27+
self.init()
28+
for (key, value) in processEnvironmentBlock {
29+
self[.init(key.value)] = value
30+
}
31+
}
32+
}
33+
34+
extension ProcessEnvironmentBlock {
35+
@_spi(ProcessEnvironmentBlockShim)
36+
public init(_ environment: Environment) {
37+
self.init()
38+
for (key, value) in environment {
39+
self[.init(key.rawValue)] = value
2940
}
3041
}
42+
}
3143

32-
public mutating func appendPath(value: String) {
33-
if let existing = self[Self.pathKey] {
34-
self[Self.pathKey] = "\(existing):\(value)"
44+
// MARK: - Process Shims
45+
extension TSCBasic.Process {
46+
package convenience init(
47+
arguments: [String],
48+
environment: Environment = .current,
49+
workingDirectory: TSCBasic.AbsolutePath? = nil,
50+
outputRedirection: OutputRedirection = .collect,
51+
startNewProcessGroup: Bool = true,
52+
loggingHandler: LoggingHandler? = .none
53+
) {
54+
if let workingDirectory {
55+
self.init(arguments: arguments, environmentBlock: .init(environment), workingDirectory: workingDirectory, outputRedirection: outputRedirection, startNewProcessGroup: startNewProcessGroup, loggingHandler: loggingHandler)
3556
} else {
36-
self[Self.pathKey] = value
57+
self.init(arguments: arguments, environmentBlock: .init(environment), outputRedirection: outputRedirection, startNewProcessGroup: startNewProcessGroup, loggingHandler: loggingHandler)
3758
}
3859
}
60+
}
3961

40-
/// `PATH` variable in the process's environment (`Path` under Windows).
41-
package var path: String? { self[Self.pathKey] }
62+
extension TSCBasic.Process {
63+
static package func popen(
64+
arguments: [String],
65+
environment: Environment,
66+
loggingHandler: LoggingHandler? = nil,
67+
queue: DispatchQueue? = nil,
68+
completion: @escaping (Result<ProcessResult, Swift.Error>) -> Void
69+
) {
70+
popen(arguments: arguments, environmentBlock: .init(environment), loggingHandler: loggingHandler,queue: queue,completion: completion)
71+
}
4272

43-
package static var pathValueDelimiter: String {
44-
#if os(Windows)
45-
";"
46-
#else
47-
":"
48-
#endif
73+
@discardableResult
74+
static package func popen(
75+
arguments: [String],
76+
environment: Environment,
77+
loggingHandler: LoggingHandler? = nil
78+
) throws -> ProcessResult {
79+
try popen(arguments: arguments, environmentBlock: .init(environment), loggingHandler: loggingHandler)
4980
}
5081

51-
package static var pathKey: ProcessEnvironmentKey {
52-
#if os(Windows)
53-
"Path"
54-
#else
55-
"PATH"
56-
#endif
82+
@discardableResult
83+
static package func popen(
84+
args: String...,
85+
environment: Environment,
86+
loggingHandler: LoggingHandler? = nil
87+
) throws -> ProcessResult {
88+
try popen(arguments: args, environmentBlock: .init(environment), loggingHandler: loggingHandler)
5789
}
58-
}
5990

60-
// filter env variable that should not be included in a cache as they change
61-
// often and should not be considered in business logic
62-
// rdar://107029374
63-
extension ProcessEnvironmentBlock {
64-
// internal for testing
65-
static let nonCachableKeys: Set<ProcessEnvironmentKey> = [
66-
"TERM",
67-
"TERM_PROGRAM",
68-
"TERM_PROGRAM_VERSION",
69-
"TERM_SESSION_ID",
70-
"ITERM_PROFILE",
71-
"ITERM_SESSION_ID",
72-
"SECURITYSESSIONID",
73-
"LaunchInstanceID",
74-
"LC_TERMINAL",
75-
"LC_TERMINAL_VERSION",
76-
"CLICOLOR",
77-
"LS_COLORS",
78-
"VSCODE_IPC_HOOK_CLI",
79-
"HYPERFINE_RANDOMIZED_ENVIRONMENT_OFFSET",
80-
"SSH_AUTH_SOCK",
81-
]
82-
83-
/// Returns a copy of `self` with known non-cacheable keys removed.
84-
public var cachable: ProcessEnvironmentBlock {
85-
self.filter { !Self.nonCachableKeys.contains($0.key) }
91+
static package func popen(
92+
arguments: [String],
93+
environment: Environment,
94+
loggingHandler: LoggingHandler? = nil
95+
) async throws -> ProcessResult {
96+
try await popen(arguments: arguments, environmentBlock: .init(environment), loggingHandler: loggingHandler)
97+
}
98+
99+
static package func popen(
100+
args: String...,
101+
environment: Environment,
102+
loggingHandler: LoggingHandler? = nil
103+
) async throws -> ProcessResult {
104+
try await popen(arguments: args, environmentBlock: .init(environment), loggingHandler: loggingHandler)
86105
}
87106
}
88107

89-
extension ProcessEnvironmentKey: @retroactive Comparable {
90-
public static func < (lhs: Self, rhs: Self) -> Bool {
91-
#if os(Windows)
92-
// TODO: is this any faster than just doing a lowercased conversion and compare?
93-
lhs.value.caseInsensitiveCompare(rhs.value) == .orderedAscending
94-
#else
95-
lhs.value < rhs.value
96-
#endif
108+
extension TSCBasic.Process {
109+
@discardableResult
110+
static package func checkNonZeroExit(
111+
arguments: [String],
112+
environment: Environment,
113+
loggingHandler: LoggingHandler? = nil
114+
) throws -> String {
115+
try checkNonZeroExit(arguments: arguments, environmentBlock: .init(environment), loggingHandler: loggingHandler)
116+
}
117+
118+
@discardableResult
119+
static package func checkNonZeroExit(
120+
arguments: [String],
121+
environment: Environment,
122+
loggingHandler: LoggingHandler? = nil
123+
) async throws -> String {
124+
try await checkNonZeroExit(arguments: arguments, environmentBlock: .init(environment), loggingHandler: loggingHandler)
125+
}
126+
127+
@discardableResult
128+
static package func checkNonZeroExit(
129+
args: String...,
130+
environment: Environment,
131+
loggingHandler: LoggingHandler? = nil
132+
) throws -> String {
133+
try checkNonZeroExit(arguments: args, environmentBlock: .init(environment), loggingHandler: loggingHandler)
134+
}
135+
136+
137+
@discardableResult
138+
static package func checkNonZeroExit(
139+
args: String...,
140+
environment: Environment,
141+
loggingHandler: LoggingHandler? = nil
142+
) async throws -> String {
143+
try await checkNonZeroExit(arguments: args, environmentBlock: .init(environment), loggingHandler: loggingHandler)
97144
}
98145
}
99146

100-
extension ProcessEnvironmentBlock {
101-
package func nonPortable() -> [String: String] {
102-
var dict = [String: String]()
103-
for (key, value) in self {
104-
dict[key.value] = value
105-
}
106-
return dict
147+
// MARK: ProcessResult Shims
148+
extension ProcessResult {
149+
package init(
150+
arguments: [String],
151+
environment: Environment,
152+
exitStatus: ExitStatus,
153+
output: Result<[UInt8], Swift.Error>,
154+
stderrOutput: Result<[UInt8], Swift.Error>
155+
) {
156+
self.init(arguments: arguments, environmentBlock: .init(environment), exitStatus: exitStatus, output: output, stderrOutput: stderrOutput)
107157
}
108158
}

Sources/Basics/FileSystem/FileSystem+Extensions.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ import protocol TSCBasic.FileSystem
2323
import enum TSCBasic.FileSystemAttribute
2424
import var TSCBasic.localFileSystem
2525
import protocol TSCBasic.WritableByteStream
26-
import enum TSCBasic.ProcessEnv
2726

2827
public typealias FileSystem = TSCBasic.FileSystem
2928
public let localFileSystem = TSCBasic.localFileSystem
@@ -215,7 +214,7 @@ extension FileSystem {
215214
/// or under $XDG_CONFIG_HOME/swiftpm if the environmental variable is defined
216215
public var dotSwiftPM: AbsolutePath {
217216
get throws {
218-
if let configurationDirectory = ProcessEnv.block["XDG_CONFIG_HOME"] {
217+
if let configurationDirectory = Environment.current["XDG_CONFIG_HOME"] {
219218
return try AbsolutePath(validating: configurationDirectory).appending("swiftpm")
220219
} else {
221220
return try self.homeDirectory.appending(".swiftpm")

Sources/Basics/ImportScanning.swift

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import Dispatch
1414

1515
import class Foundation.JSONDecoder
1616
import class TSCBasic.Process
17-
import struct TSCBasic.ProcessEnvironmentBlock
1817

1918
private let defaultImports = ["Swift", "SwiftOnoneSupport", "_Concurrency",
2019
"_StringProcessing", "_SwiftConcurrencyShims"]
@@ -23,17 +22,17 @@ private struct Imports: Decodable {
2322
let imports: [String]
2423
}
2524

26-
public protocol ImportScanner {
25+
package protocol ImportScanner {
2726
func scanImports(_ filePathToScan: AbsolutePath) async throws -> [String]
2827
}
2928

3029
public struct SwiftcImportScanner: ImportScanner {
31-
private let swiftCompilerEnvironment: ProcessEnvironmentBlock
30+
private let swiftCompilerEnvironment: Environment
3231
private let swiftCompilerFlags: [String]
3332
private let swiftCompilerPath: AbsolutePath
3433

35-
public init(
36-
swiftCompilerEnvironment: ProcessEnvironmentBlock,
34+
package init(
35+
swiftCompilerEnvironment: Environment,
3736
swiftCompilerFlags: [String],
3837
swiftCompilerPath: AbsolutePath
3938
) {
@@ -47,7 +46,7 @@ public struct SwiftcImportScanner: ImportScanner {
4746
filePathToScan.pathString,
4847
"-scan-dependencies", "-Xfrontend", "-import-prescan"] + self.swiftCompilerFlags
4948

50-
let result = try await TSCBasic.Process.popen(arguments: cmd, environmentBlock: self.swiftCompilerEnvironment)
49+
let result = try await TSCBasic.Process.popen(arguments: cmd, environment: self.swiftCompilerEnvironment)
5150

5251
let stdout = try result.utf8Output()
5352
return try JSONDecoder.makeWithDefaults().decode(Imports.self, from: stdout).imports

Sources/Build/BuildDescription/ClangTargetBuildDescription.swift

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,6 @@ import struct SPMBuildCore.BuildParameters
2020
import struct SPMBuildCore.BuildToolPluginInvocationResult
2121
import struct SPMBuildCore.PrebuildCommandResult
2222

23-
import enum TSCBasic.ProcessEnv
24-
2523
/// Target description for a Clang target i.e. C language family target.
2624
public final class ClangTargetBuildDescription {
2725
/// The package this target belongs to.

Sources/Build/BuildManifest/LLBuildManifestBuilder+Swift.swift

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,8 @@ import struct LLBuildManifest.LLBuildManifest
1919
import struct SPMBuildCore.BuildParameters
2020
import struct PackageGraph.ResolvedModule
2121
import protocol TSCBasic.FileSystem
22-
import enum TSCBasic.ProcessEnv
2322
import func TSCBasic.topologicalSort
24-
import struct Basics.ProcessEnvironmentBlock
23+
import struct Basics.Environment
2524

2625
#if USE_IMPL_ONLY_IMPORTS
2726
@_implementationOnly import class DriverSupport.SPMSwiftDriverExecutor
@@ -76,7 +75,7 @@ extension LLBuildManifestBuilder {
7675
let executor = SPMSwiftDriverExecutor(
7776
resolver: resolver,
7877
fileSystem: target.fileSystem,
79-
env: ProcessEnvironmentBlock.current
78+
env: Environment.current
8079
)
8180
var driver = try Driver(
8281
args: commandLine,
@@ -291,7 +290,7 @@ extension LLBuildManifestBuilder {
291290
let executor = SPMSwiftDriverExecutor(
292291
resolver: resolver,
293292
fileSystem: self.fileSystem,
294-
env: ProcessEnvironmentBlock.current
293+
env: Environment.current
295294
)
296295
var driver = try Driver(
297296
args: commandLine,

Sources/Build/BuildManifest/LLBuildManifestBuilder.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ import SwiftDriver
2323
#endif
2424

2525
import struct TSCBasic.ByteString
26-
import enum TSCBasic.ProcessEnv
2726
import func TSCBasic.topologicalSort
2827

2928
/// High-level interface to ``LLBuildManifest`` and ``LLBuildManifestWriter``.

0 commit comments

Comments
 (0)