use of com.google.devtools.build.lib.packages.Rule in project bazel by bazelbuild.
the class AspectDefinitionTest method testAspectWithImplicitOrLateboundAttribute_AddsToAttributeMap.
@Test
public void testAspectWithImplicitOrLateboundAttribute_AddsToAttributeMap() throws Exception {
Attribute implicit = attr("$runtime", BuildType.LABEL).value(Label.parseAbsoluteUnchecked("//run:time")).build();
LateBoundLabel<String> latebound = new LateBoundLabel<String>() {
@Override
public Label resolve(Rule rule, AttributeMap attributes, String configuration) {
return Label.parseAbsoluteUnchecked("//run:away");
}
};
AspectDefinition simple = new AspectDefinition.Builder(TEST_ASPECT_CLASS).add(implicit).add(attr(":latebound", BuildType.LABEL).value(latebound)).build();
assertThat(simple.getAttributes()).containsEntry("$runtime", implicit);
assertThat(simple.getAttributes()).containsKey(":latebound");
assertThat(simple.getAttributes().get(":latebound").getLateBoundDefault()).isEqualTo(latebound);
}
use of com.google.devtools.build.lib.packages.Rule in project bazel by bazelbuild.
the class ConstraintSemantics method getDepsOnlyInSelects.
/**
* Returns the deps for this attribute that only appear in selects.
*
* <p>For example:
* <pre>
* deps = [":a"] + select({"//foo:cond": [":b"]}) + select({"//conditions:default": [":c"]})
* </pre>
*
* returns {@code [":b"]}. Even though {@code [":c"]} also appears in a select, that's a
* degenerate case with only one always-chosen condition. So that's considered the same as
* an unconditional dep.
*
* <p>Note that just because a dep only appears in selects for this attribute doesn't mean it
* won't appear unconditionally in another attribute.
*/
private static Set<Label> getDepsOnlyInSelects(RuleContext ruleContext, String attr, Type<?> attrType) {
Rule rule = ruleContext.getRule();
if (!rule.isConfigurableAttribute(attr) || !BuildType.isLabelType(attrType)) {
return ImmutableSet.of();
}
Set<Label> unconditionalDeps = new LinkedHashSet<>();
Set<Label> selectableDeps = new LinkedHashSet<>();
BuildType.SelectorList<?> selectList = (BuildType.SelectorList<?>) RawAttributeMapper.of(rule).getRawAttributeValue(rule, attr);
for (BuildType.Selector<?> select : selectList.getSelectors()) {
addSelectValuesToSet(select, select.isUnconditional() ? unconditionalDeps : selectableDeps);
}
return Sets.difference(selectableDeps, unconditionalDeps);
}
use of com.google.devtools.build.lib.packages.Rule in project bazel by bazelbuild.
the class RepositoryDelegatorFunction method compute.
@Override
public SkyValue compute(SkyKey skyKey, Environment env) throws SkyFunctionException, InterruptedException {
RepositoryName repositoryName = (RepositoryName) skyKey.argument();
Rule rule = RepositoryFunction.getRule(repositoryName, null, env);
if (rule == null) {
return null;
}
BlazeDirectories directories = PrecomputedValue.BLAZE_DIRECTORIES.get(env);
if (directories == null) {
return null;
}
RepositoryFunction handler;
if (rule.getRuleClassObject().isSkylark()) {
handler = skylarkHandler;
} else {
handler = handlers.get(rule.getRuleClass());
}
if (handler == null) {
throw new RepositoryFunctionException(new EvalException(Location.fromFile(directories.getWorkspace().getRelative("WORKSPACE")), "Could not find handler for " + rule), Transience.PERSISTENT);
}
handler.setClientEnvironment(clientEnvironment);
Path repoRoot = RepositoryFunction.getExternalRepositoryDirectory(directories).getRelative(rule.getName());
byte[] ruleSpecificData = handler.getRuleSpecificMarkerData(rule, env);
if (ruleSpecificData == null) {
return null;
}
String ruleKey = computeRuleKey(rule, ruleSpecificData);
Map<String, String> markerData = new TreeMap<>();
Path markerPath = getMarkerPath(directories, rule);
if (handler.isLocal(rule)) {
// Local repositories are always fetched because the operation is generally fast and they do
// not depend on non-local data, so it does not make much sense to try to cache from across
// server instances.
setupRepositoryRoot(repoRoot);
RepositoryDirectoryValue.Builder localRepo = handler.fetch(rule, repoRoot, directories, env, markerData);
if (localRepo == null) {
return null;
} else {
// We write the marker file for local repository essentially for getting the digest and
// injecting it in the RepositoryDirectoryValue.
byte[] digest = writeMarkerFile(markerPath, markerData, ruleKey);
return localRepo.setDigest(digest).build();
}
}
// We check the repository root for existence here, but we can't depend on the FileValue,
// because it's possible that we eventually create that directory in which case the FileValue
// and the state of the file system would be inconsistent.
byte[] markerHash = isFilesystemUpToDate(markerPath, rule, ruleKey, handler, env);
if (env.valuesMissing()) {
return null;
}
if (markerHash != null && repoRoot.exists()) {
// Now that we know that it exists, we can declare a Skyframe dependency on the repository
// root.
RepositoryFunction.getRepositoryDirectory(repoRoot, env);
if (env.valuesMissing()) {
return null;
}
return RepositoryDirectoryValue.builder().setPath(repoRoot).setDigest(markerHash).build();
}
if (isFetch.get()) {
// Fetching enabled, go ahead.
setupRepositoryRoot(repoRoot);
RepositoryDirectoryValue.Builder result = handler.fetch(rule, repoRoot, directories, env, markerData);
if (env.valuesMissing()) {
return null;
}
// No new Skyframe dependencies must be added between calling the repository implementation
// and writing the marker file because if they aren't computed, it would cause a Skyframe
// restart thus calling the possibly very slow (networking, decompression...) fetch()
// operation again. So we write the marker file here immediately.
byte[] digest = writeMarkerFile(markerPath, markerData, ruleKey);
return result.setDigest(digest).build();
}
if (!repoRoot.exists()) {
// The repository isn't on the file system, there is nothing we can do.
throw new RepositoryFunctionException(new IOException("to fix, run\n\tbazel fetch //...\nExternal repository " + repositoryName + " not found and fetching repositories is disabled."), Transience.TRANSIENT);
}
// Declare a Skyframe dependency so that this is re-evaluated when something happens to the
// directory.
FileValue repoRootValue = RepositoryFunction.getRepositoryDirectory(repoRoot, env);
if (env.valuesMissing()) {
return null;
}
// Try to build with whatever is on the file system and emit a warning.
env.getListener().handle(Event.warn(rule.getLocation(), String.format("External repository '%s' is not up-to-date and fetching is disabled. To update, " + "run the build without the '--nofetch' command line option.", rule.getName())));
return RepositoryDirectoryValue.builder().setPath(repoRootValue.realRootedPath().asPath()).setFetchingDelayed().build();
}
use of com.google.devtools.build.lib.packages.Rule in project bazel by bazelbuild.
the class UnknownRuleConfiguredTarget method create.
@Override
public ConfiguredTarget create(RuleContext context) {
// TODO(bazel-team): (2009) why isn't this an error? It would stop the build more promptly...
context.ruleWarning("cannot build " + context.getRule().getRuleClass() + " rules");
ImmutableList<Artifact> outputArtifacts = context.getOutputArtifacts();
NestedSet<Artifact> filesToBuild;
if (outputArtifacts.isEmpty()) {
// Gotta build *something*...
filesToBuild = NestedSetBuilder.create(Order.STABLE_ORDER, context.createOutputArtifact());
} else {
filesToBuild = NestedSetBuilder.wrap(Order.STABLE_ORDER, outputArtifacts);
}
Rule rule = context.getRule();
context.registerAction(new FailAction(context.getActionOwner(), filesToBuild, "cannot build " + rule.getRuleClass() + " rules such as " + rule.getLabel()));
return new RuleConfiguredTargetBuilder(context).setFilesToBuild(filesToBuild).add(RunfilesProvider.class, RunfilesProvider.simple(Runfiles.EMPTY)).build();
}
use of com.google.devtools.build.lib.packages.Rule in project bazel by bazelbuild.
the class RepositoryFunctionTest method testGetTargetPathAbsolute.
@Test
public void testGetTargetPathAbsolute() throws Exception {
Rule rule = scratchRule("external", "w", "local_repository(", " name = 'w',", " path = '/a/b/c',", ")");
assertEquals(new PathFragment("/a/b/c"), TestingRepositoryFunction.getTargetPath(rule, rootDirectory));
}
Aggregations