Skip to content

Commit 6925afe

Browse files
committed
Allow overriding the workspace buildsystem per workspace
Merge options prior to determining the buildsystem to use for a workspace, rather than after. Also fix up a few workspace type comments which referred to the shorthand names.
1 parent bb13147 commit 6925afe

File tree

4 files changed

+80
-14
lines changed

4 files changed

+80
-14
lines changed

Documentation/Configuration File.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ The structure of the file is currently not guaranteed to be stable. Options may
4343
- `logLevel: "debug"|"info"|"default"|"error"|"fault"`: The level from which one onwards log messages should be written.
4444
- `privacyLevel: "public"|"private"|"sensitive"`: Whether potentially sensitive information should be redacted. Default is `public`, which redacts potentially sensitive information.
4545
- `inputMirrorDirectory: string`: Write all input received by SourceKit-LSP on stdin to a file in this directory. Useful to record and replay an entire SourceKit-LSP session.
46-
- `defaultWorkspaceType: "buildserver"|"compdb"|"swiftpm"`: Overrides workspace type selection logic.
46+
- `defaultWorkspaceType: "swiftPM"|"compilationDatabase"|"buildServer"`: Overrides workspace type selection logic.
4747
- `generatedFilesPath: string`: Directory in which generated interfaces and macro expansions should be stored.
4848
- `backgroundIndexing: bool`: Explicitly enable or disable background indexing.
4949
- `backgroundPreparationMode: "build"|"noLazy"|"enabled"`: Determines how background indexing should prepare a target. Possible values are:

Sources/SKOptions/SourceKitLSPOptions.swift

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,7 @@ public struct SourceKitLSPOptions: Sendable, Codable, Equatable {
280280
set { logging = newValue }
281281
}
282282

283-
/// Default workspace type (buildserver|compdb|swiftpm). Overrides workspace type selection logic.
283+
/// Default workspace type (swiftPM|compilationDatabase|buildServer). Overrides workspace type selection logic.
284284
public var defaultWorkspaceType: WorkspaceType?
285285
public var generatedFilesPath: String?
286286

@@ -444,6 +444,17 @@ public struct SourceKitLSPOptions: Sendable, Codable, Equatable {
444444
)
445445
}
446446

447+
public static func merging(base: SourceKitLSPOptions, workspaceFolder: DocumentURI) -> SourceKitLSPOptions {
448+
return SourceKitLSPOptions.merging(
449+
base: base,
450+
override: SourceKitLSPOptions(
451+
path: workspaceFolder.fileURL?
452+
.appendingPathComponent(".sourcekit-lsp")
453+
.appendingPathComponent("config.json")
454+
)
455+
)
456+
}
457+
447458
public var generatedFilesAbsolutePath: URL {
448459
if let generatedFilesPath {
449460
return URL(fileURLWithPath: generatedFilesPath)

Sources/SourceKitLSP/SourceKitLSPServer.swift

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,8 @@ package actor SourceKitLSPServer {
222222
// was added to it and thus currently doesn't know that it can handle that file. In that case, we shouldn't open
223223
// a new workspace for the same root. Instead, the existing workspace's build system needs to be reloaded.
224224
let uri = DocumentURI(url)
225+
226+
let options = SourceKitLSPOptions.merging(base: self.options, workspaceFolder: uri)
225227
guard let buildSystemSpec = determineBuildSystem(forWorkspaceFolder: uri, options: self.options) else {
226228
continue
227229
}
@@ -231,7 +233,7 @@ package actor SourceKitLSPServer {
231233
guard
232234
let workspace = await orLog(
233235
"Creating workspace",
234-
{ try await createWorkspace(workspaceFolder: uri, buildSystemSpec: buildSystemSpec) }
236+
{ try await createWorkspace(workspaceFolder: uri, options: options, buildSystemSpec: buildSystemSpec) }
235237
)
236238
else {
237239
continue
@@ -821,22 +823,15 @@ extension SourceKitLSPServer {
821823
/// If the build system that was determined for the workspace does not satisfy `condition`, `nil` is returned.
822824
private func createWorkspace(
823825
workspaceFolder: DocumentURI,
826+
options: SourceKitLSPOptions,
824827
buildSystemSpec: BuildSystemSpec?
825828
) async throws -> Workspace {
826829
guard let capabilityRegistry = capabilityRegistry else {
827830
struct NoCapabilityRegistryError: Error {}
828831
logger.log("Cannot open workspace before server is initialized")
829832
throw NoCapabilityRegistryError()
830833
}
831-
let testHooks = self.testHooks
832-
let options = SourceKitLSPOptions.merging(
833-
base: self.options,
834-
override: SourceKitLSPOptions(
835-
path: workspaceFolder.fileURL?
836-
.appendingPathComponent(".sourcekit-lsp")
837-
.appendingPathComponent("config.json")
838-
)
839-
)
834+
840835
logger.log("Creating workspace at \(workspaceFolder.forLogging) with options: \(options.forLogging)")
841836
logger.logFullObjectInMultipleLogMessages(header: "Options for workspace", options.loggingProxy)
842837

@@ -848,7 +843,7 @@ extension SourceKitLSPServer {
848843
buildSystemSpec: buildSystemSpec,
849844
toolchainRegistry: self.toolchainRegistry,
850845
options: options,
851-
testHooks: testHooks,
846+
testHooks: self.testHooks,
852847
indexTaskScheduler: indexTaskScheduler
853848
)
854849
return workspace
@@ -857,9 +852,12 @@ extension SourceKitLSPServer {
857852
/// Determines the build system for the given workspace folder and creates a `Workspace` that uses this inferred build
858853
/// system.
859854
private func createWorkspaceWithInferredBuildSystem(workspaceFolder: DocumentURI) async throws -> Workspace {
855+
let options = SourceKitLSPOptions.merging(base: self.options, workspaceFolder: workspaceFolder)
856+
let buildSystemSpec = determineBuildSystem(forWorkspaceFolder: workspaceFolder, options: options)
860857
return try await self.createWorkspace(
861858
workspaceFolder: workspaceFolder,
862-
buildSystemSpec: determineBuildSystem(forWorkspaceFolder: workspaceFolder, options: self.options)
859+
options: options,
860+
buildSystemSpec: buildSystemSpec
863861
)
864862
}
865863

Tests/SourceKitLSPTests/WorkspaceTests.swift

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13+
import BuildSystemIntegration
1314
import Foundation
1415
import LanguageServerProtocol
1516
import SKLogging
@@ -967,4 +968,60 @@ final class WorkspaceTests: XCTestCase {
967968
["Cannot convert value of type 'Int' to specified type 'String'"]
968969
)
969970
}
971+
972+
func testWorkspaceOptionsOverrideBuildSystem() async throws {
973+
let swiftc = try await unwrap(ToolchainRegistry.forTesting.default?.swiftc)
974+
let sdkArgs =
975+
if let defaultSDKPath {
976+
"""
977+
-sdk '\(defaultSDKPath)'
978+
"""
979+
} else {
980+
""
981+
}
982+
983+
let project = try await MultiFileTestProject(files: [
984+
".sourcekit-lsp/config.json": """
985+
{
986+
"defaultWorkspaceType": "compilationDatabase"
987+
}
988+
""",
989+
"Foo.swift": """
990+
#if HAVE_SETTINGS
991+
#error("Have settings")
992+
#endif
993+
""",
994+
"Sources/MyLib/Bar.swift": "",
995+
"build/compile_commands.json": """
996+
[
997+
{
998+
"directory": "$TEST_DIR",
999+
"command": "\(swiftc.filePath) $TEST_DIR/Foo.swift -DHAVE_SETTINGS \(sdkArgs)",
1000+
"file": "Foo.swift",
1001+
"output": "build/Foo.swift.o"
1002+
},
1003+
]
1004+
""",
1005+
"Package.swift": """
1006+
// swift-tools-version: 5.7
1007+
1008+
import PackageDescription
1009+
1010+
let package = Package(
1011+
name: "MyLib",
1012+
targets: [
1013+
.target(name: "MyLib"),
1014+
]
1015+
)
1016+
""",
1017+
])
1018+
let (uri, _) = try project.openDocument("Foo.swift")
1019+
let diagnostics = try await project.testClient.send(
1020+
DocumentDiagnosticsRequest(textDocument: TextDocumentIdentifier(uri))
1021+
)
1022+
XCTAssertEqual(
1023+
diagnostics.fullReport?.items.map(\.message),
1024+
["Have settings"]
1025+
)
1026+
}
9701027
}

0 commit comments

Comments
 (0)