@@ -23,6 +23,30 @@ import Dispatch
23
23
24
24
import _Concurrency
25
25
26
+ public struct ProcessEnvironmentBlock {
27
+ #if os(Windows)
28
+ public typealias Key = CaseInsensitiveString
29
+ private var storage : Dictionary < CaseInsensitiveString , String >
30
+ #else
31
+ public typealias Key = String
32
+ private var storage : Dictionary < String , String >
33
+ #endif
34
+
35
+ public init < S: Sequence > ( uniqueKeysWithValues keysAndValues: S )
36
+ where S. Element == ( Key , String ) {
37
+ storage. init ( uniqueKeysWithValues: keysAndValues)
38
+ }
39
+
40
+ public subscript( _ key: String ) -> String {
41
+ #if os(Windows)
42
+ return stroage [ CaseInsensitiveString ( key) ]
43
+ #else
44
+ return storage [ key]
45
+ #endif
46
+ }
47
+ }
48
+
49
+
26
50
/// Process result data which is available after process termination.
27
51
public struct ProcessResult : CustomStringConvertible , Sendable {
28
52
@@ -53,7 +77,7 @@ public struct ProcessResult: CustomStringConvertible, Sendable {
53
77
public let arguments : [ String ]
54
78
55
79
/// The environment with which the process was launched.
56
- public let environment : [ String : String ]
80
+ public let environment : ProcessEnvironmentBlock
57
81
58
82
/// The exit status of the process.
59
83
public let exitStatus : ExitStatus
@@ -71,7 +95,7 @@ public struct ProcessResult: CustomStringConvertible, Sendable {
71
95
/// See `waitpid(2)` for information on the exit status code.
72
96
public init (
73
97
arguments: [ String ] ,
74
- environment: [ String : String ] ,
98
+ environment: ProcessEnvironmentBlock ,
75
99
exitStatusCode: Int32 ,
76
100
normal: Bool ,
77
101
output: Result < [ UInt8 ] , Swift . Error > ,
@@ -99,7 +123,7 @@ public struct ProcessResult: CustomStringConvertible, Sendable {
99
123
/// Create an instance using an exit status and output result.
100
124
public init (
101
125
arguments: [ String ] ,
102
- environment: [ String : String ] ,
126
+ environment: ProcessEnvironmentBlock ,
103
127
exitStatus: ExitStatus ,
104
128
output: Result < [ UInt8 ] , Swift . Error > ,
105
129
stderrOutput: Result < [ UInt8 ] , Swift . Error >
@@ -285,7 +309,7 @@ public final class Process {
285
309
public let arguments : [ String ]
286
310
287
311
/// The environment with which the process was executed.
288
- public let environment : [ String : String ]
312
+ public let environment : ProcessEnvironmentBlock
289
313
290
314
/// The path to the directory under which to run the process.
291
315
public let workingDirectory : AbsolutePath ?
@@ -359,7 +383,7 @@ public final class Process {
359
383
@available ( macOS 10 . 15 , * )
360
384
public init (
361
385
arguments: [ String ] ,
362
- environment: [ String : String ] = ProcessEnv . vars,
386
+ environment: ProcessEnvironmentBlock = ProcessEnv . vars,
363
387
workingDirectory: AbsolutePath ,
364
388
outputRedirection: OutputRedirection = . collect,
365
389
startNewProcessGroup: Bool = true ,
@@ -379,7 +403,7 @@ public final class Process {
379
403
@available ( macOS 10 . 15 , * )
380
404
public convenience init (
381
405
arguments: [ String ] ,
382
- environment: [ String : String ] = ProcessEnv . vars,
406
+ environment: ProcessEnvironmentBlock = ProcessEnv . vars,
383
407
workingDirectory: AbsolutePath ,
384
408
outputRedirection: OutputRedirection = . collect,
385
409
verbose: Bool ,
@@ -411,7 +435,7 @@ public final class Process {
411
435
/// - loggingHandler: Handler for logging messages
412
436
public init (
413
437
arguments: [ String ] ,
414
- environment: [ String : String ] = ProcessEnv . vars,
438
+ environment: ProcessEnvironmentBlock = ProcessEnv . vars,
415
439
outputRedirection: OutputRedirection = . collect,
416
440
startNewProcessGroup: Bool = true ,
417
441
loggingHandler: LoggingHandler ? = . none
@@ -428,7 +452,7 @@ public final class Process {
428
452
@available ( * , deprecated, message: " use version without verbosity flag " )
429
453
public convenience init (
430
454
arguments: [ String ] ,
431
- environment: [ String : String ] = ProcessEnv . vars,
455
+ environment: ProcessEnvironmentBlock = ProcessEnv . vars,
432
456
outputRedirection: OutputRedirection = . collect,
433
457
verbose: Bool = Process . verbose,
434
458
startNewProcessGroup: Bool = true
@@ -444,7 +468,7 @@ public final class Process {
444
468
445
469
public convenience init (
446
470
args: String ... ,
447
- environment: [ String : String ] = ProcessEnv . vars,
471
+ environment: ProcessEnvironmentBlock = ProcessEnv . vars,
448
472
outputRedirection: OutputRedirection = . collect,
449
473
loggingHandler: LoggingHandler ? = . none
450
474
) {
@@ -536,7 +560,13 @@ public final class Process {
536
560
process. currentDirectoryURL = workingDirectory. asURL
537
561
}
538
562
process. executableURL = executablePath. asURL
563
+ #if os(Windows)
564
+ process. environment = . init( uniqueKeysWithValues: environment. map {
565
+ ( $0. value, $1)
566
+ } )
567
+ #else
539
568
process. environment = environment
569
+ #endif
540
570
541
571
let stdinPipe = Pipe ( )
542
572
process. standardInput = stdinPipe
@@ -989,7 +1019,7 @@ extension Process {
989
1019
@available ( macOS 10 . 15 , iOS 13 . 0 , tvOS 13 . 0 , watchOS 6 . 0 , * )
990
1020
static public func popen(
991
1021
arguments: [ String ] ,
992
- environment: [ String : String ] = ProcessEnv . vars,
1022
+ environment: ProcessEnvironmentBlock = ProcessEnv . vars,
993
1023
loggingHandler: LoggingHandler ? = . none
994
1024
) async throws -> ProcessResult {
995
1025
let process = Process (
@@ -1012,7 +1042,7 @@ extension Process {
1012
1042
@available ( macOS 10 . 15 , iOS 13 . 0 , tvOS 13 . 0 , watchOS 6 . 0 , * )
1013
1043
static public func popen(
1014
1044
args: String ... ,
1015
- environment: [ String : String ] = ProcessEnv . vars,
1045
+ environment: ProcessEnvironmentBlock = ProcessEnv . vars,
1016
1046
loggingHandler: LoggingHandler ? = . none
1017
1047
) async throws -> ProcessResult {
1018
1048
try await popen ( arguments: args, environment: environment, loggingHandler: loggingHandler)
@@ -1030,7 +1060,7 @@ extension Process {
1030
1060
@discardableResult
1031
1061
static public func checkNonZeroExit(
1032
1062
arguments: [ String ] ,
1033
- environment: [ String : String ] = ProcessEnv . vars,
1063
+ environment: ProcessEnvironmentBlock = ProcessEnv . vars,
1034
1064
loggingHandler: LoggingHandler ? = . none
1035
1065
) async throws -> String {
1036
1066
let result = try await popen ( arguments: arguments, environment: environment, loggingHandler: loggingHandler)
@@ -1053,7 +1083,7 @@ extension Process {
1053
1083
@discardableResult
1054
1084
static public func checkNonZeroExit(
1055
1085
args: String ... ,
1056
- environment: [ String : String ] = ProcessEnv . vars,
1086
+ environment: ProcessEnvironmentBlock = ProcessEnv . vars,
1057
1087
loggingHandler: LoggingHandler ? = . none
1058
1088
) async throws -> String {
1059
1089
try await checkNonZeroExit ( arguments: args, environment: environment, loggingHandler: loggingHandler)
@@ -1075,7 +1105,7 @@ extension Process {
1075
1105
// #endif
1076
1106
static public func popen(
1077
1107
arguments: [ String ] ,
1078
- environment: [ String : String ] = ProcessEnv . vars,
1108
+ environment: ProcessEnvironmentBlock = ProcessEnv . vars,
1079
1109
loggingHandler: LoggingHandler ? = . none,
1080
1110
queue: DispatchQueue ? = nil ,
1081
1111
completion: @escaping ( Result < ProcessResult , Swift . Error > ) -> Void
@@ -1113,7 +1143,7 @@ extension Process {
1113
1143
@discardableResult
1114
1144
static public func popen(
1115
1145
arguments: [ String ] ,
1116
- environment: [ String : String ] = ProcessEnv . vars,
1146
+ environment: ProcessEnvironmentBlock = ProcessEnv . vars,
1117
1147
loggingHandler: LoggingHandler ? = . none
1118
1148
) throws -> ProcessResult {
1119
1149
let process = Process (
@@ -1140,7 +1170,7 @@ extension Process {
1140
1170
@discardableResult
1141
1171
static public func popen(
1142
1172
args: String ... ,
1143
- environment: [ String : String ] = ProcessEnv . vars,
1173
+ environment: ProcessEnvironmentBlock = ProcessEnv . vars,
1144
1174
loggingHandler: LoggingHandler ? = . none
1145
1175
) throws -> ProcessResult {
1146
1176
return try Process . popen ( arguments: args, environment: environment, loggingHandler: loggingHandler)
@@ -1160,7 +1190,7 @@ extension Process {
1160
1190
@discardableResult
1161
1191
static public func checkNonZeroExit(
1162
1192
arguments: [ String ] ,
1163
- environment: [ String : String ] = ProcessEnv . vars,
1193
+ environment: ProcessEnvironmentBlock = ProcessEnv . vars,
1164
1194
loggingHandler: LoggingHandler ? = . none
1165
1195
) throws -> String {
1166
1196
let process = Process (
@@ -1192,7 +1222,7 @@ extension Process {
1192
1222
@discardableResult
1193
1223
static public func checkNonZeroExit(
1194
1224
args: String ... ,
1195
- environment: [ String : String ] = ProcessEnv . vars,
1225
+ environment: ProcessEnvironmentBlock = ProcessEnv . vars,
1196
1226
loggingHandler: LoggingHandler ? = . none
1197
1227
) throws -> String {
1198
1228
return try checkNonZeroExit ( arguments: args, environment: environment, loggingHandler: loggingHandler)
0 commit comments