Skip to content

Commit 65a9638

Browse files
committed
Improve merging in all_crate_deps
1 parent 831ef76 commit 65a9638

7 files changed

Lines changed: 297 additions & 63 deletions

File tree

rs/BUILD.bazel

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ bzl_library(
1313
"//rs/private:downloader",
1414
"//rs/private:git_repository",
1515
"//rs/private:resolver",
16+
"//rs/private:select_utils",
1617
"//rs/private:semver",
1718
"//rs/private:toml2json",
1819
"@aspect_tools_telemetry_report//:defs.bzl",
@@ -32,47 +33,68 @@ bzl_library(
3233
name = "cargo_build_script",
3334
srcs = ["cargo_build_script.bzl"],
3435
visibility = ["//visibility:public"],
35-
deps = ["@rules_rust//cargo/private:bzl_lib"],
36+
deps = [
37+
"@bazel_features//:features",
38+
"@rules_rust//cargo/private:bzl_lib",
39+
],
3640
)
3741

3842
bzl_library(
3943
name = "rust_binary",
4044
srcs = ["rust_binary.bzl"],
4145
visibility = ["//visibility:public"],
42-
deps = ["@rules_rust//rust:bzl_lib"],
46+
deps = [
47+
"@bazel_features//:features",
48+
"@rules_rust//rust:bzl_lib",
49+
],
4350
)
4451

4552
bzl_library(
4653
name = "rust_library",
4754
srcs = ["rust_library.bzl"],
4855
visibility = ["//visibility:public"],
49-
deps = ["@rules_rust//rust:bzl_lib"],
56+
deps = [
57+
"@bazel_features//:features",
58+
"@rules_rust//rust:bzl_lib",
59+
],
5060
)
5161

5262
bzl_library(
5363
name = "rust_proc_macro",
5464
srcs = ["rust_proc_macro.bzl"],
5565
visibility = ["//visibility:public"],
56-
deps = ["@rules_rust//rust:bzl_lib"],
66+
deps = [
67+
"@bazel_features//:features",
68+
"@rules_rust//rust:bzl_lib",
69+
],
5770
)
5871

5972
bzl_library(
6073
name = "rust_test",
6174
srcs = ["rust_test.bzl"],
6275
visibility = ["//visibility:public"],
63-
deps = ["@rules_rust//rust:bzl_lib"],
76+
deps = [
77+
"@bazel_features//:features",
78+
"@rules_rust//rust:bzl_lib",
79+
],
6480
)
6581

6682
bzl_library(
6783
name = "rust_shared_library",
6884
srcs = ["rust_shared_library.bzl"],
6985
visibility = ["//visibility:public"],
70-
deps = ["@rules_rust//rust:bzl_lib"],
86+
deps = [
87+
"@bazel_features//:features",
88+
"@rules_rust//rust:bzl_lib",
89+
],
7190
)
7291

7392
bzl_library(
7493
name = "rust_static_library",
7594
srcs = ["rust_static_library.bzl"],
7695
visibility = ["//visibility:public"],
77-
deps = ["@rules_rust//rust:bzl_lib"],
96+
deps = [
97+
"@bazel_features//:features",
98+
"@rules_rust//rust:bzl_lib",
99+
],
78100
)

rs/extensions.bzl

Lines changed: 60 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ load("//rs/private:downloader.bzl", "download_metadata_for_git_crates", "downloa
1111
load("//rs/private:git_repository.bzl", "git_repository")
1212
load("//rs/private:repository_utils.bzl", "render_select")
1313
load("//rs/private:resolver.bzl", "resolve")
14+
load("//rs/private:select_utils.bzl", "compute_select")
1415
load("//rs/private:semver.bzl", "select_matching_version")
1516
load("//rs/private:toml2json.bzl", "run_toml2json")
1617

@@ -31,6 +32,31 @@ def _platform(triple, use_experimental_platforms):
3132
def _select(items):
3233
return {k: sorted(v) for k, v in items.items()}
3334

35+
def _shared_and_per_platform(platform_items, use_experimental_platforms):
36+
if not platform_items:
37+
return [], {}
38+
39+
by_platform = {}
40+
for triple, items in platform_items.items():
41+
platform = _platform(triple, use_experimental_platforms)
42+
existing = by_platform.get(platform)
43+
if existing == None:
44+
by_platform[platform] = set(items)
45+
else:
46+
existing.update(items)
47+
48+
deps, per_platform = compute_select([], by_platform)
49+
return sorted(deps), per_platform
50+
51+
def _render_string_list(items):
52+
return ",\n ".join(['"%s"' % item for item in sorted(items)])
53+
54+
def _render_string_list_dict(items_by_key):
55+
rendered = []
56+
for key, items in sorted(items_by_key.items()):
57+
rendered.append('"%s": [%s]' % (key, ", ".join(['"%s"' % item for item in sorted(items)])))
58+
return ",\n ".join(rendered)
59+
3460
def _cfg_match_info_for_target(target, platform_cfg_attrs, cfg_match_cache):
3561
match_info = cfg_match_cache.get(target)
3662
if match_info:
@@ -845,10 +871,20 @@ filegroup(
845871
),
846872
)
847873

874+
resolved_platforms = []
875+
for triple in platform_triples:
876+
platform = _platform(triple, use_experimental_platforms)
877+
if platform not in resolved_platforms:
878+
resolved_platforms.append(platform)
879+
848880
defs_bzl_contents = \
849881
"""load(":data.bzl", "DEP_DATA")
850882
load("@rules_rs//rs/private:all_crate_deps.bzl", _all_crate_deps = "all_crate_deps")
851883
884+
_PLATFORMS = [
885+
{platforms}
886+
]
887+
852888
def aliases(package_name = None):
853889
dep_data = DEP_DATA.get(package_name or native.package_name())
854890
if not dep_data:
@@ -869,6 +905,7 @@ def all_crate_deps(
869905
870906
return _all_crate_deps(
871907
dep_data,
908+
platforms = _PLATFORMS,
872909
normal = normal,
873910
normal_dev = normal_dev,
874911
build = build,
@@ -880,7 +917,8 @@ RESOLVED_PLATFORMS = select({{
880917
"//conditions:default": ["@platforms//:incompatible"],
881918
}})
882919
""".format(
883-
target_compatible_with = ",\n ".join(['"%s": []' % _platform(triple, use_experimental_platforms) for triple in platform_triples]),
920+
platforms = _render_string_list(resolved_platforms),
921+
target_compatible_with = ",\n ".join(['"%s": []' % platform for platform in resolved_platforms]),
884922
this_repo = repr("@" + hub_name + "//:"),
885923
)
886924

@@ -939,9 +977,9 @@ RESOLVED_PLATFORMS = select({{
939977

940978
bazel_package = paths.join(workspace_package, package_dir)
941979

942-
deps, conditional_deps = render_select([], deps, use_experimental_platforms)
943-
build_deps, conditional_build_deps = render_select([], build_deps, use_experimental_platforms)
944-
dev_deps, conditional_dev_deps = render_select([], dev_deps, use_experimental_platforms)
980+
deps, deps_by_platform = _shared_and_per_platform(deps, use_experimental_platforms)
981+
build_deps, build_deps_by_platform = _shared_and_per_platform(build_deps, use_experimental_platforms)
982+
dev_deps, dev_deps_by_platform = _shared_and_per_platform(dev_deps, use_experimental_platforms)
945983

946984
workspace_dep_stanzas.append("""
947985
{bazel_package}: {{
@@ -950,13 +988,22 @@ RESOLVED_PLATFORMS = select({{
950988
}},
951989
"deps": [
952990
{deps}
953-
]{conditional_deps},
991+
],
992+
"deps_by_platform": {{
993+
{deps_by_platform}
994+
}},
954995
"build_deps": [
955996
{build_deps}
956-
]{conditional_build_deps},
997+
],
998+
"build_deps_by_platform": {{
999+
{build_deps_by_platform}
1000+
}},
9571001
"dev_deps": [
9581002
{dev_deps}
959-
]{conditional_dev_deps},
1003+
],
1004+
"dev_deps_by_platform": {{
1005+
{dev_deps_by_platform}
1006+
}},
9601007
"binaries": {{
9611008
{binaries}
9621009
}},
@@ -966,12 +1013,12 @@ RESOLVED_PLATFORMS = select({{
9661013
}},""".format(
9671014
bazel_package = repr(bazel_package),
9681015
aliases = ",\n ".join(['"%s": "%s"' % kv for kv in sorted(aliases.items())]),
969-
deps = ",\n ".join(['"%s"' % d for d in sorted(deps)]),
970-
conditional_deps = " + " + conditional_deps if conditional_deps else "",
971-
build_deps = ",\n ".join(['"%s"' % d for d in sorted(build_deps)]),
972-
conditional_build_deps = " + " + conditional_build_deps if conditional_build_deps else "",
973-
dev_deps = ",\n ".join(['"%s"' % d for d in sorted(dev_deps)]),
974-
conditional_dev_deps = " + " + conditional_dev_deps if conditional_dev_deps else "",
1016+
deps = _render_string_list(deps),
1017+
deps_by_platform = _render_string_list_dict(deps_by_platform),
1018+
build_deps = _render_string_list(build_deps),
1019+
build_deps_by_platform = _render_string_list_dict(build_deps_by_platform),
1020+
dev_deps = _render_string_list(dev_deps),
1021+
dev_deps_by_platform = _render_string_list_dict(dev_deps_by_platform),
9751022
binaries = ",\n ".join(['"%s": "%s"' % kv for kv in sorted(binaries.items())]),
9761023
shared_libraries = ",\n ".join(['"%s": "%s"' % kv for kv in sorted(shared_libraries.items())]),
9771024
))

rs/private/BUILD.bazel

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
load("@bazel_lib//:bzl_library.bzl", "bzl_library")
2+
load(":all_crate_deps_test.bzl", "all_crate_deps_tests")
23
load(":cfg_parser_test.bzl", "cfg_parser_tests")
34
load(":semver_test.bzl", "semver_select_tests")
45

6+
all_crate_deps_tests()
7+
58
cfg_parser_tests()
69

710
semver_select_tests()
@@ -10,7 +13,7 @@ bzl_library(
1013
name = "all_crate_deps",
1114
srcs = ["all_crate_deps.bzl"],
1215
visibility = ["//rs:__subpackages__"],
13-
deps = [],
16+
deps = [":select_utils"],
1417
)
1518

1619
bzl_library(
@@ -64,7 +67,10 @@ bzl_library(
6467
name = "repository_utils",
6568
srcs = ["repository_utils.bzl"],
6669
visibility = ["//rs:__subpackages__"],
67-
deps = [":semver"],
70+
deps = [
71+
":select_utils",
72+
":semver",
73+
],
6874
)
6975

7076
bzl_library(
@@ -176,6 +182,13 @@ bzl_library(
176182
name = "resolver",
177183
srcs = ["resolver.bzl"],
178184
visibility = ["//rs:__subpackages__"],
185+
deps = [":cfg_parser"],
186+
)
187+
188+
bzl_library(
189+
name = "select_utils",
190+
srcs = ["select_utils.bzl"],
191+
visibility = ["//rs:__subpackages__"],
179192
)
180193

181194
bzl_library(

rs/private/all_crate_deps.bzl

Lines changed: 52 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,67 @@
1+
load(":select_utils.bzl", "compute_select")
2+
13
def _filter_by_prefix(deps, prefix):
24
return [dep for dep in deps if dep.startswith(prefix)]
35

6+
def _kind_dep_spec(dep_data, kind):
7+
return (
8+
dep_data.get(kind, []),
9+
dep_data.get(kind + "_by_platform", {}),
10+
)
11+
12+
def merge_structured_dep_specs(specs, platforms, filter_prefix):
13+
merged_by_platform = {}
14+
merged_deps = set()
15+
16+
for platform in platforms:
17+
merged_by_platform[platform] = set()
18+
19+
for shared_items, per_platform_items in specs:
20+
for dep in shared_items:
21+
if not filter_prefix or dep.startswith(filter_prefix):
22+
merged_deps.add(dep)
23+
24+
for platform, deps in per_platform_items.items():
25+
filtered = _filter_by_prefix(deps, filter_prefix) if filter_prefix else deps
26+
if not filtered:
27+
continue
28+
29+
existing = merged_by_platform.get(platform)
30+
if existing == None:
31+
merged_by_platform[platform] = set(filtered)
32+
continue
33+
34+
existing.update(filtered)
35+
36+
deps, per_platform = compute_select(merged_deps, merged_by_platform)
37+
return sorted(deps), per_platform
38+
439
def all_crate_deps(
540
dep_data,
41+
platforms,
642
normal = False,
743
normal_dev = False,
844
build = False,
945
filter_prefix = None):
10-
to_return = []
11-
12-
deps = dep_data["deps"]
13-
build_deps = dep_data["build_deps"]
14-
dev_deps = dep_data["dev_deps"]
15-
16-
if filter_prefix:
17-
deps = _filter_by_prefix(deps, filter_prefix)
18-
build_deps = _filter_by_prefix(build_deps, filter_prefix)
19-
dev_deps = _filter_by_prefix(dev_deps, filter_prefix)
46+
specs = []
2047

2148
if normal_dev:
22-
to_return += dev_deps
49+
specs.append(_kind_dep_spec(dep_data, "dev_deps"))
2350

2451
if build:
25-
to_return += build_deps
52+
specs.append(_kind_dep_spec(dep_data, "build_deps"))
53+
54+
if normal or not specs:
55+
specs.append(_kind_dep_spec(dep_data, "deps"))
2656

27-
if normal or not to_return:
28-
to_return += deps
57+
deps, per_platform = merge_structured_dep_specs(
58+
specs,
59+
platforms,
60+
filter_prefix,
61+
)
62+
if not per_platform:
63+
return deps
2964

30-
return to_return
65+
branches = {platform: deps for platform, deps in sorted(per_platform.items())}
66+
branches["//conditions:default"] = []
67+
return deps + select(branches)

0 commit comments

Comments
 (0)