use of com.google.devtools.build.lib.syntax.EvalException in project bazel by bazelbuild.
the class SkylarkRuleConfiguredTargetBuilder method buildRule.
/**
* Create a Rule Configured Target from the ruleContext and the ruleImplementation. The
* registeredProviderTypes map indicates which keys in structs returned by skylark rules
* should be interpreted as native TransitiveInfoProvider instances of type (map value).
*/
public static ConfiguredTarget buildRule(RuleContext ruleContext, BaseFunction ruleImplementation, Map<String, Class<? extends TransitiveInfoProvider>> registeredProviderTypes) throws InterruptedException {
String expectFailure = ruleContext.attributes().get("expect_failure", Type.STRING);
try (Mutability mutability = Mutability.create("configured target")) {
SkylarkRuleContext skylarkRuleContext = new SkylarkRuleContext(ruleContext, null);
Environment env = Environment.builder(mutability).setCallerLabel(ruleContext.getLabel()).setGlobals(ruleContext.getRule().getRuleClassObject().getRuleDefinitionEnvironment().getGlobals()).setEventHandler(ruleContext.getAnalysisEnvironment().getEventHandler()).build();
// so we do *not* setLoadingPhase().
Object target = ruleImplementation.call(ImmutableList.<Object>of(skylarkRuleContext), ImmutableMap.<String, Object>of(), /*ast=*/
null, env);
if (ruleContext.hasErrors()) {
return null;
} else if (!(target instanceof SkylarkClassObject) && target != Runtime.NONE && !(target instanceof Iterable)) {
ruleContext.ruleError(String.format("Rule should return a struct or a list, but got %s", SkylarkType.typeOf(target)));
return null;
} else if (!expectFailure.isEmpty()) {
ruleContext.ruleError("Expected failure not found: " + expectFailure);
return null;
}
ConfiguredTarget configuredTarget = createTarget(ruleContext, target, registeredProviderTypes);
SkylarkProviderValidationUtil.checkOrphanArtifacts(ruleContext);
return configuredTarget;
} catch (EvalException e) {
addRuleToStackTrace(e, ruleContext.getRule(), ruleImplementation);
// If the error was expected, return an empty target.
if (!expectFailure.isEmpty() && getMessageWithoutStackTrace(e).matches(expectFailure)) {
return new com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder(ruleContext).add(RunfilesProvider.class, RunfilesProvider.EMPTY).build();
}
ruleContext.ruleError("\n" + e.print());
return null;
}
}
use of com.google.devtools.build.lib.syntax.EvalException in project bazel by bazelbuild.
the class SkylarkRuleConfiguredTargetBuilder method addSimpleProviders.
private static void addSimpleProviders(RuleConfiguredTargetBuilder builder, RuleContext ruleContext, Location loc, Artifact executable, Runfiles statelessRunfiles, Runfiles dataRunfiles, Runfiles defaultRunfiles, SkylarkClassObject defaultProvider) throws EvalException {
if ((statelessRunfiles != null) && (dataRunfiles != null || defaultRunfiles != null)) {
throw new EvalException(loc, "Cannot specify the provider 'runfiles' " + "together with 'data_runfiles' or 'default_runfiles'");
}
if (statelessRunfiles == null && dataRunfiles == null && defaultRunfiles == null) {
// No runfiles specified, set default
statelessRunfiles = Runfiles.EMPTY;
}
RunfilesProvider runfilesProvider = statelessRunfiles != null ? RunfilesProvider.simple(merge(statelessRunfiles, executable, ruleContext)) : RunfilesProvider.withData(// This is to keep skylark genrule consistent with the original genrule.
defaultRunfiles != null ? defaultRunfiles : Runfiles.EMPTY, dataRunfiles != null ? dataRunfiles : Runfiles.EMPTY);
builder.addProvider(RunfilesProvider.class, runfilesProvider);
Runfiles computedDefaultRunfiles = runfilesProvider.getDefaultRunfiles();
// This works because we only allowed to call a rule *_test iff it's a test type rule.
boolean testRule = TargetUtils.isTestRuleName(ruleContext.getRule().getRuleClass());
if (testRule && computedDefaultRunfiles.isEmpty()) {
throw new EvalException(loc, "Test rules have to define runfiles");
}
if (executable != null || testRule) {
RunfilesSupport runfilesSupport = computedDefaultRunfiles.isEmpty() ? null : RunfilesSupport.withExecutable(ruleContext, computedDefaultRunfiles, executable);
builder.setRunfilesSupport(runfilesSupport, executable);
}
if (ruleContext.getRule().getRuleClassObject().isSkylarkTestable()) {
SkylarkClassObject actions = ActionsProvider.create(ruleContext.getAnalysisEnvironment().getRegisteredActions());
builder.addSkylarkDeclaredProvider(actions, loc);
}
// Populate default provider fields and build it
ImmutableMap.Builder<String, Object> attrBuilder = new ImmutableMap.Builder<>();
// TODO: Add actual attributes that users expect to access from default providers
attrBuilder.put("runfiles", runfilesProvider);
SkylarkClassObject statelessDefaultProvider = new SkylarkClassObject(SkylarkRuleContext.getDefaultProvider(), attrBuilder.build());
// Add the default provider
builder.addSkylarkDeclaredProvider(statelessDefaultProvider, (defaultProvider == null) ? loc : Optional.fromNullable(defaultProvider.getCreationLocOrNull()).or(loc));
}
use of com.google.devtools.build.lib.syntax.EvalException in project bazel by bazelbuild.
the class NewRepositoryBuildFileHandler method prepareBuildFile.
/**
* Prepares for writing a build file by validating the build_file and build_file_content
* attributes of the rule.
*
* @return true if the build file was successfully created, false if the environment is missing
* values (the calling fetch() function should return null in this case).
* @throws RepositoryFunctionException if the rule does not define the build_file or
* build_file_content attributes, or if it defines both, or if the build file could not be
* retrieved, written, or symlinked.
*/
public boolean prepareBuildFile(Rule rule, Environment env) throws RepositoryFunctionException, InterruptedException {
WorkspaceAttributeMapper mapper = WorkspaceAttributeMapper.of(rule);
boolean hasBuildFile = mapper.isAttributeValueExplicitlySpecified("build_file");
boolean hasBuildFileContent = mapper.isAttributeValueExplicitlySpecified("build_file_content");
if (hasBuildFile && hasBuildFileContent) {
String error = String.format("Rule %s cannot have both a 'build_file' and 'build_file_content' attribute", rule);
throw new RepositoryFunctionException(new EvalException(rule.getLocation(), error), Transience.PERSISTENT);
} else if (hasBuildFile) {
buildFileValue = getBuildFileValue(rule, env);
if (env.valuesMissing()) {
return false;
}
} else if (hasBuildFileContent) {
try {
buildFileContent = mapper.get("build_file_content", Type.STRING);
} catch (EvalException e) {
throw new RepositoryFunctionException(e, Transience.PERSISTENT);
}
} else {
String error = String.format("Rule %s requires a 'build_file' or 'build_file_content' attribute", rule);
throw new RepositoryFunctionException(new EvalException(rule.getLocation(), error), Transience.PERSISTENT);
}
return true;
}
use of com.google.devtools.build.lib.syntax.EvalException in project bazel by bazelbuild.
the class RepositoryFunction method getTargetPath.
@VisibleForTesting
protected static PathFragment getTargetPath(Rule rule, Path workspace) throws RepositoryFunctionException {
WorkspaceAttributeMapper mapper = WorkspaceAttributeMapper.of(rule);
String path;
try {
path = mapper.get("path", Type.STRING);
} catch (EvalException e) {
throw new RepositoryFunctionException(e, Transience.PERSISTENT);
}
PathFragment pathFragment = new PathFragment(path);
return workspace.getRelative(pathFragment).asFragment();
}
use of com.google.devtools.build.lib.syntax.EvalException in project bazel by bazelbuild.
the class WorkspaceAttributeMapper method get.
/**
* Returns typecasted value for attribute or {@code null} on no match.
*/
@Nullable
public <T> T get(String attributeName, Type<T> type) throws EvalException {
Preconditions.checkNotNull(type);
Object value = getObject(attributeName);
try {
return type.cast(value);
} catch (ClassCastException e) {
throw new EvalException(rule.getAttributeContainer().getAttributeLocation(attributeName), e.getMessage());
}
}
Aggregations