@@ -361,8 +361,8 @@ extension Arguments: CustomStringConvertible, CustomDebugStringConvertible {
361
361
/// A set of environment variables to use when executing the subprocess.
362
362
public struct Environment : Sendable , Hashable {
363
363
internal enum Configuration : Sendable , Hashable {
364
- case inherit( [ String : String ] )
365
- case custom( [ String : String ] )
364
+ case inherit( [ EnvironmentKey : String ] )
365
+ case custom( [ EnvironmentKey : String ] )
366
366
#if !os(Windows)
367
367
case rawBytes( [ [ UInt8 ] ] )
368
368
#endif
@@ -379,11 +379,11 @@ public struct Environment: Sendable, Hashable {
379
379
return . init( config: . inherit( [ : ] ) )
380
380
}
381
381
/// Override the provided `newValue` in the existing `Environment`
382
- public func updating( _ newValue: [ String : String ] ) -> Self {
382
+ public func updating( _ newValue: [ EnvironmentKey : String ] ) -> Self {
383
383
return . init( config: . inherit( newValue) )
384
384
}
385
385
/// Use custom environment variables
386
- public static func custom( _ newValue: [ String : String ] ) -> Self {
386
+ public static func custom( _ newValue: [ EnvironmentKey : String ] ) -> Self {
387
387
return . init( config: . custom( newValue) )
388
388
}
389
389
@@ -424,9 +424,9 @@ extension Environment: CustomStringConvertible, CustomDebugStringConvertible {
424
424
return self . description
425
425
}
426
426
427
- internal static func currentEnvironmentValues( ) -> [ String : String ] {
427
+ internal static func currentEnvironmentValues( ) -> [ EnvironmentKey : String ] {
428
428
return self . withCopiedEnv { environments in
429
- var results : [ String : String ] = [ : ]
429
+ var results : [ EnvironmentKey : String ] = [ : ]
430
430
for env in environments {
431
431
let environmentString = String ( cString: env)
432
432
@@ -448,13 +448,87 @@ extension Environment: CustomStringConvertible, CustomDebugStringConvertible {
448
448
let value = String (
449
449
environmentString [ environmentString. index ( after: delimiter) ..< environmentString. endIndex]
450
450
)
451
- results [ key] = value
451
+ results [ EnvironmentKey ( key) ] = value
452
452
}
453
453
return results
454
454
}
455
455
}
456
456
}
457
457
458
+ /// A key used to access values in an ``Environment``.
459
+ ///
460
+ /// This type respects the compiled platform's case sensitivity requirements.
461
+ public struct EnvironmentKey {
462
+ public var rawValue : String
463
+
464
+ package init ( _ rawValue: String ) {
465
+ self . rawValue = rawValue
466
+ }
467
+ }
468
+
469
+ extension EnvironmentKey {
470
+ package static let path : Self = " PATH "
471
+ }
472
+
473
+ extension EnvironmentKey : CodingKeyRepresentable { }
474
+
475
+ extension EnvironmentKey : Comparable {
476
+ public static func < ( lhs: Self , rhs: Self ) -> Bool {
477
+ // Even on windows use a stable sort order.
478
+ lhs. rawValue < rhs. rawValue
479
+ }
480
+ }
481
+
482
+ extension EnvironmentKey : CustomStringConvertible {
483
+ public var description : String { self . rawValue }
484
+ }
485
+
486
+ extension EnvironmentKey : Encodable {
487
+ public func encode( to encoder: any Swift . Encoder ) throws {
488
+ try self . rawValue. encode ( to: encoder)
489
+ }
490
+ }
491
+
492
+ extension EnvironmentKey : Equatable {
493
+ public static func == ( _ lhs: Self , _ rhs: Self ) -> Bool {
494
+ #if os(Windows)
495
+ lhs. rawValue. lowercased ( ) == rhs. rawValue. lowercased ( )
496
+ #else
497
+ lhs. rawValue == rhs. rawValue
498
+ #endif
499
+ }
500
+ }
501
+
502
+ extension EnvironmentKey : ExpressibleByStringLiteral {
503
+ public init ( stringLiteral rawValue: String ) {
504
+ self . init ( rawValue)
505
+ }
506
+ }
507
+
508
+ extension EnvironmentKey : Decodable {
509
+ public init ( from decoder: any Swift . Decoder ) throws {
510
+ self . rawValue = try String ( from: decoder)
511
+ }
512
+ }
513
+
514
+ extension EnvironmentKey : Hashable {
515
+ public func hash( into hasher: inout Hasher ) {
516
+ #if os(Windows)
517
+ self . rawValue. lowercased ( ) . hash ( into: & hasher)
518
+ #else
519
+ self . rawValue. hash ( into: & hasher)
520
+ #endif
521
+ }
522
+ }
523
+
524
+ extension EnvironmentKey : RawRepresentable {
525
+ public init ? ( rawValue: String ) {
526
+ self . rawValue = rawValue
527
+ }
528
+ }
529
+
530
+ extension EnvironmentKey : Sendable { }
531
+
458
532
// MARK: - TerminationStatus
459
533
460
534
/// An exit status of a subprocess.
0 commit comments