Skip to content

Commit ac59c04

Browse files
authored
Ensure environment variables defined in specs are loaded in a deterministic order (swiftlang#29)
Otherwise, tasks signatures may change across relauncghes of the build service and cause rebuilds. rdar://141252371
1 parent d05f70d commit ac59c04

File tree

2 files changed

+9
-2
lines changed

2 files changed

+9
-2
lines changed

Sources/SWBCore/Specs/CommandLineToolSpec.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,7 @@ open class CommandLineToolSpec : PropertyDomainSpec, SpecType, TaskTypeDescripti
327327
@_spi(Testing) public let outputs: [MacroStringExpression]?
328328

329329
/// The additional environment variables to provide to instances of the tool.
330-
let environmentVariables: [(String, MacroStringExpression)]?
330+
@_spi(Testing) public let environmentVariables: [(String, MacroStringExpression)]?
331331

332332
/// The path of the additional "generated Info.plist" content, if used.
333333
let generatedInfoPlistContent: MacroStringExpression?
@@ -547,7 +547,7 @@ open class CommandLineToolSpec : PropertyDomainSpec, SpecType, TaskTypeDescripti
547547
if let envVariables = parser.parseObject("EnvironmentVariables", inherited: false) {
548548
if case .plDict(let items) = envVariables {
549549
var variables: [(String, MacroStringExpression)] = []
550-
for (key,valueData) in items {
550+
for (key,valueData) in items.sorted(by: \.0) {
551551
guard case .plString(let value) = valueData else {
552552
parser.error("invalid value for '\(key)' key in 'EnvironmentVariables' (expected string)")
553553
continue

Tests/SWBCoreTests/SpecLoadingTests.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -884,6 +884,13 @@ import SWBMacro
884884
XCTAssertMatch(errors[0], .prefix("unexpected item: \"arm64e\" while parsing key Architectures"))
885885
}
886886

887+
@Test
888+
func environmentVariableConsistentOrdering() async throws {
889+
let core = try await getCore()
890+
let migSpec: CompilerSpec = try core.specRegistry.getSpec("com.apple.compilers.mig") as CompilerSpec
891+
#expect(migSpec.environmentVariables?.map({ $0.0 }) == ["DEVELOPER_DIR", "SDKROOT", "TOOLCHAINS"])
892+
}
893+
887894
/// Test that loading concrete compiler specs in our Xcode install work as expected.
888895
@Test
889896
func concreteCompilerSpecLoading() async throws {

0 commit comments

Comments
 (0)