Skip to content

Commit b9fbfc1

Browse files
committed
Allow artifacts from aspects to be excluded
When using a `java_proto_library` as a dependency of a `java_export` the generated jar contains classes from protobuf, which is unexpected. This PR allows users to specify a list of workspaces to be excluded from the generated jar, and that allows us to filter the class files generated by these aspects.
1 parent 1039709 commit b9fbfc1

File tree

11 files changed

+277
-17
lines changed

11 files changed

+277
-17
lines changed

WORKSPACE

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -586,6 +586,7 @@ maven_install(
586586
)
587587

588588
load("@m2local_testing_repin//:defs.bzl", "pinned_maven_install")
589+
589590
pinned_maven_install()
590591

591592
maven_install(
@@ -698,3 +699,27 @@ rbe_preconfig(
698699
load("//migration:maven_jar_migrator_deps.bzl", "maven_jar_migrator_repositories")
699700

700701
maven_jar_migrator_repositories()
702+
703+
# Located at the end, because it's only used in tests
704+
705+
http_archive(
706+
name = "com_google_protobuf",
707+
sha256 = "6fc9b6efc18acb2fd5fb3bcf981572539c3432600042b662a162c1226b362426",
708+
strip_prefix = "protobuf-21.10",
709+
url = "https://github.com/protocolbuffers/protobuf/releases/download/v21.10/protobuf-all-21.10.tar.gz",
710+
)
711+
712+
load("@com_google_protobuf//:protobuf_deps.bzl", "protobuf_deps")
713+
714+
protobuf_deps()
715+
716+
maven_install(
717+
name = "java_export_exclusion_testing",
718+
artifacts = [
719+
"com.google.protobuf:protobuf-java:3.6.1",
720+
],
721+
maven_install_json = "@rules_jvm_external//tests/custom_maven_install:java_export_exclusion_testing_install.json",
722+
repositories = [
723+
"https://repo1.maven.org/maven2",
724+
],
725+
)

docs/api.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,8 @@ Generate a javadoc from all the `deps`
5252
## java_export
5353

5454
<pre>
55-
java_export(<a href="#java_export-name">name</a>, <a href="#java_export-maven_coordinates">maven_coordinates</a>, <a href="#java_export-deploy_env">deploy_env</a>, <a href="#java_export-pom_template">pom_template</a>, <a href="#java_export-visibility">visibility</a>, <a href="#java_export-tags">tags</a>, <a href="#java_export-testonly">testonly</a>, <a href="#java_export-kwargs">kwargs</a>)
55+
java_export(<a href="#java_export-name">name</a>, <a href="#java_export-maven_coordinates">maven_coordinates</a>, <a href="#java_export-deploy_env">deploy_env</a>, <a href="#java_export-excluded_workspaces">excluded_workspaces</a>, <a href="#java_export-pom_template">pom_template</a>, <a href="#java_export-visibility">visibility</a>,
56+
<a href="#java_export-tags">tags</a>, <a href="#java_export-testonly">testonly</a>, <a href="#java_export-kwargs">kwargs</a>)
5657
</pre>
5758

5859
Extends `java_library` to allow maven artifacts to be uploaded.
@@ -105,6 +106,7 @@ Generated rules:
105106
| <a id="java_export-name"></a>name | A unique name for this target | none |
106107
| <a id="java_export-maven_coordinates"></a>maven_coordinates | The maven coordinates for this target. | none |
107108
| <a id="java_export-deploy_env"></a>deploy_env | A list of labels of Java targets to exclude from the generated jar. [<code>java_binary</code>](https://bazel.build/reference/be/java#java_binary) targets are *not* supported. | <code>[]</code> |
109+
| <a id="java_export-excluded_workspaces"></a>excluded_workspaces | A dict of strings representing the workspace names of artifacts that should not be included in the maven jar to a <code>Label</code> pointing to the dependency that workspace should be replaced by, or <code>None</code> if the exclusion shouldn't be replaced with an extra dependency. | <code>{"com_google_protobuf": None}</code> |
108110
| <a id="java_export-pom_template"></a>pom_template | The template to be used for the pom.xml file. | <code>None</code> |
109111
| <a id="java_export-visibility"></a>visibility | The visibility of the target | <code>None</code> |
110112
| <a id="java_export-tags"></a>tags | <p align="center"> - </p> | <code>[]</code> |

private/rules/java_export.bzl

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
load(":javadoc.bzl", "javadoc")
22
load(":maven_bom_fragment.bzl", "maven_bom_fragment")
3-
load(":maven_project_jar.bzl", "maven_project_jar")
3+
load(":maven_project_jar.bzl", "DEFAULT_EXCLUDED_WORKSPACES", "maven_project_jar")
44
load(":maven_publish.bzl", "maven_publish")
55
load(":pom_file.bzl", "pom_file")
66

77
def java_export(
88
name,
99
maven_coordinates,
1010
deploy_env = [],
11+
excluded_workspaces = {name: None for name in DEFAULT_EXCLUDED_WORKSPACES},
1112
pom_template = None,
1213
visibility = None,
1314
tags = [],
@@ -61,6 +62,10 @@ def java_export(
6162
deploy_env: A list of labels of Java targets to exclude from the generated jar.
6263
[`java_binary`](https://bazel.build/reference/be/java#java_binary) targets are *not*
6364
supported.
65+
excluded_workspaces: A dict of strings representing the workspace names of artifacts
66+
that should not be included in the maven jar to a `Label` pointing to the dependency
67+
that workspace should be replaced by, or `None` if the exclusion shouldn't be replaced
68+
with an extra dependency.
6469
visibility: The visibility of the target
6570
kwargs: These are passed to [`java_library`](https://bazel.build/reference/be/java#java_library),
6671
and so may contain any valid parameter for that rule.
@@ -85,6 +90,7 @@ def java_export(
8590
maven_coordinates,
8691
lib_name,
8792
deploy_env,
93+
excluded_workspaces,
8894
pom_template,
8995
visibility,
9096
tags,
@@ -97,6 +103,7 @@ def maven_export(
97103
maven_coordinates,
98104
lib_name,
99105
deploy_env = [],
106+
excluded_workspaces = {},
100107
pom_template = None,
101108
visibility = None,
102109
tags = [],
@@ -150,6 +157,10 @@ def maven_export(
150157
deploy_env: A list of labels of Java targets to exclude from the generated jar.
151158
[`java_binary`](https://bazel.build/reference/be/java#java_binary) targets are *not*
152159
supported.
160+
excluded_workspaces: A dict of strings representing the workspace names of artifacts
161+
that should not be included in the maven jar to a `Label` pointing to the dependency
162+
that workspace should be replaced by, or `None` if the exclusion shouldn't be replaced
163+
with an extra dependency.
153164
visibility: The visibility of the target
154165
kwargs: These are passed to [`java_library`](https://bazel.build/reference/be/java#java_library),
155166
and so may contain any valid parameter for that rule.
@@ -158,13 +169,19 @@ def maven_export(
158169

159170
# Sometimes users pass `None` as the value for attributes. Guard against this
160171
deploy_env = deploy_env if deploy_env else []
172+
excluded_workspaces = excluded_workspaces if excluded_workspaces else []
161173
javadocopts = javadocopts if javadocopts else []
174+
tags = tags if tags else []
175+
176+
additional_dependencies = {label: name for (name, label) in excluded_workspaces.items() if label}
162177

163178
# Merge the jars to create the maven project jar
164179
maven_project_jar(
165180
name = "%s-project" % name,
166181
target = ":%s" % lib_name,
167182
deploy_env = deploy_env,
183+
excluded_workspaces = excluded_workspaces.keys(),
184+
additional_dependencies = additional_dependencies,
168185
visibility = visibility,
169186
tags = tags + maven_coordinates_tags,
170187
testonly = testonly,
@@ -210,6 +227,7 @@ def maven_export(
210227
name = "%s-pom" % name,
211228
target = ":%s" % lib_name,
212229
pom_template = pom_template,
230+
additional_dependencies = additional_dependencies,
213231
visibility = visibility,
214232
tags = tags,
215233
testonly = testonly,

private/rules/kt_jvm_export.bzl

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
load("@io_bazel_rules_kotlin//kotlin:jvm.bzl", "kt_jvm_library")
2-
load("//private/rules:java_export.bzl", "maven_export")
2+
load(":java_export.bzl", "maven_export")
3+
load(":maven_project_jar.bzl", "DEFAULT_EXCLUDED_WORKSPACES")
34

45
KOTLIN_STDLIB = "@com_github_jetbrains_kotlin//:kotlin-stdlib"
56

67
def kt_jvm_export(
78
name,
89
maven_coordinates,
910
deploy_env = [],
11+
excluded_workspaces = {name: None for name in DEFAULT_EXCLUDED_WORKSPACES},
1012
pom_template = None,
1113
visibility = None,
1214
tags = [],
@@ -83,13 +85,14 @@ def kt_jvm_export(
8385
)
8486

8587
maven_export(
86-
name,
87-
maven_coordinates,
88-
lib_name,
89-
updated_deploy_env,
90-
pom_template,
91-
visibility,
92-
tags,
93-
testonly,
94-
javadocopts,
88+
name = name,
89+
maven_coordinates = maven_coordinates,
90+
lib_name = lib_name,
91+
deploy_env = updated_deploy_env,
92+
excluded_workspaces = excluded_workspaces,
93+
pom_template = pom_template,
94+
visibility = visibility,
95+
tags = tags,
96+
testonly = testonly,
97+
javadocopts = javadocopts,
9598
)

private/rules/maven_project_jar.bzl

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,25 @@
11
load(":has_maven_deps.bzl", "MavenInfo", "calculate_artifact_jars", "calculate_artifact_source_jars", "has_maven_deps")
2+
load(":maven_utils.bzl", "determine_additional_dependencies")
3+
4+
DEFAULT_EXCLUDED_WORKSPACES = [
5+
# Note: we choose to drop the dependency entirely because
6+
# we can't be sure which coordinate the user has
7+
# chosen for protobuf.
8+
"com_google_protobuf",
9+
]
10+
11+
def _strip_excluded_workspace_jars(jar_files, excluded_workspaces):
12+
to_return = []
13+
14+
for jar in jar_files:
15+
owner = jar.owner
16+
17+
if owner and owner.workspace_name in excluded_workspaces:
18+
continue
19+
20+
to_return.append(jar)
21+
22+
return to_return
223

324
def _combine_jars(ctx, merge_jars, inputs, excludes, output):
425
args = ctx.actions.args()
@@ -20,7 +41,20 @@ def _maven_project_jar_impl(ctx):
2041

2142
# Identify the subset of JavaInfo to include in the artifact
2243
artifact_jars = calculate_artifact_jars(info)
23-
artifact_srcs = calculate_artifact_source_jars(info)
44+
45+
# We need to know the additional dependencies we might need to add
46+
additional_deps = [dep[JavaInfo] for dep in determine_additional_dependencies(artifact_jars, ctx.attr.additional_dependencies)]
47+
48+
# And now we strip out dependencies if they're not needed
49+
artifact_jars = _strip_excluded_workspace_jars(
50+
artifact_jars,
51+
ctx.attr.excluded_workspaces,
52+
)
53+
54+
artifact_srcs = _strip_excluded_workspace_jars(
55+
calculate_artifact_source_jars(info),
56+
ctx.attr.excluded_workspaces,
57+
)
2458

2559
# Merge together all the binary jars
2660
bin_jar = ctx.actions.declare_file("%s.jar" % ctx.label.name)
@@ -84,7 +118,7 @@ def _maven_project_jar_impl(ctx):
84118
source_jar = src_jar,
85119

86120
# TODO: calculate runtime_deps too
87-
deps = info.dep_infos.to_list(),
121+
deps = info.dep_infos.to_list() + additional_deps,
88122
exports = exported_infos,
89123
)
90124

@@ -133,6 +167,18 @@ single artifact that other teams can download and use.
133167
],
134168
allow_empty = True,
135169
),
170+
"excluded_workspaces": attr.string_list(
171+
doc = "A list of bazel workspace names to exclude from the generated jar",
172+
allow_empty = True,
173+
default = DEFAULT_EXCLUDED_WORKSPACES,
174+
),
175+
"additional_dependencies": attr.label_keyed_string_dict(
176+
doc = "Mapping of `Label`s to the excluded workspace names. Note that this must match the values passed to the `pom_file` rule so the `pom.xml` correctly lists these dependencies.",
177+
allow_empty = True,
178+
providers = [
179+
[JavaInfo],
180+
],
181+
),
136182
# Bazel's own singlejar doesn't respect java service files,
137183
# so use our own.
138184
"_merge_jars": attr.label(

private/rules/maven_utils.bzl

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,3 +128,21 @@ def generate_pom(
128128
)
129129

130130
return out
131+
132+
def determine_additional_dependencies(jar_files, additional_dependencies):
133+
"""Takes a dict of {`Label`: workspace_name} and returns the `Label`s where any `jar_files match a `workspace_name."""
134+
to_return = []
135+
136+
for jar in jar_files:
137+
owner = jar.owner
138+
139+
# If we can't tell who the owner is, let's assume things are fine
140+
if not owner:
141+
continue
142+
143+
for (dep, name) in additional_dependencies.items():
144+
if (name == owner.workspace_name) and dep:
145+
if not dep in to_return:
146+
to_return.append(dep)
147+
148+
return to_return

private/rules/pom_file.bzl

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
load(":has_maven_deps.bzl", "MavenInfo", "has_maven_deps")
2-
load(":maven_utils.bzl", "generate_pom")
1+
load(":has_maven_deps.bzl", "MavenInfo", "calculate_artifact_jars", "has_maven_deps")
2+
load(":maven_utils.bzl", "determine_additional_dependencies", "generate_pom")
33

44
def _pom_file_impl(ctx):
55
# Ensure the target has coordinates
@@ -8,10 +8,18 @@ def _pom_file_impl(ctx):
88

99
info = ctx.attr.target[MavenInfo]
1010

11+
artifact_jars = calculate_artifact_jars(info)
12+
additional_deps = determine_additional_dependencies(artifact_jars, ctx.attr.additional_dependencies)
13+
14+
all_maven_deps = info.maven_deps.to_list()
15+
for dep in additional_deps:
16+
for coords in dep[MavenInfo].as_maven_dep.to_list():
17+
all_maven_deps.append(coords)
18+
1119
out = generate_pom(
1220
ctx,
1321
coordinates = info.coordinates,
14-
versioned_dep_coordinates = sorted(info.maven_deps.to_list()),
22+
versioned_dep_coordinates = sorted(all_maven_deps),
1523
pom_template = ctx.file.pom_template,
1624
out_name = "%s.xml" % ctx.label.name,
1725
)
@@ -53,5 +61,15 @@ The following substitutions are performed on the template file:
5361
has_maven_deps,
5462
],
5563
),
64+
"additional_dependencies": attr.label_keyed_string_dict(
65+
doc = "Mapping of `Label`s to the excluded workspace names",
66+
allow_empty = True,
67+
providers = [
68+
[JavaInfo],
69+
],
70+
aspects = [
71+
has_maven_deps,
72+
],
73+
),
5674
},
5775
)
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"__AUTOGENERATED_FILE_DO_NOT_MODIFY_THIS_FILE_MANUALLY": "THERE_IS_NO_DATA_ONLY_ZUUL",
3+
"__INPUT_ARTIFACTS_HASH": -908403006,
4+
"__RESOLVED_ARTIFACTS_HASH": -1289526812,
5+
"artifacts": {
6+
"com.google.protobuf:protobuf-java": {
7+
"shasums": {
8+
"jar": "fb66d913ff0578553b2e28a3338cbbbe2657e6cfe0e98d939f23aea219daf508"
9+
},
10+
"version": "3.6.1"
11+
}
12+
},
13+
"dependencies": {},
14+
"packages": {
15+
"com.google.protobuf:protobuf-java": [
16+
"com.google.protobuf",
17+
"com.google.protobuf.compiler"
18+
]
19+
},
20+
"repositories": {
21+
"https://repo1.maven.org/maven2/": [
22+
"com.google.protobuf:protobuf-java"
23+
]
24+
},
25+
"version": "2"
26+
}

tests/integration/java_export/BUILD

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,3 +144,50 @@ sh_test(
144144
"@bazel_tools//tools/bash/runfiles",
145145
],
146146
)
147+
148+
proto_library(
149+
name = "example_proto",
150+
srcs = ["example.proto"],
151+
deps = [
152+
# It's important that we pull our dep from `@com_google_protobuf`
153+
"@com_google_protobuf//:wrappers_proto",
154+
],
155+
)
156+
157+
java_proto_library(
158+
name = "example-proto-library",
159+
deps = [":example_proto"],
160+
)
161+
162+
java_export(
163+
name = "with-proto-dep",
164+
maven_coordinates = "com.example:example-with-proto:0.0.1",
165+
runtime_deps = [":example-proto-library"],
166+
)
167+
168+
java_export(
169+
name = "with-added-dependency",
170+
excluded_workspaces = {
171+
"com_google_protobuf": artifact(
172+
"com.google.protobuf:protobuf-java",
173+
repository_name = "java_export_exclusion_testing",
174+
),
175+
},
176+
maven_coordinates = "com.example:example-with-proto:0.0.1",
177+
runtime_deps = [":example-proto-library"],
178+
)
179+
180+
sh_test(
181+
name = "check-excluded-packages-are-excluded",
182+
srcs = [
183+
"check-excluded-packages-are-excluded.sh",
184+
],
185+
data = [
186+
":with-added-dependency-pom",
187+
":with-proto-dep",
188+
":with-proto-dep-pom",
189+
],
190+
deps = [
191+
"@bazel_tools//tools/bash/runfiles",
192+
],
193+
)

0 commit comments

Comments
 (0)