This repository contains Bazel rules and macros that will format Swift source files using nicklockwood/SwiftFormat, test that the formatted files exist in the workspace directory, and copy the formatted files to the workspace directory.
The following provides a quick introduction on how to use the rules in this repository. Also, check out the documentation and the examples for more information.
Add the following to your WORKSPACE
file to add this repository and its dependencies.
# Download and configure rules_swiftformat.
http_archive(
name = "rules_swift_tidy",
sha256 = "f496774f56e8260e277dc17366cf670b55dee3616327a13d2d04bd1b62cdcc88",
strip_prefix = "rules_swiftformat-0.4.1",
urls = [
"http://github.com/cgrindel/rules_swiftformat/archive/v0.4.1.tar.gz",
],
)
load(
"//swiftformat:deps.bzl",
"swiftformat_rules_dependencies",
)
swiftformat_rules_dependencies()
# Configure the dependencies for rules_swiftformat
load(
"@cgrindel_bazel_starlib//:deps.bzl",
"bazel_starlib_dependencies",
)
bazel_starlib_dependencies()
load(
"@build_bazel_rules_swift//swift:repositories.bzl",
"swift_rules_dependencies",
)
swift_rules_dependencies()
load(
"@build_bazel_rules_swift//swift:extras.bzl",
"swift_rules_extra_dependencies",
)
swift_rules_extra_dependencies()
load(
"@rules_swift_tidy//swiftformat:defs.bzl",
"swiftformat_register_prebuilt_toolchains",
)
swiftformat_register_prebuilt_toolchains()
At the root of your workspace, create a BUILD.bazel
file, if you don't have one. Add the
following:
load(
"@cgrindel_bazel_starlib//updatesrc:defs.bzl",
"updatesrc_update_all",
)
# We export this file to make it available to other Bazel packages in the workspace.
exports_files([".swiftformat"])
# Define a runnable target to copy all of the formatted files to the workspace directory.
updatesrc_update_all(
name = "update_all",
)
The exports_files
declaration defines a target for your SwiftFormat configuration file
(.swiftformat
). It is referenced by the
swiftformat_pkg
that we will add to each of the Bazel packages that contain Swift source files.
The updatesrc_update_all macro defines a runnable target that copies all of the formatted Swift source files to the workspace directory.
In every Bazel package that contains Swift source files, add a
swiftformat_pkg
declaration.
load(
"@rules_swift_tidy//swiftformat:defs.bzl",
"swiftformat_pkg",
)
swiftformat_pkg(name = "swiftformat")
The swiftformat_pkg
macro defines targets for
a Bazel package which will format the Swift source files, test that the formatted files are in the
workspace directory and copies the formatted files to the workspace directory.
From the command-line, you can format the Swift source files, copy them back to the workspace directory and execute the tests that ensure the formatted soures are in the workspace directory.
# Format the Swift source files and copy the formatted files back to the workspace directory
$ bazel run //:update_all
# Execute all of your tests including the formatting checks
$ bazel test //...
By default, rules_swiftformat
will load a recent release of
SwiftFormat. This works well for most cases.
However, if you would like to specify the SwiftFormat release, you can do so by specifying the
assets to download when calling swiftformat_register_prebuilt_toolchains
function in your WORKSPACE
.
swiftformat_register_prebuilt_toolchains(
assets = [
prebuilt_assets.create_swiftformat(
version = "0.51.11",
os = "macos",
cpu = "x86_64",
file = "swiftformat",
sha256 = "e565ebf6c54ee8e1ac83e4974edae34e002f86eda358a5838c0171f32f00ab20",
),
# Other declarations...
],
)
To make this easier, this repository includes a tool called generate_assets_declaration
. Executing
this tool will generate the appropriate declaration to download and configure the desired version of
SwiftFormat.
# Specify the desired SwiftFormat version
$ bazel run //tools:generate_assets_declaration -- "0.51.11"
load(
"@rules_swift_tidy//swiftformat:defs.bzl",
"swiftformat_register_prebuilt_toolchains",
"prebuilt_assets",
)
swiftformat_register_prebuilt_toolchains(
assets = [
prebuilt_assets.create_swiftformat(
version = "0.51.11",
os = "macos",
cpu = "x86_64",
file = "swiftformat",
sha256 = "e565ebf6c54ee8e1ac83e4974edae34e002f86eda358a5838c0171f32f00ab20",
),
prebuilt_assets.create_swiftformat(
version = "0.51.11",
os = "macos",
cpu = "arm64",
file = "swiftformat",
sha256 = "e565ebf6c54ee8e1ac83e4974edae34e002f86eda358a5838c0171f32f00ab20",
),
prebuilt_assets.create_swiftformat(
version = "0.51.11",
os = "linux",
cpu = "x86_64",
file = "swiftformat_linux",
sha256 = "a49b79d97c234ccb5bcd2064ffec868e93e2eabf2d5de79974ca3802d8e389ec",
),
],
)
By default, this ruleset downloads prebuilt binaries from
nicklockwood/SwiftFormat. The Linux binaries provided
by this website dynamically load certain shared libraries (e.g. Foundation). On Linux, Swift
finds these libraries by searching the directories specified by the LD_LIBRARY_PATH
envronment
variable. Be sure to update this environment variable with the path to the shard libraries provided
by the Swift SDK.
For instance, on Ubuntu, one might install Swift to $HOME/swift-5.7.2-RELEASE-ubuntu22.04
. The
shared library directory for this installation is
$HOME/swift-5.7.2-RELEASE-ubuntu22.04/usr/lib/swift/linux
.
In addition to setting the LD_LIBRARY_PATH
environment variable, you must tell Bazel to provide
this value to its actions. This is done by using the --action_env
flag. Update the .bazelrc
file
for your project to include the following:
# Need to expose the PATH so that the Swift toolchain can be found
build --action_env=PATH
# Need to expose the LD_LIBRARY_PATH so that the Swift dynamic loaded
# so files can be found
build --action_env=LD_LIBRARY_PATH