Skip to content

Commit 12d0e9d

Browse files
authored
feat: implement swift_deps bzlmod extension (cgrindel#290)
- Disable Bazel 5.4.0 integration tests while adding support for bzlmod. - Remove nogo target. Not used and was not compiling with bzlmod enabled. - Add `MODULE.bazel`. - Add `swift_deps` bzlmod extension to support generating Swift packages from info in `swift_deps_index.json`. - Add `bazel_package_name` attribute to `local_swift_package` and `swift_package`. It provides the unmolested Bazel repo name for the Swift package. In bzlmod mode, the `repository_ctx.name` value is the canonical repo name (i.e., includes the parent repo name). Related to cgrindel#276.
1 parent c3a6afb commit 12d0e9d

20 files changed

+257
-37
lines changed

.github/workflows/ci.yml

-8
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,8 @@ jobs:
3333
include:
3434
- example: http_archive_ext_deps
3535
bazel_version: .bazelversion
36-
- example: http_archive_ext_deps
37-
bazel_version: "5_4_0"
3836
- example: pkg_manifest_minimal
3937
bazel_version: .bazelversion
40-
- example: pkg_manifest_minimal
41-
bazel_version: "5_4_0"
4238
- example: soto_example
4339
bazel_version: .bazelversion
4440
- example: vapor_example
@@ -88,12 +84,8 @@ jobs:
8884
include:
8985
- example: http_archive_ext_deps
9086
bazel_version: .bazelversion
91-
- example: http_archive_ext_deps
92-
bazel_version: "5_4_0"
9387
- example: pkg_manifest_minimal
9488
bazel_version: .bazelversion
95-
- example: pkg_manifest_minimal
96-
bazel_version: "5_4_0"
9789
- example: soto_example
9890
bazel_version: .bazelversion
9991
- example: vapor_example

BUILD.bazel

+8-11
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ load("@cgrindel_bazel_starlib//bzltidy:defs.bzl", "tidy")
66
load("@cgrindel_bazel_starlib//markdown:defs.bzl", "markdown_pkg")
77
load("@cgrindel_bazel_starlib//shlib/rules:execute_binary.bzl", "execute_binary")
88
load("@cgrindel_bazel_starlib//updatesrc:defs.bzl", "updatesrc_diff_and_update", "updatesrc_update_all")
9-
load("@io_bazel_rules_go//go:def.bzl", "TOOLS_NOGO", "nogo")
109
load(
1110
"@rules_bazel_integration_test//bazel_integration_test:defs.bzl",
1211
"integration_test_utils",
@@ -61,16 +60,6 @@ tidy(
6160
],
6261
)
6362

64-
# MARK: - nogo Code Analysis
65-
66-
# https://github.com/bazelbuild/rules_go/blob/master/go/nogo.rst
67-
nogo(
68-
name = "nogo",
69-
config = "nogo_config.json",
70-
visibility = ["//visibility:public"],
71-
deps = TOOLS_NOGO,
72-
)
73-
7463
# MARK: - Gazelle
7564

7665
gazelle_binary(
@@ -154,6 +143,7 @@ filegroup(
154143
srcs = [
155144
".bazelrc",
156145
"BUILD.bazel",
146+
"MODULE.bazel",
157147
"WORKSPACE",
158148
"ci.bazelrc",
159149
"shared.bazelrc",
@@ -231,6 +221,13 @@ updatesrc_diff_and_update(
231221
],
232222
)
233223

224+
bzl_library(
225+
name = "extensions",
226+
srcs = ["extensions.bzl"],
227+
visibility = ["//visibility:public"],
228+
deps = ["//swiftpkg/bzlmod:swift_deps"],
229+
)
230+
234231
bzl_library(
235232
name = "bazel_versions",
236233
srcs = ["bazel_versions.bzl"],

MODULE.bazel

+79
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
module(
2+
name = "cgrindel_swift_bazel",
3+
version = "0.0.0",
4+
)
5+
6+
# MARK: - Runtime Dependencies
7+
8+
bazel_dep(name = "cgrindel_bazel_starlib", version = "0.14.9")
9+
bazel_dep(name = "bazel_skylib", version = "1.4.1")
10+
bazel_dep(
11+
name = "rules_go",
12+
version = "0.38.1",
13+
repo_name = "io_bazel_rules_go",
14+
)
15+
bazel_dep(name = "rules_cc", version = "0.0.6")
16+
bazel_dep(name = "platforms", version = "0.0.6")
17+
18+
# With bzlmod enabled, any dependencies for repositories generated by
19+
# swift_bazel _must_ be a runtime dependency of swift_bazel.
20+
bazel_dep(
21+
name = "rules_swift",
22+
version = "1.6.0",
23+
repo_name = "build_bazel_rules_swift",
24+
)
25+
bazel_dep(
26+
name = "rules_apple",
27+
version = "2.1.0",
28+
repo_name = "build_bazel_rules_apple",
29+
)
30+
31+
# TODO(chuck): FIX ME! Gazelle needs a new release to get the following fix:
32+
# https://github.com/bazelbuild/bazel-gazelle/pull/1413
33+
bazel_dep(
34+
name = "gazelle",
35+
version = "0.29.0",
36+
repo_name = "bazel_gazelle",
37+
)
38+
39+
go_sdk = use_extension("@io_bazel_rules_go//go:extensions.bzl", "go_sdk")
40+
use_repo(
41+
go_sdk,
42+
go_sdk = "go_default_sdk",
43+
)
44+
45+
go_deps = use_extension("@bazel_gazelle//:extensions.bzl", "go_deps")
46+
go_deps.from_file(go_mod = "//:go.mod")
47+
use_repo(
48+
go_deps,
49+
"com_github_bazelbuild_buildtools",
50+
"com_github_creasty_defaults",
51+
"com_github_deckarep_golang_set_v2",
52+
"com_github_stretchr_testify",
53+
"in_gopkg_yaml_v3",
54+
"org_golang_x_exp",
55+
"org_golang_x_tools",
56+
)
57+
58+
# MARK: - Dev Dependencies
59+
60+
bazel_dep(
61+
name = "rules_bazel_integration_test",
62+
version = "0.11.1",
63+
dev_dependency = True,
64+
)
65+
bazel_dep(
66+
name = "bazel_skylib_gazelle_plugin",
67+
version = "1.4.1",
68+
dev_dependency = True,
69+
)
70+
71+
bazel_binaries = use_extension(
72+
"@rules_bazel_integration_test//:extensions.bzl",
73+
"bazel_binaries",
74+
)
75+
bazel_binaries.download(version_file = "//:.bazelversion")
76+
use_repo(
77+
bazel_binaries,
78+
"build_bazel_bazel_.bazelversion",
79+
)

WORKSPACE.bzlmod

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Intentionally blank
2+
# This exists to force Bazel in bzlmod mode to be strict.

bazel_versions.bzl

-1
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,4 @@ CURRENT_BAZEL_VERSION = "//:.bazelversion"
44

55
SUPPORTED_BAZEL_VERSIONS = [
66
CURRENT_BAZEL_VERSION,
7-
"5.4.0",
87
]

docs/repository_rules_overview.md

+6-4
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ On this page:
1717
## local_swift_package
1818

1919
<pre>
20-
local_swift_package(<a href="#local_swift_package-name">name</a>, <a href="#local_swift_package-dependencies_index">dependencies_index</a>, <a href="#local_swift_package-env">env</a>, <a href="#local_swift_package-path">path</a>, <a href="#local_swift_package-repo_mapping">repo_mapping</a>)
20+
local_swift_package(<a href="#local_swift_package-name">name</a>, <a href="#local_swift_package-bazel_package_name">bazel_package_name</a>, <a href="#local_swift_package-dependencies_index">dependencies_index</a>, <a href="#local_swift_package-env">env</a>, <a href="#local_swift_package-path">path</a>, <a href="#local_swift_package-repo_mapping">repo_mapping</a>)
2121
</pre>
2222

2323
Used to build a local Swift package.
@@ -28,6 +28,7 @@ Used to build a local Swift package.
2828
| Name | Description | Type | Mandatory | Default |
2929
| :------------- | :------------- | :------------- | :------------- | :------------- |
3030
| <a id="local_swift_package-name"></a>name | A unique name for this repository. | <a href="https://bazel.build/concepts/labels#target-names">Name</a> | required | |
31+
| <a id="local_swift_package-bazel_package_name"></a>bazel_package_name | The short name for the Swift package's Bazel repository. | String | optional | <code>""</code> |
3132
| <a id="local_swift_package-dependencies_index"></a>dependencies_index | A JSON file that contains a mapping of Swift products and Swift modules. | <a href="https://bazel.build/concepts/labels">Label</a> | required | |
3233
| <a id="local_swift_package-env"></a>env | Environment variables that will be passed to the execution environments for this repository rule. (e.g. SPM version check, SPM dependency resolution, SPM package description generation) | <a href="https://bazel.build/rules/lib/dict">Dictionary: String -> String</a> | optional | <code>{}</code> |
3334
| <a id="local_swift_package-path"></a>path | The path to the local Swift package directory. | String | required | |
@@ -39,9 +40,9 @@ Used to build a local Swift package.
3940
## swift_package
4041

4142
<pre>
42-
swift_package(<a href="#swift_package-name">name</a>, <a href="#swift_package-branch">branch</a>, <a href="#swift_package-commit">commit</a>, <a href="#swift_package-dependencies_index">dependencies_index</a>, <a href="#swift_package-env">env</a>, <a href="#swift_package-init_submodules">init_submodules</a>, <a href="#swift_package-patch_args">patch_args</a>,
43-
<a href="#swift_package-patch_cmds">patch_cmds</a>, <a href="#swift_package-patch_cmds_win">patch_cmds_win</a>, <a href="#swift_package-patch_tool">patch_tool</a>, <a href="#swift_package-patches">patches</a>, <a href="#swift_package-recursive_init_submodules">recursive_init_submodules</a>, <a href="#swift_package-remote">remote</a>,
44-
<a href="#swift_package-repo_mapping">repo_mapping</a>, <a href="#swift_package-shallow_since">shallow_since</a>, <a href="#swift_package-tag">tag</a>, <a href="#swift_package-verbose">verbose</a>)
43+
swift_package(<a href="#swift_package-name">name</a>, <a href="#swift_package-bazel_package_name">bazel_package_name</a>, <a href="#swift_package-branch">branch</a>, <a href="#swift_package-commit">commit</a>, <a href="#swift_package-dependencies_index">dependencies_index</a>, <a href="#swift_package-env">env</a>, <a href="#swift_package-init_submodules">init_submodules</a>,
44+
<a href="#swift_package-patch_args">patch_args</a>, <a href="#swift_package-patch_cmds">patch_cmds</a>, <a href="#swift_package-patch_cmds_win">patch_cmds_win</a>, <a href="#swift_package-patch_tool">patch_tool</a>, <a href="#swift_package-patches">patches</a>, <a href="#swift_package-recursive_init_submodules">recursive_init_submodules</a>,
45+
<a href="#swift_package-remote">remote</a>, <a href="#swift_package-repo_mapping">repo_mapping</a>, <a href="#swift_package-shallow_since">shallow_since</a>, <a href="#swift_package-tag">tag</a>, <a href="#swift_package-verbose">verbose</a>)
4546
</pre>
4647

4748
Used to download and build an external Swift package.
@@ -53,6 +54,7 @@ Used to download and build an external Swift package.
5354
| Name | Description | Type | Mandatory | Default |
5455
| :------------- | :------------- | :------------- | :------------- | :------------- |
5556
| <a id="swift_package-name"></a>name | A unique name for this repository. | <a href="https://bazel.build/concepts/labels#target-names">Name</a> | required | |
57+
| <a id="swift_package-bazel_package_name"></a>bazel_package_name | The short name for the Swift package's Bazel repository. | String | optional | <code>""</code> |
5658
| <a id="swift_package-branch"></a>branch | branch in the remote repository to checked out. Precisely one of branch, tag, or commit must be specified. | String | optional | <code>""</code> |
5759
| <a id="swift_package-commit"></a>commit | The commit or revision to download from version control. | String | required | |
5860
| <a id="swift_package-dependencies_index"></a>dependencies_index | A JSON file that contains a mapping of Swift products and Swift modules. | <a href="https://bazel.build/concepts/labels">Label</a> | required | |
+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
bazel_dep(
2+
name = "cgrindel_swift_bazel",
3+
version = "0.0.0",
4+
)
5+
local_path_override(
6+
module_name = "cgrindel_swift_bazel",
7+
path = "../..",
8+
)
9+
10+
bazel_dep(name = "cgrindel_bazel_starlib", version = "0.14.9")
11+
bazel_dep(name = "bazel_skylib", version = "1.4.1")
12+
bazel_dep(
13+
name = "rules_swift",
14+
version = "1.6.0",
15+
repo_name = "build_bazel_rules_swift",
16+
)
17+
18+
bazel_dep(
19+
name = "bazel_skylib_gazelle_plugin",
20+
version = "1.4.1",
21+
dev_dependency = True,
22+
)
23+
bazel_dep(
24+
name = "gazelle",
25+
version = "0.29.0",
26+
dev_dependency = True,
27+
repo_name = "bazel_gazelle",
28+
)
29+
30+
swift_deps = use_extension(
31+
"@cgrindel_swift_bazel//:extensions.bzl",
32+
"swift_deps",
33+
)
34+
swift_deps.from_file(
35+
deps_index = "//:swift_deps_index.json",
36+
)
37+
use_repo(
38+
swift_deps,
39+
"swiftpkg_my_local_package",
40+
"swiftpkg_swift_argument_parser",
41+
"swiftpkg_swift_log",
42+
"swiftpkg_swiftformat",
43+
)
44+
45+
# IDEA
46+
# use_repo(swift_deps, "swift_deps")
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Intentionally blank
2+
# This exists to force Bazel in bzlmod mode to be strict.

examples/pkg_manifest_minimal/swift_deps_index.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
{
22
"direct_dep_identities": [
3+
"my_local_package",
34
"swift-argument-parser",
45
"swift-log",
5-
"swiftformat",
6-
"my_local_package"
6+
"swiftformat"
77
],
88
"modules": [
99
{

extensions.bzl

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
"""Bazel module extensions."""
2+
3+
load("//swiftpkg/bzlmod:swift_deps.bzl", _swift_deps = "swift_deps")
4+
5+
swift_deps = _swift_deps

go.mod

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module github.com/cgrindel/swift_bazel
22

3-
go 1.19
3+
go 1.18
44

55
require (
66
github.com/bazelbuild/bazel-gazelle v0.29.0

shared.bazelrc

+5
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,8 @@ build --incompatible_strict_action_env=true
66

77
# Test output information
88
test --test_output=errors --test_summary=detailed
9+
10+
# GH276: Enable bzlmod
11+
# # Enable bzlmod
12+
# common --enable_bzlmod
13+
# build --@cgrindel_bazel_starlib//bzlmod:enabled

swiftpkg/bzlmod/BUILD.bazel

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
2+
load("@cgrindel_bazel_starlib//bzlformat:defs.bzl", "bzlformat_pkg")
3+
4+
bzlformat_pkg(name = "bzlformat")
5+
6+
bzl_library(
7+
name = "swift_deps",
8+
srcs = ["swift_deps.bzl"],
9+
visibility = ["//visibility:public"],
10+
deps = ["//swiftpkg/internal:deps_indexes"],
11+
)

swiftpkg/bzlmod/swift_deps.bzl

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
"""Implementation for `swift_deps` bzlmod extension."""
2+
3+
load("//swiftpkg/internal:deps_indexes.bzl", "deps_indexes")
4+
load("//swiftpkg/internal:local_swift_package.bzl", "local_swift_package")
5+
load("//swiftpkg/internal:swift_package.bzl", "swift_package")
6+
7+
# MARK: - swift_deps bzlmod Extension
8+
9+
def _declare_pkg_from_package(package, deps_index_label):
10+
if package.remote_pkg != None:
11+
swift_package(
12+
name = package.name,
13+
bazel_package_name = package.name,
14+
commit = package.remote_pkg.commit,
15+
remote = package.remote_pkg.remote,
16+
dependencies_index = deps_index_label,
17+
)
18+
elif package.local_pkg != None:
19+
local_swift_package(
20+
name = package.name,
21+
bazel_package_name = package.name,
22+
path = package.local_pkg.path,
23+
dependencies_index = deps_index_label,
24+
)
25+
else:
26+
fail("Found package '{}' without a remote or local.".format(
27+
package.identity,
28+
))
29+
30+
def _declare_pkgs_from_file(module_ctx, from_file):
31+
index_json = module_ctx.read(from_file.deps_index)
32+
deps_index = deps_indexes.new_from_json(index_json)
33+
for package in deps_index.packages_by_id.values():
34+
_declare_pkg_from_package(package, from_file.deps_index)
35+
36+
def _swift_deps_impl(module_ctx):
37+
for mod in module_ctx.modules:
38+
for from_file in mod.tags.from_file:
39+
_declare_pkgs_from_file(module_ctx, from_file)
40+
41+
_from_file_tag = tag_class(
42+
attrs = {
43+
"deps_index": attr.label(
44+
mandatory = True,
45+
doc = "A `swift_deps_index.json`.",
46+
),
47+
},
48+
doc = "Load Swift packages from a file generated by the Gazelle extension.",
49+
)
50+
51+
swift_deps = module_extension(
52+
implementation = _swift_deps_impl,
53+
tag_classes = {
54+
"from_file": _from_file_tag,
55+
},
56+
)

swiftpkg/internal/local_swift_package.bzl

+3-3
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ def _local_swift_package_impl(repository_ctx):
6060
pkg_ctx = pkg_ctxs.read(repository_ctx, repo_dir, env)
6161
repo_rules.gen_build_files(repository_ctx, pkg_ctx)
6262

63-
return update_attrs(repository_ctx.attr, _COMMON_ATTRS.keys(), {})
63+
return update_attrs(repository_ctx.attr, _ALL_ATTRS.keys(), {})
6464

6565
_PATH_ATTRS = {
6666
"path": attr.string(
@@ -69,14 +69,14 @@ _PATH_ATTRS = {
6969
),
7070
}
7171

72-
_COMMON_ATTRS = dicts.add(
72+
_ALL_ATTRS = dicts.add(
7373
repo_rules.env_attrs,
7474
repo_rules.swift_attrs,
7575
_PATH_ATTRS,
7676
)
7777

7878
local_swift_package = repository_rule(
7979
implementation = _local_swift_package_impl,
80-
attrs = _COMMON_ATTRS,
80+
attrs = _ALL_ATTRS,
8181
doc = "Used to build a local Swift package.",
8282
)

swiftpkg/internal/pkg_ctxs.bzl

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
load(":deps_indexes.bzl", "deps_indexes")
44
load(":pkginfo_ext_deps.bzl", "pkginfo_ext_deps")
55
load(":pkginfos.bzl", "pkginfos")
6+
load(":repository_utils.bzl", "repository_utils")
67

78
def _read(repository_ctx, repo_dir, env):
89
deps_index_json = repository_ctx.read(
@@ -17,7 +18,7 @@ def _read(repository_ctx, repo_dir, env):
1718
)
1819
return _new(
1920
pkg_info = pkg_info,
20-
repo_name = repository_ctx.name,
21+
repo_name = repository_utils.package_name(repository_ctx),
2122
deps_index = deps_index,
2223
)
2324

0 commit comments

Comments
 (0)