Skip to content

Commit 91355b6

Browse files
committed
Fix environment related warnings
1 parent 363fadf commit 91355b6

Some content is hidden

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

45 files changed

+187
-155
lines changed

Sources/Basics/EnvironmentVariables.swift

Lines changed: 52 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -10,61 +10,59 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13+
import Foundation
1314
import class Foundation.ProcessInfo
15+
import struct TSCBasic.ProcessEnvironmentBlock
16+
import struct TSCBasic.ProcessEnvironmentKey
17+
import enum TSCBasic.ProcessEnv
1418

15-
public typealias EnvironmentVariables = [String: String]
19+
public typealias ProcessEnvironmentBlock = TSCBasic.ProcessEnvironmentBlock
1620

17-
extension EnvironmentVariables {
18-
public static func empty() -> EnvironmentVariables {
19-
[:]
20-
}
21-
22-
public static func process() -> EnvironmentVariables {
23-
ProcessInfo.processInfo.environment
24-
}
21+
extension ProcessEnvironmentBlock {
22+
public static var current: ProcessEnvironmentBlock { ProcessEnv.block }
2523

26-
public mutating func prependPath(_ key: String, value: String) {
27-
var values = value.isEmpty ? [] : [value]
28-
if let existing = self[key], !existing.isEmpty {
29-
values.append(existing)
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
3029
}
31-
self.setPath(key, values)
3230
}
3331

34-
public mutating func appendPath(_ key: String, value: String) {
35-
var values = value.isEmpty ? [] : [value]
36-
if let existing = self[key], !existing.isEmpty {
37-
values.insert(existing, at: 0)
32+
public mutating func appendPath(value: String) {
33+
if let existing = self[Self.pathKey] {
34+
self[Self.pathKey] = "\(existing):\(value)"
35+
} else {
36+
self[Self.pathKey] = value
3837
}
39-
self.setPath(key, values)
4038
}
4139

42-
private mutating func setPath(_ key: String, _ values: [String]) {
40+
/// `PATH` variable in the process's environment (`Path` under Windows).
41+
package var path: String? { self[Self.pathKey] }
42+
43+
package static var pathValueDelimiter: String {
4344
#if os(Windows)
44-
let delimiter = ";"
45+
";"
4546
#else
46-
let delimiter = ":"
47+
":"
4748
#endif
48-
self[key] = values.joined(separator: delimiter)
4949
}
5050

51-
/// `PATH` variable in the process's environment (`Path` under Windows).
52-
public var path: String? {
51+
package static var pathKey: ProcessEnvironmentKey {
5352
#if os(Windows)
54-
let pathArg = "Path"
53+
"Path"
5554
#else
56-
let pathArg = "PATH"
55+
"PATH"
5756
#endif
58-
return self[pathArg]
5957
}
6058
}
6159

6260
// filter env variable that should not be included in a cache as they change
6361
// often and should not be considered in business logic
6462
// rdar://107029374
65-
extension EnvironmentVariables {
63+
extension ProcessEnvironmentBlock {
6664
// internal for testing
67-
static let nonCachableKeys: Set<String> = [
65+
static let nonCachableKeys: Set<ProcessEnvironmentKey> = [
6866
"TERM",
6967
"TERM_PROGRAM",
7068
"TERM_PROGRAM_VERSION",
@@ -82,7 +80,29 @@ extension EnvironmentVariables {
8280
"SSH_AUTH_SOCK",
8381
]
8482

85-
public var cachable: EnvironmentVariables {
86-
return self.filter { !Self.nonCachableKeys.contains($0.key) }
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) }
86+
}
87+
}
88+
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
97+
}
98+
}
99+
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
87107
}
88108
}

Sources/Basics/FileSystem/FileSystem+Extensions.swift

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

2728
public typealias FileSystem = TSCBasic.FileSystem
2829
public let localFileSystem = TSCBasic.localFileSystem
@@ -214,7 +215,7 @@ extension FileSystem {
214215
/// or under $XDG_CONFIG_HOME/swiftpm if the environmental variable is defined
215216
public var dotSwiftPM: AbsolutePath {
216217
get throws {
217-
if let configurationDirectory = EnvironmentVariables.process()["XDG_CONFIG_HOME"] {
218+
if let configurationDirectory = ProcessEnv.block["XDG_CONFIG_HOME"] {
218219
return try AbsolutePath(validating: configurationDirectory).appending("swiftpm")
219220
} else {
220221
return try self.homeDirectory.appending(".swiftpm")

Sources/Basics/ImportScanning.swift

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

1515
import class Foundation.JSONDecoder
1616
import class TSCBasic.Process
17+
import struct TSCBasic.ProcessEnvironmentBlock
1718

1819
private let defaultImports = ["Swift", "SwiftOnoneSupport", "_Concurrency",
1920
"_StringProcessing", "_SwiftConcurrencyShims"]
@@ -27,12 +28,12 @@ public protocol ImportScanner {
2728
}
2829

2930
public struct SwiftcImportScanner: ImportScanner {
30-
private let swiftCompilerEnvironment: EnvironmentVariables
31+
private let swiftCompilerEnvironment: ProcessEnvironmentBlock
3132
private let swiftCompilerFlags: [String]
3233
private let swiftCompilerPath: AbsolutePath
3334

3435
public init(
35-
swiftCompilerEnvironment: EnvironmentVariables,
36+
swiftCompilerEnvironment: ProcessEnvironmentBlock,
3637
swiftCompilerFlags: [String],
3738
swiftCompilerPath: AbsolutePath
3839
) {
@@ -46,7 +47,7 @@ public struct SwiftcImportScanner: ImportScanner {
4647
filePathToScan.pathString,
4748
"-scan-dependencies", "-Xfrontend", "-import-prescan"] + self.swiftCompilerFlags
4849

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

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

Sources/Build/BuildManifest/LLBuildManifestBuilder+Swift.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import struct PackageGraph.ResolvedModule
2121
import protocol TSCBasic.FileSystem
2222
import enum TSCBasic.ProcessEnv
2323
import func TSCBasic.topologicalSort
24+
import struct Basics.ProcessEnvironmentBlock
2425

2526
#if USE_IMPL_ONLY_IMPORTS
2627
@_implementationOnly import class DriverSupport.SPMSwiftDriverExecutor
@@ -75,7 +76,7 @@ extension LLBuildManifestBuilder {
7576
let executor = SPMSwiftDriverExecutor(
7677
resolver: resolver,
7778
fileSystem: target.fileSystem,
78-
env: ProcessEnv.vars
79+
env: ProcessEnvironmentBlock.current
7980
)
8081
var driver = try Driver(
8182
args: commandLine,
@@ -290,7 +291,7 @@ extension LLBuildManifestBuilder {
290291
let executor = SPMSwiftDriverExecutor(
291292
resolver: resolver,
292293
fileSystem: self.fileSystem,
293-
env: ProcessEnv.vars
294+
env: ProcessEnvironmentBlock.current
294295
)
295296
var driver = try Driver(
296297
args: commandLine,

Sources/Build/BuildOperation.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS
227227
let resolver = try ArgsResolver(fileSystem: localFileSystem)
228228
let executor = SPMSwiftDriverExecutor(resolver: resolver,
229229
fileSystem: localFileSystem,
230-
env: ProcessEnv.vars)
230+
env: ProcessEnvironmentBlock.current)
231231

232232
let consumeDiagnostics: DiagnosticsEngine = DiagnosticsEngine(handlers: [])
233233
var driver = try Driver(args: commandLine,
@@ -465,7 +465,7 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS
465465
self.preparationStepName = preparationStepName
466466
self.progressTracker = progressTracker
467467
}
468-
func willCompilePlugin(commandLine: [String], environment: EnvironmentVariables) {
468+
func willCompilePlugin(commandLine: [String], environment: ProcessEnvironmentBlock) {
469469
self.progressTracker?.preparationStepStarted(preparationStepName)
470470
}
471471
func didCompilePlugin(result: PluginCompilationResult) {
@@ -824,7 +824,7 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS
824824
if !pluginConfiguration.disableSandbox {
825825
commandLine = try Sandbox.apply(command: commandLine, fileSystem: self.fileSystem, strictness: .writableTemporaryDirectory, writableDirectories: [pluginResult.pluginOutputDirectory])
826826
}
827-
let processResult = try Process.popen(arguments: commandLine, environment: command.configuration.environment)
827+
let processResult = try Process.popen(arguments: commandLine, environmentBlock: command.configuration.environment)
828828
let output = try processResult.utf8Output() + processResult.utf8stderrOutput()
829829
if processResult.exitStatus != .terminated(code: 0) {
830830
throw StringError("failed: \(command)\n\n\(output)")

Sources/Build/LLBuildCommands.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,7 @@ final class PackageStructureCommand: CustomLLBuildCommand {
380380
var hash = Data()
381381
hash += try! encoder.encode(self.context.productsBuildParameters)
382382
hash += try! encoder.encode(self.context.toolsBuildParameters)
383-
hash += try! encoder.encode(ProcessEnv.vars)
383+
hash += try! encoder.encode(ProcessEnvironmentBlock.current)
384384
return [UInt8](hash)
385385
}
386386

Sources/Commands/PackageCommands/InstalledPackages.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ extension SwiftPackageCommand {
3232
func run(_ tool: SwiftCommandState) throws {
3333
let swiftpmBinDir = try tool.fileSystem.getOrCreateSwiftPMInstalledBinariesDirectory()
3434

35-
let env = ProcessInfo.processInfo.environment
35+
let env = ProcessEnvironmentBlock.current
3636

3737
if let path = env.path, !path.contains(swiftpmBinDir.pathString), !globalOptions.logging.quiet {
3838
tool.observabilityScope.emit(

Sources/Commands/SwiftTestCommand.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -788,7 +788,7 @@ final class TestRunner {
788788
// The toolchain to use.
789789
private let toolchain: UserToolchain
790790

791-
private let testEnv: [String: String]
791+
private let testEnv: ProcessEnvironmentBlock
792792

793793
/// ObservabilityScope to emit diagnostics.
794794
private let observabilityScope: ObservabilityScope
@@ -822,7 +822,7 @@ final class TestRunner {
822822
additionalArguments: [String],
823823
cancellator: Cancellator,
824824
toolchain: UserToolchain,
825-
testEnv: [String: String],
825+
testEnv: ProcessEnvironmentBlock,
826826
observabilityScope: ObservabilityScope,
827827
library: BuildParameters.Testing.Library
828828
) {
@@ -880,7 +880,7 @@ final class TestRunner {
880880
stdout: outputHandler,
881881
stderr: outputHandler
882882
)
883-
let process = TSCBasic.Process(arguments: try args(forTestAt: path), environment: self.testEnv, outputRedirection: outputRedirection)
883+
let process = TSCBasic.Process(arguments: try args(forTestAt: path), environmentBlock: self.testEnv, outputRedirection: outputRedirection)
884884
guard let terminationKey = self.cancellator.register(process) else {
885885
return false // terminating
886886
}

Sources/Commands/Utilities/PluginDelegate.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ final class PluginDelegate: PluginInvocationDelegate {
3232
self.lineBufferedOutput = Data()
3333
}
3434

35-
func pluginCompilationStarted(commandLine: [String], environment: EnvironmentVariables) {
35+
func pluginCompilationStarted(commandLine: [String], environment: ProcessEnvironmentBlock) {
3636
}
3737

3838
func pluginCompilationEnded(result: PluginCompilationResult) {
@@ -430,7 +430,7 @@ final class PluginDelegate: PluginInvocationDelegate {
430430
guard let package = packageGraph.package(for: target) else {
431431
throw StringError("could not determine the package for target “\(target.name)")
432432
}
433-
let outputDir = try buildParameters.dataPath.appending(
433+
let outputDir = buildParameters.dataPath.appending(
434434
components: "extracted-symbols",
435435
package.identity.description,
436436
target.name

Sources/Commands/Utilities/TestingSupport.swift

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ enum TestingSupport {
125125
library: .xctest
126126
)
127127

128-
try TSCBasic.Process.checkNonZeroExit(arguments: args, environment: env)
128+
try TSCBasic.Process.checkNonZeroExit(arguments: args, environmentBlock: env)
129129
// Read the temporary file's content.
130130
return try swiftCommandState.fileSystem.readFileContents(AbsolutePath(tempFile.path))
131131
}
@@ -153,8 +153,8 @@ enum TestingSupport {
153153
destinationBuildParameters buildParameters: BuildParameters,
154154
sanitizers: [Sanitizer],
155155
library: BuildParameters.Testing.Library
156-
) throws -> EnvironmentVariables {
157-
var env = EnvironmentVariables.process()
156+
) throws -> ProcessEnvironmentBlock {
157+
var env = ProcessEnvironmentBlock.current
158158

159159
// If the standard output or error stream is NOT a TTY, set the NO_COLOR
160160
// environment variable. This environment variable is a de facto
@@ -191,8 +191,9 @@ enum TestingSupport {
191191
// Add the sdk platform path if we have it.
192192
if let sdkPlatformFrameworksPath = try? SwiftSDK.sdkPlatformFrameworkPaths() {
193193
// appending since we prefer the user setting (if set) to the one we inject
194-
env.appendPath("DYLD_FRAMEWORK_PATH", value: sdkPlatformFrameworksPath.fwk.pathString)
195-
env.appendPath("DYLD_LIBRARY_PATH", value: sdkPlatformFrameworksPath.lib.pathString)
194+
// FIXME: Rauhul
195+
// env.appendPath("DYLD_FRAMEWORK_PATH", value: sdkPlatformFrameworksPath.fwk.pathString)
196+
// env.appendPath("DYLD_LIBRARY_PATH", value: sdkPlatformFrameworksPath.lib.pathString)
196197
}
197198

198199
// Fast path when no sanitizers are enabled.

Sources/CoreCommands/SwiftCommandState.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ public final class SwiftCommandState {
265265

266266
fileprivate var buildSystemProvider: BuildSystemProvider?
267267

268-
private let environment: EnvironmentVariables
268+
private let environment: ProcessEnvironmentBlock
269269

270270
private let hostTriple: Basics.Triple?
271271

@@ -301,7 +301,7 @@ public final class SwiftCommandState {
301301
workspaceLoaderProvider: @escaping WorkspaceLoaderProvider,
302302
hostTriple: Basics.Triple? = nil,
303303
fileSystem: any FileSystem = localFileSystem,
304-
environment: EnvironmentVariables = ProcessEnv.vars
304+
environment: ProcessEnvironmentBlock = .current
305305
) throws {
306306
self.hostTriple = hostTriple
307307
self.fileSystem = fileSystem

Sources/DriverSupport/DriverSupportUtils.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ public enum DriverSupport {
6868
do {
6969
let helpJob = try Process.launchProcess(
7070
arguments: [swiftcPathString, "-h"],
71-
env: ProcessEnv.vars
71+
env: ProcessEnvironmentBlock.current.nonPortable()
7272
)
7373
let processResult = try helpJob.waitUntilExit()
7474
guard processResult.exitStatus == .terminated(code: 0) else {

Sources/DriverSupport/SPMSwiftDriverExecutor.swift

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,11 @@ public final class SPMSwiftDriverExecutor: DriverExecutor {
3131

3232
public let resolver: ArgsResolver
3333
let fileSystem: FileSystem
34-
let env: EnvironmentVariables
35-
34+
let env: ProcessEnvironmentBlock
35+
3636
public init(resolver: ArgsResolver,
3737
fileSystem: FileSystem,
38-
env: EnvironmentVariables) {
38+
env: ProcessEnvironmentBlock) {
3939
self.resolver = resolver
4040
self.fileSystem = fileSystem
4141
self.env = env
@@ -54,7 +54,11 @@ public final class SPMSwiftDriverExecutor: DriverExecutor {
5454
throw Error.inPlaceExecutionUnsupported
5555
}
5656

57-
var childEnv = env
57+
58+
var childEnv = [String: String]()
59+
for (key, value) in env {
60+
childEnv[key.value] = value
61+
}
5862
childEnv.merge(job.extraEnvironment, uniquingKeysWith: { (_, new) in new })
5963

6064
let process = try Process.launchProcess(arguments: arguments, env: childEnv)

Sources/LLBuildManifest/LLBuildManifest.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,7 @@ public struct LLBuildManifest {
336336
inputs: [Node],
337337
outputs: [Node],
338338
arguments: [String],
339-
environment: EnvironmentVariables = .empty(),
339+
environment: ProcessEnvironmentBlock = [:],
340340
workingDirectory: String? = nil,
341341
allowMissingInputs: Bool = false
342342
) {

Sources/LLBuildManifest/LLBuildManifestWriter.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,16 @@ public struct ManifestToolStream {
193193
}
194194
}
195195
}
196+
197+
public subscript(key: String) -> ProcessEnvironmentBlock {
198+
get { fatalError() }
199+
set {
200+
self.buffer += " \(key):\n"
201+
for (key, value) in newValue.sorted(by: { $0.key.value < $1.key.value }) {
202+
self.buffer += " \(key.value.asJSON): \(value.asJSON)\n"
203+
}
204+
}
205+
}
196206
}
197207

198208
extension [String] {

0 commit comments

Comments
 (0)