New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for a compile database file not at the root of a workspace #915
Add support for a compile database file not at the root of a workspace #915
Conversation
@@ -55,7 +55,7 @@ public final class SKSwiftPMTestWorkspace { | |||
/// Connection to the language server. | |||
public let testClient: TestSourceKitLSPClient | |||
|
|||
/// When `testServer` is not `nil`, the workspace will be opened in that server, otherwise a new server will be created for the workspace | |||
/// When `testClient` is not `nil`, the workspace will be opened in that client's server, otherwise a new client will be created for the workspace |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not really related, but I was confused by the wording here when browsing the codebase.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, I recently changed testServer
to testClient
and looks like I forgot that comment. Thanks for updating it.
var compilationDatabaseSearchPaths = try! [ | ||
// These defaults match the behavior of clangd | ||
RelativePath(validating: "."), | ||
RelativePath(validating: "build"), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It may make sense to pull these out and make the search paths "additional" so the defaults persist even in the presence of custom search paths.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I think that would make sense. IMO the search precedence should be user-defined search paths, .
, build
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice. Thanks for opening a PR for this so quickly 🤩.
I would like to think about the naming of the command line option a little bit more. I’m not unconditionally happy with it but don’t have any better ideas either, so maybe it’s fine. @bnbarham Maybe you’ve got an opinion here as well.
try? | ||
(JSONCompilationDatabase(directory: $0, fileSystem) | ||
?? FixedCompilationDatabase(directory: $0, fileSystem)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the initializers now return nil
when the file doesn’t exist, I think we no longer need to do try?
here and can change it to try
. That way we don’t silently ignore errors anymore.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I looked into this but it is actually a bigger change than it seems as the throws
will propagate all the way up to things like the BuildSystem
protocol, so you may want to do that separately (if at all). In the meantime I made it try!
since decoding errors should be very infrequent and shouldn't fail silently.
@@ -55,7 +55,7 @@ public final class SKSwiftPMTestWorkspace { | |||
/// Connection to the language server. | |||
public let testClient: TestSourceKitLSPClient | |||
|
|||
/// When `testServer` is not `nil`, the workspace will be opened in that server, otherwise a new server will be created for the workspace | |||
/// When `testClient` is not `nil`, the workspace will be opened in that client's server, otherwise a new client will be created for the workspace |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, I recently changed testServer
to testClient
and looks like I forgot that comment. Thanks for updating it.
@@ -137,6 +150,18 @@ struct SourceKitLSP: ParsableCommand { | |||
) | |||
var indexPrefixMappings = [PathPrefixMapping]() | |||
|
|||
@Option( | |||
name: .customLong("compilation-db-search-path", withSingleDash: false), | |||
parsing: .unconditionalSingleValue, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any reason why you decided to choose unconditionalSingleValue
here instead of the default singleValue
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No strong reason, though now that I think about it singleValue
might be better as --compilation-db-search-path --some-other-flag may have a better compilation error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That’s what I thought as well.
let compilationDatabase = try JSONCompilationDatabase( | ||
file: AbsolutePath(validating: compilationDatabaseUrl.path) | ||
)! | ||
let newCommands = compilationDatabase.allCommands.map { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you use XCTUnwrap
instead of !
here so the test doesn’t crash if the database is nil
?
@@ -137,6 +150,18 @@ struct SourceKitLSP: ParsableCommand { | |||
) | |||
var indexPrefixMappings = [PathPrefixMapping]() | |||
|
|||
@Option( | |||
name: .customLong("compilation-db-search-path", withSingleDash: false), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
withSingleDash
defaults to false
, so we don’t need to specify it.
var compilationDatabaseSearchPaths = try! [ | ||
// These defaults match the behavior of clangd | ||
RelativePath(validating: "."), | ||
RelativePath(validating: "build"), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I think that would make sense. IMO the search precedence should be user-defined search paths, .
, build
.
No particularly strong ones. |
This confused me when I was looking into this. I was used to "compile_commands.json", but the term "compile database" is more accurate (and what is used in the |
@@ -137,6 +150,18 @@ struct SourceKitLSP: ParsableCommand { | |||
) | |||
var indexPrefixMappings = [PathPrefixMapping]() | |||
|
|||
@Option( | |||
name: .customLong("compilation-db-search-path", withSingleDash: false), | |||
parsing: .unconditionalSingleValue, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That’s what I thought as well.
I think |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have a couple more minor formatting comments inline.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just one more note on the doc comments.
Also: Could you squash your commits? It makes for a nicer git history.
let path = directory.appending(component: "compile_flags.txt") | ||
try self.init(file: path, fileSystem) | ||
} | ||
|
||
public init(file: AbsolutePath, _ fileSystem: FileSystem = localFileSystem) throws { | ||
/// Loads the compilation database from `file` | ||
/// returns: `nil` if the file does not exist |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you also update the other returns:
lines to use docc markup?
65b2571
to
170b44b
Compare
Updated comments, and squash-force0pushed... do you guys not use GitHub's "squash and merge"? |
I prefer not to squash and merge for the reasons outlined here: https://github.com/apple/swift-syntax/blob/main/CONTRIBUTING.md#authoring-commits |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice. Let’s get this in 🚢
@swift-ci Please test |
@swift-ci Please test Windows |
Thanks for working with me on this @ahoppen! |
Thanks for your contribution! |
Introduce a new command-line flag (
--compile-db-search-path
) tosourcekit-lsp
, which can be used to specify which subdirectories in a workspace should be searched for a clangd-style compile database (compile_commands.json
orcompile_flags.txt
). Originally, I was going to add aclangd
-like--compile-commands-dir
flag, but upon further investigation decided this wasn't a good approach, as sourcekit-lsp supports multiple workspaces andclangd
does not. In a world with multiple workspaces it does not make sense to specify a single absolute path to a compile-database, so instead I opted for a set of relative search paths, which apply to all databases managed by a particular instance ofsourcekit-lsp
.