-
Notifications
You must be signed in to change notification settings - Fork 17
/
Copy pathmain.swift
134 lines (120 loc) · 7.18 KB
/
main.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
import BKBuildService
import Foundation
import XCBProtocol
import BEP
struct BasicMessageContext {
let xcbbuildService: XCBBuildServiceProcess
let bkservice: BKBuildService
let indexingService: IndexingService
let bepService: BEPService
}
/// This example listens to a BEP stream to display some output.
///
/// All operations are delegated to XCBBuildService and we inject
/// progress from BEP.
enum BasicMessageHandler {
/// Proxying response handler
/// Every message is written to the XCBBuildService
/// This simply injects Progress messages from the BEP
static func respond(input: XCBInputStream, data: Data, msgId: UInt64, context: Any?) {
let ctx = context as! BasicMessageContext
let xcbbuildService = ctx.xcbbuildService
let bkservice = ctx.bkservice
let indexingService = ctx.indexingService
let bepService = ctx.bepService
let decoder = XCBDecoder(input: input)
let encoder = XCBEncoder(input: input, msgId: msgId)
let identifier = input.identifier ?? ""
if let msg = decoder.decodeMessage() {
if let createSessionRequest = msg as? CreateSessionRequest {
// Initialize workspace info for the current workspace
let workspaceInfo = WorkspaceInfo(
xcode: createSessionRequest.xcode,
workspaceName: createSessionRequest.workspaceName,
workspaceHash: createSessionRequest.workspaceHash,
xcodeprojPath: createSessionRequest.xcodeprojPath
)
indexingService.infos[createSessionRequest.workspaceKey] = workspaceInfo
log("[INFO] Loaded xcbuildkit config: \(workspaceInfo.config)")
// Initialize build service
xcbbuildService.startIfNecessary(xcode: workspaceInfo.xcode)
// Initialize indexing information
indexingService.initializeOutputFileMappingFromCache(msg: createSessionRequest)
} else if msg is BuildStartRequest {
let message = BuildProgressUpdatedResponse()
if let responseData = try? message.encode(encoder) {
bkservice.write(responseData)
}
} else if let createBuildRequest = msg as? CreateBuildRequest, let workspaceInfo = indexingService.infos[createBuildRequest.workspaceKey] {
log("[INFO] Creating build with config: \(workspaceInfo.config)")
// Start streaming from the BEP
if let bepPath = workspaceInfo.config.configBEPPath {
do {
try bepService.startStream(msg: createBuildRequest, bepPath: bepPath, startBuildInput: input, msgId: msgId, ctx: ctx)
} catch {
log("[ERROR] Failed to start BEP stream with error: " + error.localizedDescription)
}
} else {
log("[WARNING] BEP string config key 'BUILD_SERVICE_BEP_PATH' empty. Bazel information won't be available during a build.")
}
// This information was not explicitly available in `CreateSessionRequest`, parse from `CreateBuildRequest` instead
// Necessary for indexing and potentially for other things in the future. This is effectively $SRCROOT.
workspaceInfo.workingDir = createBuildRequest.workingDir
workspaceInfo.derivedDataPath = createBuildRequest.derivedDataPath
workspaceInfo.indexDataStoreFolderPath = createBuildRequest.indexDataStoreFolderPath
workspaceInfo.targetConfiguration = createBuildRequest.configuration
// Attempt to initialize in-memory mapping if empty
// It's possible that indexing data is not ready yet in `CreateSessionRequest` above
if workspaceInfo.outputFileForSource.count == 0 {
indexingService.initializeOutputFileMappingFromCache(msg: createBuildRequest)
}
// Setup DataStore for indexing with Bazel
indexingService.setupDataStore(msg: createBuildRequest)
} else if let indexingInfoRequest = msg as? IndexingInfoRequested,
let sourceMapInfo = indexingService.indexingSourceMapInfo(msg: indexingInfoRequest),
let workspaceInfo = indexingService.infos[indexingInfoRequest.workspaceKey] {
// Compose the indexing response payload and emit the response message
// Note that information is combined from different places (workspace info, incoming indexing request, indexing service helper methods)
let compilerInvocationData = BazelBuildServiceStub.getASTArgs(
isSwift: indexingInfoRequest.filePath.hasSuffix(".swift"),
targetID: indexingInfoRequest.targetID,
xcode: workspaceInfo.xcode,
sourceFilePath: indexingInfoRequest.filePath,
outputFilePath: sourceMapInfo.outputFilePath,
derivedDataPath: workspaceInfo.derivedDataPath,
workspaceHash: workspaceInfo.workspaceHash,
workspaceName: workspaceInfo.workspaceName,
sdkPath: ctx.indexingService.sdkPath(msg: indexingInfoRequest),
sdkName: indexingInfoRequest.sdk,
defaultWorkingDir: workspaceInfo.workingDir,
bazelWorkingDir: workspaceInfo.config.bazelWorkingDir,
configuration: workspaceInfo.targetConfiguration,
platform: indexingInfoRequest.platform,
cmdLineArgs: sourceMapInfo.cmdLineArgs)
let message = IndexingInfoReceivedResponse(
targetID: indexingInfoRequest.targetID,
data: indexingInfoRequest.outputPathOnly ? BazelBuildServiceStub.outputPathOnlyData(outputFilePath: sourceMapInfo.outputFilePath, sourceFilePath: indexingInfoRequest.filePath, workingDir: workspaceInfo.workingDir, bazelWorkingDir: workspaceInfo.config.bazelWorkingDir) : nil,
responseChannel: UInt64(indexingInfoRequest.responseChannel),
compilerInvocationData: indexingInfoRequest.outputPathOnly ? nil : compilerInvocationData)
if let encoded: XCBResponse = try? message.encode(encoder) {
bkservice.write(encoded, msgId:message.responseChannel)
log("[INFO] Handling \(identifier) [outputPathOnly=\(indexingInfoRequest.outputPathOnly)] for source \(indexingInfoRequest.filePath) and output file \(sourceMapInfo.outputFilePath)")
return
}
}
}
log("[INFO] Proxying request with type: \(identifier)")
xcbbuildService.write(data)
}
}
let xcbbuildService = XCBBuildServiceProcess()
let bkservice = BKBuildService()
let indexingService = IndexingService()
let bepService = BEPService()
let context = BasicMessageContext(
xcbbuildService: xcbbuildService,
bkservice: bkservice,
indexingService: indexingService,
bepService: bepService
)
bkservice.start(messageHandler: BasicMessageHandler.respond, context: context)