Skip to content

Refactor task environment IPC to use structured data and semantic hin…#1239

Open
shrudge wants to merge 3 commits into
swiftlang:mainfrom
shrudge:fix-task-environment-ipc
Open

Refactor task environment IPC to use structured data and semantic hin…#1239
shrudge wants to merge 3 commits into
swiftlang:mainfrom
shrudge:fix-task-environment-ipc

Conversation

@shrudge

@shrudge shrudge commented Mar 25, 2026

Copy link
Copy Markdown
Contributor

Refactor task environment IPC to use structured data (#1211)

Motivation

I’m finally putting this up for review after getting sidetracked by some pre-existing noise in BuildOperationTests—mostly visionOS and RealityAssetsCompile errors that seem specific to my local environment.

The main goal here is to stop the server from "baking" environment strings directly into the command log. By sending structured data instead, we move the presentation logic to the client where it belongs and keep the message stream much cleaner.

Modifications

  • IPC Stability: Updated serialization aggregate counts for BuildOperationStarted (1→2) and BuildOperationTaskInfo (7→9).

  • Efficiency: The base environment is now sent once at build start to avoid repeating it for every task.

  • Structured Deltas: Tasks now send a [String: String] dictionary of their specific environment changes.

  • Semantic Hints: Replaced the old boolean with a hint (.normal vs .prominent) so the client can decide when the environment is important enough to show.

Result

The message stream is now more efficient, and the client has full control over how to merge and render environments. I’ve verified the stability with MessageSerializationTests and confirmed the client-side merging in BuildLogTests.

@jakepetroules jakepetroules left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is a good start overall; @owenv what do you think?

let taskSpec = task.type as? Spec
let serializedDiagnosticsPaths = task.type.serializedDiagnosticsInfo(task, operation.requestContext.fs).map(\.serializedDiagnosticsPath)
let info = BuildOperationTaskInfo(taskName: taskSpec?.name ?? "", signature: .taskIdentifier(ByteString(encodingAsUTF8: task.identifier.rawValue)), ruleInfo: task.ruleInfo.quotedDescription, executionDescription: (task.execDescription ?? task.ruleInfo.quotedDescription), commandLineDisplayString: task.showCommandLineInLog ? commandLineDisplayString(task.commandLine.map(\.asByteString), additionalOutput: task.additionalOutput, workingDirectory: task.workingDirectory, environment: environmentToShow, dependencyInfo: dependencyInfo, hostOS: workspaceContext.core.hostOperatingSystem) : nil, interestingPath: interestingPath, serializedDiagnosticsPaths: serializedDiagnosticsPaths)
let info = BuildOperationTaskInfo(taskName: taskSpec?.name ?? "", signature: .taskIdentifier(ByteString(encodingAsUTF8: task.identifier.rawValue)), ruleInfo: task.ruleInfo.quotedDescription, executionDescription: (task.execDescription ?? task.ruleInfo.quotedDescription), commandLineDisplayString: task.showCommandLineInLog ? commandLineDisplayString(task.commandLine.map(\.asByteString), additionalOutput: task.additionalOutput, workingDirectory: task.workingDirectory, environment: nil, dependencyInfo: dependencyInfo, hostOS: workspaceContext.core.hostOperatingSystem) : nil, interestingPath: interestingPath, serializedDiagnosticsPaths: serializedDiagnosticsPaths, taskEnvironment: taskEnvironment, environmentDisplayHint: environmentDisplayHint)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We might want to keep 'environment' as the original value for now to give clients time to transition.

Comment thread Sources/SWBBuildService/BuildOperationMessages.swift Outdated

public init(from deserializer: any Deserializer) throws {
try deserializer.beginAggregate(7)
try deserializer.beginAggregate(9)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we need to find a way to stage this change in so it doesn't break IPC compatibility immediately for out of process clients

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can do let count = try deserializer.beginAggregate(7...9), IIRC, and then use the count value to decide what fields to deserialize.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for these reviews, I will get a patch pushed up shortly.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jakepetroules I went with 7...8 here instead of 7...9 Since we completely dropped the EnvironmentDisplayHint property per the other feedback.

Comment thread Sources/SWBBuildService/BuildOperationMessages.swift Outdated
Comment thread Sources/SWBProtocol/BuildOperationMessages.swift Outdated
@jakepetroules

Copy link
Copy Markdown
Collaborator

@swift-ci test

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants