2222import com .google .devtools .build .lib .actions .Artifact ;
2323import com .google .devtools .build .lib .actions .CommandLines ;
2424import com .google .devtools .build .lib .actions .MutableActionGraph .ActionConflictException ;
25- import com .google .devtools .build .lib .analysis .AliasProvider ;
2625import com .google .devtools .build .lib .analysis .CommandConstructor ;
2726import com .google .devtools .build .lib .analysis .CommandHelper ;
2827import com .google .devtools .build .lib .analysis .ConfigurationMakeVariableContext ;
5049import com .google .devtools .build .lib .util .OnDemandString ;
5150import com .google .devtools .build .lib .util .Pair ;
5251import com .google .devtools .build .lib .vfs .PathFragment ;
52+ import com .google .errorprone .annotations .ForOverride ;
5353import java .util .List ;
5454import java .util .Map ;
5555import javax .annotation .Nullable ;
5656
5757/**
58- * A base implementation of genrule, to be used by specific implementing rules which can change some
59- * of the semantics around when the execution info and inputs are changed .
58+ * A base implementation of genrule, to be used by specific implementing rules which can change the
59+ * semantics of {@link #isStampingEnabled} and {@link #collectSources} .
6060 */
6161public abstract class GenRuleBase implements RuleConfiguredTargetFactory {
6262
63- /**
64- * Returns {@code true} if the rule should be stamped.
65- *
66- * <p>Genrule implementations can set this based on the rule context, including by defining their
67- * own attributes over and above what is present in {@link GenRuleBaseRule}.
68- */
69- protected abstract boolean isStampingEnabled (RuleContext ruleContext );
70-
71- /** Collects sources from src attribute. */
72- protected ImmutableMap <Label , NestedSet <Artifact >> collectSources (
73- List <? extends TransitiveInfoCollection > srcs ) throws RuleErrorException {
74- ImmutableMap .Builder <Label , NestedSet <Artifact >> labelMap = ImmutableMap .builder ();
75-
76- for (TransitiveInfoCollection dep : srcs ) {
77- NestedSet <Artifact > files = dep .getProvider (FileProvider .class ).getFilesToBuild ();
78- labelMap .put (AliasProvider .getDependencyLabel (dep ), files );
79- }
80-
81- return labelMap .build ();
82- }
83-
84- enum CommandType {
85- BASH ,
86- WINDOWS_BATCH ,
87- WINDOWS_POWERSHELL ,
88- }
89-
90- @ Nullable
91- private static Pair <CommandType , String > determineCommandTypeAndAttribute (
92- RuleContext ruleContext ) {
93- AttributeMap attributeMap = ruleContext .attributes ();
94- if (ruleContext .isExecutedOnWindows ()) {
95- if (attributeMap .isAttributeValueExplicitlySpecified ("cmd_ps" )) {
96- return Pair .of (CommandType .WINDOWS_POWERSHELL , "cmd_ps" );
97- }
98- if (attributeMap .isAttributeValueExplicitlySpecified ("cmd_bat" )) {
99- return Pair .of (CommandType .WINDOWS_BATCH , "cmd_bat" );
100- }
101- }
102- if (attributeMap .isAttributeValueExplicitlySpecified ("cmd_bash" )) {
103- return Pair .of (CommandType .BASH , "cmd_bash" );
104- }
105- if (attributeMap .isAttributeValueExplicitlySpecified ("cmd" )) {
106- return Pair .of (CommandType .BASH , "cmd" );
107- }
108- ruleContext .attributeError (
109- "cmd" ,
110- "missing value for `cmd` attribute, you can also set `cmd_ps` or `cmd_bat` on"
111- + " Windows and `cmd_bash` on other platforms." );
112- return null ;
113- }
114-
11563 @ Override
11664 @ Nullable
117- public ConfiguredTarget create (RuleContext ruleContext )
65+ public final ConfiguredTarget create (RuleContext ruleContext )
11866 throws InterruptedException , RuleErrorException , ActionConflictException {
11967 NestedSet <Artifact > filesToBuild =
12068 NestedSetBuilder .wrap (Order .STABLE_ORDER , ruleContext .getOutputArtifacts ());
@@ -143,7 +91,9 @@ public ConfiguredTarget create(RuleContext ruleContext)
14391 // The CommandHelper class makes an explicit copy of this in the constructor, so flattening
14492 // here should be benign.
14593 CommandHelper commandHelper =
146- commandHelperBuilder (ruleContext )
94+ CommandHelper .builder (ruleContext )
95+ .addToolDependencies ("tools" )
96+ .addToolDependencies ("toolchains" )
14797 .addLabelMap (
14898 labelMap .entrySet ().stream ()
14999 .collect (toImmutableMap (Map .Entry ::getKey , e -> e .getValue ().toList ())))
@@ -165,7 +115,7 @@ public ConfiguredTarget create(RuleContext ruleContext)
165115 ruleContext ,
166116 resolvedSrcs ,
167117 filesToBuild ,
168- /* makeVariableSuppliers = */ ImmutableList .of (),
118+ /* makeVariableSuppliers= */ ImmutableList .of (),
169119 expandToWindowsPath );
170120 String command =
171121 ruleContext
@@ -277,10 +227,49 @@ public String toString() {
277227 .build ();
278228 }
279229
280- protected CommandHelper .Builder commandHelperBuilder (RuleContext ruleContext ) {
281- return CommandHelper .builder (ruleContext )
282- .addToolDependencies ("tools" )
283- .addToolDependencies ("toolchains" );
230+ /**
231+ * Returns {@code true} if the rule should be stamped.
232+ *
233+ * <p>Genrule implementations can set this based on the rule context, including by defining their
234+ * own attributes over and above what is present in {@link GenRuleBaseRule}.
235+ */
236+ @ ForOverride
237+ protected abstract boolean isStampingEnabled (RuleContext ruleContext );
238+
239+ /** Collects sources from src attribute. */
240+ @ ForOverride
241+ protected abstract ImmutableMap <Label , NestedSet <Artifact >> collectSources (
242+ List <? extends TransitiveInfoCollection > srcs ) throws RuleErrorException ;
243+
244+ private enum CommandType {
245+ BASH ,
246+ WINDOWS_BATCH ,
247+ WINDOWS_POWERSHELL ,
248+ }
249+
250+ @ Nullable
251+ private static Pair <CommandType , String > determineCommandTypeAndAttribute (
252+ RuleContext ruleContext ) {
253+ AttributeMap attributeMap = ruleContext .attributes ();
254+ if (ruleContext .isExecutedOnWindows ()) {
255+ if (attributeMap .isAttributeValueExplicitlySpecified ("cmd_ps" )) {
256+ return Pair .of (CommandType .WINDOWS_POWERSHELL , "cmd_ps" );
257+ }
258+ if (attributeMap .isAttributeValueExplicitlySpecified ("cmd_bat" )) {
259+ return Pair .of (CommandType .WINDOWS_BATCH , "cmd_bat" );
260+ }
261+ }
262+ if (attributeMap .isAttributeValueExplicitlySpecified ("cmd_bash" )) {
263+ return Pair .of (CommandType .BASH , "cmd_bash" );
264+ }
265+ if (attributeMap .isAttributeValueExplicitlySpecified ("cmd" )) {
266+ return Pair .of (CommandType .BASH , "cmd" );
267+ }
268+ ruleContext .attributeError (
269+ "cmd" ,
270+ "missing value for `cmd` attribute, you can also set `cmd_ps` or `cmd_bat` on"
271+ + " Windows and `cmd_bash` on other platforms." );
272+ return null ;
284273 }
285274
286275 /**
@@ -299,14 +288,14 @@ private static Artifact getExecutable(RuleContext ruleContext, NestedSet<Artifac
299288 * Implementation of {@link ConfigurationMakeVariableContext} used to expand variables in a
300289 * genrule command string.
301290 */
302- protected static class CommandResolverContext extends ConfigurationMakeVariableContext {
291+ private static final class CommandResolverContext extends ConfigurationMakeVariableContext {
303292
304293 private final RuleContext ruleContext ;
305294 private final NestedSet <Artifact > resolvedSrcs ;
306295 private final NestedSet <Artifact > filesToBuild ;
307296 private final boolean windowsPath ;
308297
309- public CommandResolverContext (
298+ CommandResolverContext (
310299 RuleContext ruleContext ,
311300 NestedSet <Artifact > resolvedSrcs ,
312301 NestedSet <Artifact > filesToBuild ,
@@ -323,10 +312,6 @@ public CommandResolverContext(
323312 this .windowsPath = windowsPath ;
324313 }
325314
326- public RuleContext getRuleContext () {
327- return ruleContext ;
328- }
329-
330315 @ Override
331316 public String lookupVariable (String variableName )
332317 throws ExpansionException , InterruptedException {
@@ -393,15 +378,13 @@ private String lookupVariableImpl(String variableName)
393378 * Returns the path of the sole element "artifacts", generating an exception with an informative
394379 * error message iff the set is not a singleton. Used to expand "$<", "$@".
395380 */
396- private static final String expandSingletonArtifact (
381+ private static String expandSingletonArtifact (
397382 NestedSet <Artifact > artifacts , String variable , String artifactName )
398383 throws ExpansionException {
399384 if (artifacts .isEmpty ()) {
400- throw new ExpansionException ("variable '" + variable
401- + "' : no " + artifactName );
385+ throw new ExpansionException ("variable '" + variable + "' : no " + artifactName );
402386 } else if (!artifacts .isSingleton ()) {
403- throw new ExpansionException ("variable '" + variable
404- + "' : more than one " + artifactName );
387+ throw new ExpansionException ("variable '" + variable + "' : more than one " + artifactName );
405388 }
406389 return artifacts .getSingleton ().getExecPathString ();
407390 }
0 commit comments