Skip to content

Commit

Permalink
Add new flag to specify if output_licenses attribute should be checke…
Browse files Browse the repository at this point in the history
…d for licenses.

Also flipped :jvm attribute from HOST to TARGET and set the new flag on it.

--
PiperOrigin-RevId: 144084000
MOS_MIGRATED_REVID=144084000
  • Loading branch information
iirina authored and hlopko committed Jan 10, 2017
1 parent 284bbda commit 2f23599
Show file tree
Hide file tree
Showing 8 changed files with 116 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,14 @@ public String toString() {
public final NestedSet<TargetLicense> getTransitiveLicenses() {
return licenses;
}

@Override
public TargetLicense getOutputLicenses() {
return null;
}

@Override
public boolean hasOutputLicenses() {
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,17 @@ public interface LicensesProvider extends TransitiveInfoProvider {
*/
NestedSet<TargetLicense> getTransitiveLicenses();

/**
* A label - license association for output_licenses. If there are no output_licenses it returns
* null.
*/
TargetLicense getOutputLicenses();

/**
* Return whether there is an output_licenses.
*/
boolean hasOutputLicenses();

/**
* License association for a particular target.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,14 @@

package com.google.devtools.build.lib.analysis;

import com.google.common.collect.ListMultimap;
import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.collect.nestedset.Order;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
import com.google.devtools.build.lib.packages.Attribute;
import com.google.devtools.build.lib.packages.AttributeMap;
import com.google.devtools.build.lib.packages.License;
import com.google.devtools.build.lib.packages.Rule;

Expand All @@ -28,12 +31,15 @@
@Immutable
public final class LicensesProviderImpl implements LicensesProvider {
public static final LicensesProvider EMPTY =
new LicensesProviderImpl(NestedSetBuilder.<TargetLicense>emptySet(Order.LINK_ORDER));
new LicensesProviderImpl(NestedSetBuilder.<TargetLicense>emptySet(Order.LINK_ORDER), null);

private final NestedSet<TargetLicense> transitiveLicenses;
private final TargetLicense outputLicenses;

public LicensesProviderImpl(NestedSet<TargetLicense> transitiveLicenses) {
public LicensesProviderImpl(
NestedSet<TargetLicense> transitiveLicenses, TargetLicense outputLicenses) {
this.transitiveLicenses = transitiveLicenses;
this.outputLicenses = outputLicenses;
}

/**
Expand All @@ -47,29 +53,59 @@ public static LicensesProvider of(RuleContext ruleContext) {
NestedSetBuilder<TargetLicense> builder = NestedSetBuilder.linkOrder();
BuildConfiguration configuration = ruleContext.getConfiguration();
Rule rule = ruleContext.getRule();
License toolOutputLicense = rule.getToolOutputLicense(ruleContext.attributes());
AttributeMap attributes = ruleContext.attributes();
License toolOutputLicense = rule.getToolOutputLicense(attributes);
TargetLicense outputLicenses =
toolOutputLicense == null ? null : new TargetLicense(rule.getLabel(), toolOutputLicense);

if (configuration.isHostConfiguration() && toolOutputLicense != null) {
if (toolOutputLicense != License.NO_LICENSE) {
builder.add(new TargetLicense(rule.getLabel(), toolOutputLicense));
builder.add(outputLicenses);
}
} else {
if (rule.getLicense() != License.NO_LICENSE) {
builder.add(new TargetLicense(rule.getLabel(), rule.getLicense()));
}

for (TransitiveInfoCollection dep : ruleContext.getConfiguredTargetMap().values()) {
LicensesProvider provider = dep.getProvider(LicensesProvider.class);
if (provider != null) {
builder.addTransitive(provider.getTransitiveLicenses());
ListMultimap<String, ? extends TransitiveInfoCollection> configuredMap =
ruleContext.getConfiguredTargetMap();

for (String depAttrName : attributes.getAttributeNames()) {
// Only add the transitive licenses for the attributes that do not have the output_licenses.
Attribute attribute = attributes.getAttributeDefinition(depAttrName);
for (TransitiveInfoCollection dep : configuredMap.get(depAttrName)) {
LicensesProvider provider = dep.getProvider(LicensesProvider.class);
if (provider == null) {
continue;
}
if (useOutputLicenses(attribute, configuration) && provider.hasOutputLicenses()) {
builder.add(provider.getOutputLicenses());
} else {
builder.addTransitive(provider.getTransitiveLicenses());
}
}
}
}

return new LicensesProviderImpl(builder.build());
return new LicensesProviderImpl(builder.build(), outputLicenses);
}

private static boolean useOutputLicenses(Attribute attribute, BuildConfiguration configuration) {
return configuration.isHostConfiguration() || attribute.useOutputLicenses();
}

@Override
public NestedSet<TargetLicense> getTransitiveLicenses() {
return transitiveLicenses;
}

@Override
public TargetLicense getOutputLicenses() {
return outputLicenses;
}

@Override
public boolean hasOutputLicenses() {
return outputLicenses != null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,19 @@ public NestedSet<TargetLicense> getTransitiveLicenses() {
.getTransitiveLicenses();
}

@Override
public TargetLicense getOutputLicenses() {
return getProvider(LicensesProvider.class, LicensesProviderImpl.EMPTY)
.getOutputLicenses();
}

@Override
public boolean hasOutputLicenses() {
return getProvider(LicensesProvider.class, LicensesProviderImpl.EMPTY)
.hasOutputLicenses();
}


@Override
public NestedSet<Artifact> getInstrumentedFiles() {
return getProvider(InstrumentedFilesProvider.class, InstrumentedFilesProviderImpl.EMPTY)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ public static final class JavaBaseRule implements RuleDefinition {
@Override
public RuleClass build(Builder builder, RuleDefinitionEnvironment env) {
return builder
.add(attr(":jvm", LABEL).cfg(HOST).value(JavaSemantics.JVM))
.add(attr(":jvm", LABEL).value(JavaSemantics.JVM).useOutputLicenses())
.add(attr(":host_jdk", LABEL).cfg(HOST).value(JavaSemantics.HOST_JDK))
.add(attr("$jacoco_instrumentation", LABEL).cfg(HOST))
.build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,11 @@ private enum PropertyFlag {
* policy would check it.
*/
SKIP_CONSTRAINTS_OVERRIDE,

/**
* Whether we should use output_licenses to check the licences on this attribute.
*/
OUTPUT_LICENSES,
}

// TODO(bazel-team): modify this interface to extend Predicate and have an extra error
Expand Down Expand Up @@ -535,6 +540,14 @@ public Builder<TYPE> orderIndependent() {
return setPropertyFlag(PropertyFlag.ORDER_INDEPENDENT, "order-independent");
}

/**
* Mark the built attribute as to use output_licenses for license checking.
*/
public Builder<TYPE> useOutputLicenses() {
Preconditions.checkState(BuildType.isLabelType(type), "must be a label type");
return setPropertyFlag(PropertyFlag.OUTPUT_LICENSES, "output_license");
}

/**
* Defines the configuration transition for this attribute.
*/
Expand Down Expand Up @@ -1864,6 +1877,13 @@ public boolean isOrderIndependent() {
return getPropertyFlag(PropertyFlag.ORDER_INDEPENDENT);
}

/**
* Returns true if output_licenses should be used for checking licensing.
*/
public boolean useOutputLicenses() {
return getPropertyFlag(PropertyFlag.OUTPUT_LICENSES);
}

/**
* Returns the configuration transition for this attribute for label or label
* list attributes. For other attributes it will always return {@code NONE}.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,10 @@ public ConfiguredTarget create(RuleContext ruleContext)
// but it is sort-of-kind-of a tool, but various parts of it are linked into the output...
// ...so we trust the judgment of the author of the cc_toolchain rule to figure out what
// licenses should be propagated to C++ targets.
License outputLicense = ruleContext.getRule().getToolOutputLicense(ruleContext.attributes());
// TODO(elenairina): Remove this and use Attribute.Builder.useOutputLicenses() on the
// :cc_toolchain attribute instead.
final License outputLicense =
ruleContext.getRule().getToolOutputLicense(ruleContext.attributes());
if (outputLicense != null && outputLicense != License.NO_LICENSE) {
final NestedSet<TargetLicense> license = NestedSetBuilder.create(Order.STABLE_ORDER,
new TargetLicense(ruleContext.getLabel(), outputLicense));
Expand All @@ -246,6 +249,17 @@ public ConfiguredTarget create(RuleContext ruleContext)
public NestedSet<TargetLicense> getTransitiveLicenses() {
return license;
}

@Override
public TargetLicense getOutputLicenses() {
return new TargetLicense(label, outputLicense);
}

@Override
public boolean hasOutputLicenses() {
return true;
}

};

builder.add(LicensesProvider.class, licensesProvider);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -471,7 +471,7 @@ private void collectDefaultRunfiles(Runfiles.Builder builder, RuleContext ruleCo
builder.addArtifacts((Iterable<Artifact>) common.getRuntimeClasspath());

// Add the JDK files if it comes from the source repository (see java_stub_template.txt).
TransitiveInfoCollection javabaseTarget = ruleContext.getPrerequisite(":jvm", Mode.HOST);
TransitiveInfoCollection javabaseTarget = ruleContext.getPrerequisite(":jvm", Mode.TARGET);
if (javabaseTarget != null) {
builder.addArtifacts(
(Iterable<Artifact>) javabaseTarget.getProvider(FileProvider.class).getFilesToBuild());
Expand Down

0 comments on commit 2f23599

Please sign in to comment.