/** Constructs the RuleConfiguredTarget instance based on the values set for this Builder. */ public ConfiguredTarget build() { if (ruleContext.getConfiguration().enforceConstraints()) { checkConstraints(); } if (ruleContext.hasErrors()) { return null; } FilesToRunProvider filesToRunProvider = new FilesToRunProvider( ruleContext.getLabel(), RuleContext.getFilesToRun(runfilesSupport, filesToBuild), runfilesSupport, executable); add(FileProvider.class, new FileProvider(ruleContext.getLabel(), filesToBuild)); add(FilesToRunProvider.class, filesToRunProvider); if (runfilesSupport != null) { // If a binary is built, build its runfiles, too addOutputGroup(OutputGroupProvider.HIDDEN_TOP_LEVEL, runfilesSupport.getRunfilesMiddleman()); } else if (providers.get(RunfilesProvider.class) != null) { // If we don't have a RunfilesSupport (probably because this is not a binary rule), we still // want to build the files this rule contributes to runfiles of dependent rules so that we // report an error if one of these is broken. // // Note that this is a best-effort thing: there is .getDataRunfiles() and all the language- // specific *RunfilesProvider classes, which we don't add here for reasons that are lost in // the mists of time. addOutputGroup( OutputGroupProvider.HIDDEN_TOP_LEVEL, ((RunfilesProvider) providers.get(RunfilesProvider.class)) .getDefaultRunfiles() .getAllArtifacts()); } // Create test action and artifacts if target was successfully initialized // and is a test. if (TargetUtils.isTestRule(ruleContext.getTarget())) { Preconditions.checkState(runfilesSupport != null); add(TestProvider.class, initializeTestProvider(filesToRunProvider)); } add(ExtraActionArtifactsProvider.class, initializeExtraActions()); if (!outputGroupBuilders.isEmpty()) { ImmutableMap.Builder<String, NestedSet<Artifact>> outputGroups = ImmutableMap.builder(); for (Map.Entry<String, NestedSetBuilder<Artifact>> entry : outputGroupBuilders.entrySet()) { outputGroups.put(entry.getKey(), entry.getValue().build()); } add(OutputGroupProvider.class, new OutputGroupProvider(outputGroups.build())); } return new RuleConfiguredTarget( ruleContext, mandatoryStampFiles, skylarkProviders.build(), providers); }
private static void addOutputGroups( Object value, Location loc, RuleConfiguredTargetBuilder builder) throws EvalException { Map<String, SkylarkValue> outputGroups = SkylarkType.castMap(value, String.class, SkylarkValue.class, "output_groups"); for (String outputGroup : outputGroups.keySet()) { SkylarkValue objects = outputGroups.get(outputGroup); NestedSet<Artifact> artifacts; String typeErrorMessage = "Output group '%s' is of unexpected type. " + "Should be list or set of Files, but got '%s' instead."; if (objects instanceof SkylarkList) { NestedSetBuilder<Artifact> nestedSetBuilder = NestedSetBuilder.stableOrder(); for (Object o : (SkylarkList) objects) { if (o instanceof Artifact) { nestedSetBuilder.add((Artifact) o); } else { throw new EvalException( loc, String.format( typeErrorMessage, outputGroup, "list with an element of " + EvalUtils.getDataTypeNameFromClass(o.getClass()))); } } artifacts = nestedSetBuilder.build(); } else { artifacts = SkylarkType.cast( objects, SkylarkNestedSet.class, Artifact.class, loc, typeErrorMessage, outputGroup, EvalUtils.getDataTypeName(objects, true)) .getSet(Artifact.class); } builder.addOutputGroup(outputGroup, artifacts); } }