1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
// Copyright 2017 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.devtools.build.lib.rules.java;
import static com.google.devtools.build.lib.util.Preconditions.checkNotNull;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.actions.ParameterFile.ParameterFileType;
import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.analysis.actions.CustomCommandLine;
import com.google.devtools.build.lib.analysis.actions.CustomCommandLine.VectorArg;
import com.google.devtools.build.lib.analysis.actions.ParamFileInfo;
import com.google.devtools.build.lib.analysis.actions.SpawnAction;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.rules.java.JavaConfiguration.OneVersionEnforcementLevel;
import com.google.devtools.build.lib.util.Preconditions;
/** Utility for generating a call to the one-version binary. */
public final class OneVersionCheckActionBuilder {
private OneVersionCheckActionBuilder() {}
private OneVersionEnforcementLevel enforcementLevel;
private Artifact outputArtifact;
private JavaToolchainProvider javaToolchain;
private NestedSet<Artifact> jarsToCheck;
public static OneVersionCheckActionBuilder newBuilder() {
return new OneVersionCheckActionBuilder();
}
public OneVersionCheckActionBuilder useToolchain(JavaToolchainProvider toolchain) {
javaToolchain = toolchain;
return this;
}
public OneVersionCheckActionBuilder checkJars(NestedSet<Artifact> jarsToCheck) {
this.jarsToCheck = jarsToCheck;
return this;
}
public OneVersionCheckActionBuilder outputArtifact(Artifact outputArtifact) {
this.outputArtifact = outputArtifact;
return this;
}
public OneVersionCheckActionBuilder withEnforcementLevel(
OneVersionEnforcementLevel enforcementLevel) {
Preconditions.checkArgument(
enforcementLevel != OneVersionEnforcementLevel.OFF,
"one version enforcement actions shouldn't be built if the enforcement "
+ "level is set to off");
this.enforcementLevel = enforcementLevel;
return this;
}
public Artifact build(RuleContext ruleContext) {
Preconditions.checkNotNull(enforcementLevel);
Preconditions.checkNotNull(outputArtifact);
Preconditions.checkNotNull(javaToolchain);
Preconditions.checkNotNull(jarsToCheck);
Artifact oneVersionTool = javaToolchain.getOneVersionBinary();
Artifact oneVersionWhitelist = javaToolchain.getOneVersionWhitelist();
if (oneVersionTool == null || oneVersionWhitelist == null) {
ruleContext.ruleError(
String.format(
"one version enforcement was requested but it is not supported by the current "
+ "Java toolchain '%s'; see the "
+ "java_toolchain.oneversion and java_toolchain.oneversion_whitelist "
+ "attributes",
javaToolchain.getToolchainLabel()));
return outputArtifact;
}
CustomCommandLine.Builder oneVersionArgsBuilder =
CustomCommandLine.builder()
.addExecPath("--output", outputArtifact)
.addExecPath("--whitelist", oneVersionWhitelist);
if (enforcementLevel == OneVersionEnforcementLevel.WARNING) {
oneVersionArgsBuilder.add("--succeed_on_found_violations");
}
oneVersionArgsBuilder.addAll(
"--inputs",
VectorArg.of(jarsToCheck).mapped(OneVersionCheckActionBuilder::jarAndTargetArg));
CustomCommandLine oneVersionArgs = oneVersionArgsBuilder.build();
ruleContext.registerAction(
new SpawnAction.Builder()
.addOutput(outputArtifact)
.addInput(oneVersionWhitelist)
.addTransitiveInputs(jarsToCheck)
.setExecutable(oneVersionTool)
.addCommandLine(
oneVersionArgs,
ParamFileInfo.builder(ParameterFileType.SHELL_QUOTED).setUseAlways(true).build())
.setMnemonic("JavaOneVersion")
.setProgressMessage("Checking for one-version violations in %s", ruleContext.getLabel())
.build(ruleContext));
return outputArtifact;
}
private static String jarAndTargetArg(Artifact jar) {
return jar.getExecPathString() + "," + getArtifactOwnerGeneralizedLabel(jar);
}
private static String getArtifactOwnerGeneralizedLabel(Artifact artifact) {
Label label = checkNotNull(artifact.getArtifactOwner(), artifact).getLabel();
return
label.getPackageIdentifier().getRepository().isDefault()
|| label.getPackageIdentifier().getRepository().isMain()
? label.toString()
// Escape '@' prefix for .params file.
: "@" + label;
}
}
|