Skip to content

Commit 880db7f

Browse files
feat: set license information for packages with rules_license (#1118)
Resolves #1092. Signed-off-by: Brentley Jones <[email protected]>
1 parent 76b88dc commit 880db7f

13 files changed

+261
-6
lines changed

MODULE.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ module(
77

88
bazel_dep(name = "cgrindel_bazel_starlib", version = "0.21.0")
99
bazel_dep(name = "bazel_skylib", version = "1.4.2")
10+
bazel_dep(name = "rules_license", version = "0.0.8")
1011
bazel_dep(
1112
name = "rules_go",
1213
version = "0.47.0",

deps.bzl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,13 @@ def swift_bazel_dependencies():
4444
"https://github.com/cgrindel/bazel-starlib/releases/download/v0.21.0/bazel-starlib.v0.21.0.tar.gz",
4545
],
4646
)
47+
48+
maybe(
49+
http_archive,
50+
name = "rules_license",
51+
sha256 = "241b06f3097fd186ff468832150d6cc142247dc42a32aaefb56d0099895fd229",
52+
urls = [
53+
"https://mirror.bazel.build/github.com/bazelbuild/rules_license/releases/download/0.0.8/rules_license-0.0.8.tar.gz",
54+
"https://github.com/bazelbuild/rules_license/releases/download/0.0.8/rules_license-0.0.8.tar.gz",
55+
],
56+
)

docs/repository_rules_overview.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ Used to build a local Swift package.
4242
<pre>
4343
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>,
4444
<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>)
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>, <a href="#swift_package-version">version</a>)
4646
</pre>
4747

4848
Used to download and build an external Swift package.
@@ -70,5 +70,6 @@ Used to download and build an external Swift package.
7070
| <a id="swift_package-shallow_since"></a>shallow_since | an optional date, not after the specified commit; the argument is not allowed if a tag is specified (which allows cloning with depth 1). Setting such a date close to the specified commit allows for a more shallow clone of the repository, saving bandwidth and wall-clock time. | String | optional | `""` |
7171
| <a id="swift_package-tag"></a>tag | tag in the remote repository to checked out. Precisely one of branch, tag, or commit must be specified. | String | optional | `""` |
7272
| <a id="swift_package-verbose"></a>verbose | - | Boolean | optional | `False` |
73+
| <a id="swift_package-version"></a>version | The resolved version of the package. | String | optional | `""` |
7374

7475

swiftpkg/bzlmod/swift_deps.bzl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ def _declare_pkg_from_dependency(dep, config_pkg):
164164
bazel_package_name = name,
165165
commit = pin.state.revision,
166166
remote = pin.location,
167+
version = pin.state.version,
167168
dependencies_index = None,
168169
init_submodules = init_submodules,
169170
recursive_init_submodules = recursive_init_submodules,

swiftpkg/internal/build_decls.bzl

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,10 @@ def _to_starlark_parts(decl, indent):
2929
for c in decl.comments:
3030
parts.append(scg.indent(indent, "{}\n".format(c)))
3131
parts.append(scg.indent(indent, "{}(\n".format(decl.kind)))
32-
parts.extend(scg.new_attr("name", decl.name, indent + 1))
32+
33+
# Name won't be set for `package` declarations
34+
if decl.name:
35+
parts.extend(scg.new_attr("name", decl.name, indent + 1))
3336

3437
# Sort the keys to ensure that we have a consistent output. It would be
3538
# ideal to output them in a manner that matches Buildifier output rules.

swiftpkg/internal/build_files.bzl

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,14 @@ load(":build_decls.bzl", "build_decls")
55
load(":load_statements.bzl", "load_statements")
66
load(":starlark_codegen.bzl", scg = "starlark_codegen")
77

8-
def _new(load_stmts = [], decls = []):
8+
def _new(load_stmts = [], package_attrs = {}, decls = []):
99
"""Create a `struct` that represents the parts of a Bazel build file.
1010
1111
Args:
1212
load_stmts: A `list` of load statement `struct` values as returned
1313
by `load_statements.new`.
14+
package_attrs: A `dict` of attributes to set on the `package`
15+
declaration.
1416
decls: A `list` of declaration `struct` values as returned by
1517
`build_decls.new`.
1618
@@ -19,6 +21,7 @@ def _new(load_stmts = [], decls = []):
1921
"""
2022
return struct(
2123
load_stmts = load_stmts,
24+
package_attrs = package_attrs,
2225
decls = decls,
2326
to_starlark_parts = _to_starlark_parts,
2427
)
@@ -27,6 +30,13 @@ def _to_starlark_parts(build_file, indent):
2730
parts = []
2831
for load_stmt in build_file.load_stmts:
2932
parts.extend([scg.with_indent(indent, load_stmt), "\n"])
33+
if build_file.package_attrs:
34+
package_decl = build_decls.new(
35+
"package",
36+
None,
37+
attrs = build_file.package_attrs,
38+
)
39+
parts.extend(["\n", scg.with_indent(indent, package_decl), "\n"])
3040
for decl in build_file.decls:
3141
parts.extend(["\n", scg.with_indent(indent, decl), "\n"])
3242
return parts
@@ -48,14 +58,17 @@ def _merge(*bld_files):
4858
fail("Attempted to merge build files, but none were provided.")
4959

5060
load_stmts = []
61+
package_attrs = {}
5162
decls = []
5263
for bf in bld_files:
5364
load_stmts.extend(bf.load_stmts)
65+
package_attrs |= bf.package_attrs
5466
decls.extend(bf.decls)
5567
load_stmts = load_statements.uniq(load_stmts)
5668
decls = build_decls.uniq(decls)
5769
return _new(
5870
load_stmts = load_stmts,
71+
package_attrs = package_attrs,
5972
decls = decls,
6073
)
6174

swiftpkg/internal/pkginfos.bzl

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -598,6 +598,18 @@ def _new_from_parsed_json(
598598
)
599599
targets.append(target)
600600

601+
url = None
602+
version = None
603+
if hasattr(repository_ctx, "attr"):
604+
# We only want to try to collect url and version when called from
605+
# `swift_package`
606+
url = getattr(repository_ctx.attr, "remote", None)
607+
version = getattr(
608+
repository_ctx.attr,
609+
"version",
610+
getattr(repository_ctx.attr, "commit", None),
611+
)
612+
601613
return _new(
602614
name = dump_manifest["name"],
603615
path = pkg_path,
@@ -610,6 +622,8 @@ def _new_from_parsed_json(
610622
dependencies = dependencies,
611623
products = products,
612624
targets = targets,
625+
url = url,
626+
version = version,
613627
)
614628

615629
# MARK: - Swift Package
@@ -622,7 +636,9 @@ def _new(
622636
platforms = [],
623637
dependencies = [],
624638
products = [],
625-
targets = []):
639+
targets = [],
640+
url = None,
641+
version = None):
626642
"""Returns a `struct` representing information about a Swift package.
627643
628644
Args:
@@ -639,6 +655,8 @@ def _new(
639655
`pkginfos.new_product()`.
640656
targets: A `list` of target structs as created by
641657
`pkginfos.new_target()`.
658+
url: Optional. The url of the package (`string`).
659+
version: Optional. The semantic version of the package (`string`).
642660
643661
Returns:
644662
A `struct` representing information about a Swift package.
@@ -652,6 +670,8 @@ def _new(
652670
dependencies = dependencies,
653671
products = products,
654672
targets = targets,
673+
url = url,
674+
version = version,
655675
)
656676

657677
# MARK: - Platform

swiftpkg/internal/repo_rules.bzl

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,19 @@ higher. Found version %s installed.\
6565
def _gen_build_files(repository_ctx, pkg_ctx):
6666
pkg_info = pkg_ctx.pkg_info
6767

68-
# Create Bazel declarations for the Swift package targets
6968
bld_files = []
69+
70+
licenses = repository_files.find_license_files(repository_ctx)
71+
bld_files.append(
72+
# Pick the shortest name, in order to prefer `LICENSE` over
73+
# `LICENSE.md`
74+
swiftpkg_build_files.new_for_license(
75+
pkg_info,
76+
sorted(licenses, key = len)[0] if licenses else None,
77+
),
78+
)
79+
80+
# Create Bazel declarations for the Swift package targets
7081
for target in pkg_info.targets:
7182
# Unfortunately, Package.resolved does not contain test-only external
7283
# dependencies. So, we need to skip generating test targets.

swiftpkg/internal/repository_files.bzl

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,49 @@ def _path_exists(repository_ctx, path):
1818
)
1919
return exec_result.return_code == 0
2020

21+
def _find_license_files(repository_ctx):
22+
"""Retrieves all license files at the root of the package.
23+
24+
Args:
25+
repository_ctx: A `repository_ctx` instance.
26+
27+
Returns:
28+
A `list` of path `string` values.
29+
"""
30+
31+
find_args = [
32+
"find",
33+
# Follow symlinks and report on the actual files.
34+
"-H",
35+
"-L",
36+
".",
37+
# For GNU find, it is important for the global options (e.g. -maxdepth)
38+
# to be specified BEFORE other options like -type. Also, GNU find does
39+
# not support -depth <level>. So, we approximate it by using -mindepth
40+
# and -maxdepth.
41+
"-mindepth",
42+
"1",
43+
"-maxdepth",
44+
"1",
45+
"-type",
46+
"f",
47+
"(",
48+
"-name",
49+
"LICENSE",
50+
"-o",
51+
"-name",
52+
"LICENSE.*",
53+
")",
54+
]
55+
56+
exec_result = repository_ctx.execute(find_args, quiet = True)
57+
if exec_result.return_code != 0:
58+
fail("Failed to find license files. stderr:\n%s" % exec_result.stderr)
59+
return _process_find_results(
60+
exec_result.stdout,
61+
find_path = ".",
62+
)
63+
2164
def _list_files_under(
2265
repository_ctx,
2366
path,
@@ -247,6 +290,7 @@ repository_files = struct(
247290
exclude_paths = _exclude_paths,
248291
file_type = _file_type,
249292
find_and_delete_files = _find_and_delete_files,
293+
find_license_files = _find_license_files,
250294
is_directory = _is_directory,
251295
list_directories_under = _list_directories_under,
252296
list_files_under = _list_files_under,

swiftpkg/internal/starlark_codegen.bzl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ _single_indent_str = " "
55
# MARK: - Simple Type Detection
66

77
_simple_starlark_types = [
8-
"None",
8+
"NoneType",
99
"bool",
1010
"int",
1111
"string",

0 commit comments

Comments
 (0)