Skip to content
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .bazelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
common --enable_bzlmod
1 change: 1 addition & 0 deletions .bazelversion
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
7.4.1
2 changes: 2 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ jobs:
run: swift test
- name: Build sourcekit-bazel-bsp (release)
run: swift build -c release
- name: Build sourcekit-bazel-bsp (Bazel)
run: bazelisk build //Sources/sourcekit-bazel-bsp
- name: Build example //HelloWorld iOS app
run: |
cd Example
Expand Down
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ Package.resolved
.*.sw?
__pycache__
/.vscode/
swift-cmark
swift-cmark
bazel-*
Empty file added BUILD.bazel
Empty file.
24 changes: 24 additions & 0 deletions MODULE.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
bazel_dep(name = "rules_swift", version = "3.1.1", repo_name = "build_bazel_rules_swift")
bazel_dep(name = "rules_swift_package_manager", version = "1.3.0")
bazel_dep(name = "rules_apple", version = "4.1.2", repo_name = "build_bazel_rules_apple")

swift_deps = use_extension(
"@rules_swift_package_manager//:extensions.bzl",
"swift_deps",
)
swift_deps.from_package(
resolved = "//:Package.resolved",
swift = "//:Package.swift",
)
use_repo(
swift_deps,
"swift_package",
"swiftpkg_sourcekit_lsp",
"swiftpkg_swift_argument_parser",
"swiftpkg_swift_protobuf",
# The name of the Swift package repositories will be added to this declaration in step 4 after
# running `bazel mod tidy`.
# NOTE: The name of the Bazel external repository for a Swift package is `swiftpkg_xxx` where
# `xxx` is the Swift package identity, lowercase, with punctuation replaced by `hyphen`. For
# example, the repository name for apple/swift-nio is `swiftpkg_swift_nio`.
)
188 changes: 188 additions & 0 deletions MODULE.bazel.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ let package = Package(
),
.package(
url: "https://github.com/apple/sourcekit-lsp",
revision: "5df8f3d9ac0e647238ed4203e8f399ae5a095aa3"
revision: "6022af05e92b1fb9e3e17a09753d6434d8f0dc9b"
),
.package(
url: "https://github.com/apple/swift-protobuf.git",
Expand Down
32 changes: 29 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,35 @@
- Make sure all transitive libraries you'd like to use the BSP for have accompanying `(platform)_build_test` rules that directly targets them and are named `(lib_name)_ios_skbsp`. Only iOS rules are supported as of writing.
- This is because Bazel is currently missing a couple of important features we need in order to make this work in a clean way. This requirement can thus be seen as temporary, and you can expect it to be removed in the future as we evolve the tool and those missing features are introduced.
- Download and install [the official Swift extension](https://marketplace.visualstudio.com/items?itemName=swiftlang.swift-vscode) for Cursor / VSCode.
- Copy the .bsp/ folder on this repository to the root of the repository you'd like to use this tool for.
- Edit the `argv` fields in `.bsp/config.json` to match the details for your app / setup. You can see all available options by running `sourcekit-bazel-bsp serve --help`.
- On Cursor / VSCode, open a workspace containing the repository in question.
- Integrate BSP Server:
- Automated (suggested)
- Add the following to your `MODULE.bazel` file:

```python
bazel_dep(name = "sourcekit_bazel_bsp", version = "0.0.1", repo_name = "sourcekit_bazel_bsp")
```

- Define a `setup_sourcekit_bsp` in a BUILD.bazel file in the root of your workspace:

```python
load("@sourcekit_bazel_bsp//rules:setup_sourcekit_bsp.bzl")

setup_sourcekit_bsp(
name = "setup_sourcekit_bsp",
targets = YOUR_TARGETS,
bazel_wrapper = "/usr/local/bin/bazelisk" # Defaults to bazel
index_flags = [], # Optional indexing flags to pass to the build
files_to_watch = ["src/MyApp/**/*.swift"] # Globs of files to watch for changes to
)
```

- Run `bazel run //:setup_sourcekit_bsp`
- Thats it you have now integrated the tool. Users should re-run that command whenever the configuration is changed.

- Manual
- Copy the .bsp/ folder on this repository to the root of the repository you'd like to use this tool for.
- Edit the `argv` fields in `.bsp/config.json` to match the details for your app / setup. You can see all available options by running `sourcekit-bazel-bsp serve --help`.
- On the settings page for the Swift extension, enable `SourceKit-LSP: Background Indexing` at the **workspace level**. It **has** to be workspace settings; this specific setting is not supported at the folder level.
- Reload your workspace (`Cmd+Shift+P -> Reload Window`)

Expand All @@ -62,4 +88,4 @@ If you wish for the logs to become redacted again, you can remove the configurat

Since sourcekit-bazel-bsp is initialized from within sourcekit-lsp, debugging it requires you to start a lldb session in advance. You can do it with the following command: `lldb --attach-name sourcekit-bazel-bsp --wait-for`

Once the lldb session is initialized, triggering the initialization of the Swift extension on your IDE of choice (e.g. opening a Swift file in VSCode) should eventually cause lldb to start a debugging session.
Once the lldb session is initialized, triggering the initialization of the Swift extension on your IDE of choice (e.g. opening a Swift file in VSCode) should eventually cause lldb to start a debugging session.
12 changes: 12 additions & 0 deletions Sources/BazelProtobufBindings/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library")

swift_library(
name = "BazelProtobufBindings",
srcs = glob(["**/*.swift"], allow_empty = False),
module_name = "BazelProtobufBindings",
visibility = ["//visibility:public"],
deps = [
"@swiftpkg_swift_protobuf//:SwiftProtobuf",
],
package_name = "sourcekit-bazel-bsp",
)
14 changes: 14 additions & 0 deletions Sources/SourceKitBazelBSP/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library")

swift_library(
name = "SourceKitBazelBSP",
srcs = glob(["**/*.swift"], allow_empty = False),
module_name = "SourceKitBazelBSP",
visibility = ["//visibility:public"],
deps = [
"//Sources/BazelProtobufBindings",
"@swiftpkg_sourcekit_lsp//:BuildServerProtocol",
"@swiftpkg_sourcekit_lsp//:LSPBindings",
],
package_name = "sourcekit-bazel-bsp",
)
13 changes: 13 additions & 0 deletions Sources/sourcekit-bazel-bsp/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
load("@build_bazel_rules_swift//swift:swift.bzl", "swift_binary")

swift_binary(
name = "sourcekit-bazel-bsp",
srcs = glob(["**/*.swift"], allow_empty = False),
deps = [
"//Sources/SourceKitBazelBSP",
"@swiftpkg_swift_argument_parser//:ArgumentParser",
"@swiftpkg_swift_protobuf//:SwiftProtobuf",
],
visibility = ["//visibility:public"],
package_name = "sourcekit-bazel-bsp",
)
4 changes: 4 additions & 0 deletions rules/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
exports_files([
"bsp_config.json.tpl",
"setup_sourcekit_bsp.sh.tpl",
])
13 changes: 13 additions & 0 deletions rules/bsp_config.json.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"name": "sourcekit-bazel-bsp",
"version": "0.0.1",
"bspVersion": "2.2.0",
"languages": [
"c",
"cpp",
"objective-c",
"objective-cpp",
"swift"
],
"argv": [%argv%]
}
84 changes: 84 additions & 0 deletions rules/setup_sourcekit_bsp.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
def _setup_sourcekit_bsp_impl(ctx):
rendered_bsp_config = ctx.actions.declare_file("config.json")
bsp_config_argv = [
".bsp/sourcekit-bazel-bsp",
"serve",
]
for target in ctx.attr.targets:
bsp_config_argv.append("--target")
bsp_config_argv.append(target.label)
bsp_config_argv.append("--bazel-wrapper")
bsp_config_argv.append(ctx.attr.bazel_wrapper)
for index_flag in ctx.attr.index_flags:
bsp_config_argv.append("--index-flag")
bsp_config_argv.append(index_flag)
for files_to_watch in ctx.attr.files_to_watch:
bsp_config_argv.append("--files-to-watch")
bsp_config_argv.append(files_to_watch)
ctx.actions.expand_template(
template = ctx.file._bsp_config_template,
output = rendered_bsp_config,
substitutions = {
"%argv%": ", ".join(["\"%s\"" % arg for arg in bsp_config_argv]),
},
)
executable = ctx.actions.declare_file("setup_sourcekit_bsp.sh")
ctx.actions.expand_template(
template = ctx.file._setup_sourcekit_bsp_script,
is_executable = True,
output = executable,
substitutions = {
"%bsp_config_path%": rendered_bsp_config.short_path,
"%sourcekit_bazel_bsp_path%": ctx.executable._sourcekit_bazel_bsp_tool.short_path,
},
)
tools_runfiles = ctx.runfiles(
files = [
ctx.executable._sourcekit_bazel_bsp_tool,
rendered_bsp_config,
],
)
return DefaultInfo(
executable = executable,
files = depset(direct = [executable]),
runfiles = tools_runfiles,
)


setup_sourcekit_bsp = rule(
implementation = _setup_sourcekit_bsp_impl,
executable = True,
doc = "Sets up the sourcekit-bazel-bsp in the current workspace using the provided configuration.",
attrs = {
"_bsp_config_template": attr.label(
doc = "The template for the sourcekit-bazel-bsp configuration.",
default = "//rules:bsp_config.json.tpl",
allow_single_file = True,
),
"_setup_sourcekit_bsp_script": attr.label(
doc = "The script for setting up the sourcekit-bazel-bsp.",
default = "//rules:setup_sourcekit_bsp.sh.tpl",
allow_single_file = True,
),
"_sourcekit_bazel_bsp_tool": attr.label(
doc = "The sourcekit-bazel-bsp binary.",
default = "//Sources/sourcekit-bazel-bsp",
cfg = "exec",
executable = True,
),
"targets": attr.label_list(
doc = "The targets to set up the sourcekit-bazel-bsp for.",
mandatory = True,
),
"bazel_wrapper": attr.string(
doc = "The bazel wrapper to use.",
default = "bazel",
),
"index_flags": attr.string_list(
doc = "The index flags to use.",
),
"files_to_watch": attr.string_list(
doc = "The files to watch.",
),
},
)
9 changes: 9 additions & 0 deletions rules/setup_sourcekit_bsp.sh.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/bin/bash

set -euo pipefail

sourcekit_bazel_bsp_path="%sourcekit_bazel_bsp_path%"
bsp_config_path="%bsp_config_path%"

cp "${bsp_config_path}" "$BUILD_WORKSPACE_DIRECTORY/.bsp/config.json"
cp "${sourcekit_bazel_bsp_path}" "$BUILD_WORKSPACE_DIRECTORY/.bsp/sourcekit-bazel-bsp"
Loading