Skip to content

Commit fb3e1b9

Browse files
committed
review comments
resolve macOS CI compiler crash
1 parent a3adf0e commit fb3e1b9

File tree

2 files changed

+51
-33
lines changed

2 files changed

+51
-33
lines changed

Sources/Basics/Environment/Environment.swift

Lines changed: 47 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,15 @@
1212

1313
import Foundation
1414

15-
#if USE_IMPL_ONLY_IMPORTS
16-
@_implementationOnly import TSCclibc
15+
#if canImport(Glibc)
16+
import Glibc
17+
#elseif canImport(Musl)
18+
import Musl
19+
#elseif os(Windows)
20+
import CRT
21+
import WinSDK
1722
#else
18-
import TSCclibc
23+
import Darwin.C
1924
#endif
2025

2126
// FIXME: Use Synchronization.Mutex when available
@@ -79,7 +84,7 @@ extension Environment {
7984
package mutating func prependPath(key: EnvironmentKey, value: String) {
8085
guard !value.isEmpty else { return }
8186
if let existing = self[key] {
82-
self[key] = "\(value)\(Self.pathValueDelimiter)\(existing)"
87+
self[key] = "\(value)\(Self.pathEntryDelimiter)\(existing)"
8388
} else {
8489
self[key] = value
8590
}
@@ -88,13 +93,13 @@ extension Environment {
8893
package mutating func appendPath(key: EnvironmentKey, value: String) {
8994
guard !value.isEmpty else { return }
9095
if let existing = self[key] {
91-
self[key] = "\(existing)\(Self.pathValueDelimiter)\(value)"
96+
self[key] = "\(existing)\(Self.pathEntryDelimiter)\(value)"
9297
} else {
9398
self[key] = value
9499
}
95100
}
96101

97-
package static var pathValueDelimiter: String {
102+
package static var pathEntryDelimiter: String {
98103
#if os(Windows)
99104
";"
100105
#else
@@ -195,8 +200,32 @@ extension Environment {
195200
///
196201
/// > Important: This operation is _not_ concurrency safe.
197202
package static func set(key: EnvironmentKey, value: String?) throws {
203+
#if os(Windows)
204+
func SetEnvironmentVariableW(_ key: String, _ value: String?) -> Bool {
205+
key.withCString(encodedAs: UTF16.self) { key in
206+
if let value {
207+
value.withCString(encodedAs: UTF16.self) { value in
208+
SetEnvironmentVariableW(key, value)
209+
}
210+
} else {
211+
SetEnvironmentVariableW(key, nil)
212+
}
213+
}
214+
}
215+
#endif
216+
217+
// Invalidate cached value after mutating the global environment.
218+
// This is potentially overly safe because we may not need to invalidate
219+
// the cache if the mutation fails. However this approach is easier to
220+
// read and reason about.
221+
defer { Self._cachedCurrent.withLock { $0 = nil } }
198222
if let value = value {
199223
#if os(Windows)
224+
guard SetEnvironmentVariableW(key.rawValue, value) else {
225+
throw UpdateEnvironmentError(
226+
function: "SetEnvironmentVariableW",
227+
code: Int32(GetLastError()))
228+
}
200229
guard _putenv("\(key)=\(value)") == 0 else {
201230
throw UpdateEnvironmentError(
202231
function: "_putenv",
@@ -211,6 +240,11 @@ extension Environment {
211240
#endif
212241
} else {
213242
#if os(Windows)
243+
guard SetEnvironmentVariableW(key.rawValue, nil) else {
244+
throw UpdateEnvironmentError(
245+
function: "SetEnvironmentVariableW",
246+
code: Int32(GetLastError()))
247+
}
214248
guard _putenv("\(key)=") == 0 else {
215249
throw UpdateEnvironmentError(
216250
function: "_putenv",
@@ -224,7 +258,6 @@ extension Environment {
224258
}
225259
#endif
226260
}
227-
Self._cachedCurrent.withLock { $0 = nil }
228261
}
229262
}
230263

@@ -254,9 +287,6 @@ extension Environment: Collection {
254287
var underlying: Dictionary<EnvironmentKey, String>.Index
255288
}
256289
public typealias Element = (key: EnvironmentKey, value: String)
257-
// FIXME: Remove after upgrading past Swift 5.9
258-
// Required to be explicitly spelled out on older Swift compilers.
259-
public typealias Iterator = IndexingIterator<Self>
260290

261291
public var startIndex: Index {
262292
Index(underlying: self.storage.startIndex)
@@ -266,8 +296,8 @@ extension Environment: Collection {
266296
Index(underlying: self.storage.endIndex)
267297
}
268298

269-
public subscript(index: Index) -> Iterator.Element {
270-
get { self.storage[index.underlying] }
299+
public subscript(index: Index) -> Element {
300+
self.storage[index.underlying]
271301
}
272302

273303
public func index(after index: Self.Index) -> Self.Index {
@@ -277,23 +307,11 @@ extension Environment: Collection {
277307

278308
extension Environment: CustomStringConvertible {
279309
public var description: String {
280-
var description = "["
281-
let sorted = self.sorted { $0.key < $1.key }
282-
var first = true
283-
for (key, value) in sorted {
284-
if first {
285-
first = false
286-
} else {
287-
description.append(", ")
288-
}
289-
description.append("\"")
290-
description.append(key.rawValue)
291-
description.append("=")
292-
description.append(value)
293-
description.append("\"")
294-
}
295-
description.append("]")
296-
return description
310+
let body = self
311+
.sorted { $0.key < $1.key }
312+
.map { #""\#($0.rawValue)"="\#($1)""# }
313+
.joined(separator: ", ")
314+
return "[\(body)]"
297315
}
298316
}
299317

Tests/BasicsTests/Environment/EnvironmentTests.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ final class EnvironmentTests: XCTestCase {
4747
}
4848

4949
func path(_ components: String...) -> String {
50-
components.joined(separator: Environment.pathValueDelimiter)
50+
components.joined(separator: Environment.pathEntryDelimiter)
5151
}
5252

5353
func test_prependPath() {
@@ -86,11 +86,11 @@ final class EnvironmentTests: XCTestCase {
8686
XCTAssertEqual(environment[key], path("/bin", "/usr/bin", "/usr/local/bin"))
8787
}
8888

89-
func test_pathValueDelimiter() {
89+
func test_pathEntryDelimiter() {
9090
#if os(Windows)
91-
XCTAssertEqual(Environment.pathValueDelimiter, ";")
91+
XCTAssertEqual(Environment.pathEntryDelimiter, ";")
9292
#else
93-
XCTAssertEqual(Environment.pathValueDelimiter, ":")
93+
XCTAssertEqual(Environment.pathEntryDelimiter, ":")
9494
#endif
9595
}
9696

0 commit comments

Comments
 (0)