示例#1
0
    /**
     * Validity-checks that no group has its environment referenced in both the "compatible with"
     * and restricted to" attributes. Returns true if all is good, returns false and reports
     * appropriate errors if there are any problems.
     */
    boolean validateEnvironmentSpecifications() {
      ImmutableCollection<EnvironmentGroup> restrictionGroups = restrictionEnvironments.getGroups();
      boolean hasErrors = false;

      for (EnvironmentGroup group : compatibilityEnvironments.getGroups()) {
        if (restrictionGroups.contains(group)) {
          // To avoid error-spamming the user, when we find a conflict we only report one example
          // environment from each attribute for that group.
          Label compatibilityEnv =
              compatibilityEnvironments.getEnvironments(group).iterator().next();
          Label restrictionEnv = restrictionEnvironments.getEnvironments(group).iterator().next();

          if (compatibilityEnv.equals(restrictionEnv)) {
            ruleContext.attributeError(
                compatibilityAttr,
                compatibilityEnv + " cannot appear both here and in " + restrictionAttr);
          } else {
            ruleContext.attributeError(
                compatibilityAttr,
                compatibilityEnv
                    + " and "
                    + restrictionEnv
                    + " belong to the same environment group. They should be declared "
                    + "together either here or in "
                    + restrictionAttr);
          }
          hasErrors = true;
        }
      }

      return !hasErrors;
    }
示例#2
0
 /**
  * Adds environments specified in the "compatible with" attribute to the set of supported
  * environments, along with all defaults from the groups they belong to. Returns these
  * environments, not including the defaults.
  */
 private EnvironmentCollection collectCompatibilityEnvironments(
     EnvironmentCollection.Builder supportedEnvironments) {
   EnvironmentCollection compatibilityEnvironments =
       collectEnvironments(compatibilityAttr, supportedEnvironments);
   for (EnvironmentGroup group : compatibilityEnvironments.getGroups()) {
     supportedEnvironments.putAll(group, defaultsProvider.getDefaults(group));
   }
   return compatibilityEnvironments;
 }
示例#3
0
 @Override
 public Collection<Label> getDefaults(EnvironmentGroup group) {
   if (ruleClassDefaults.getGroups().contains(group)) {
     return ruleClassDefaults.getEnvironments(group);
   } else {
     // If there are no rule class defaults for this group, just inherit global defaults.
     return groupDefaults.getDefaults(group);
   }
 }
示例#4
0
 /**
  * Adds environments to an {@link EnvironmentCollection} from groups that aren't already a part of
  * that collection.
  *
  * @param environments the collection to add to
  * @param toAdd the collection to add. All environments in this collection in groups that aren't
  *     represented in {@code environments} are added to {@code environments}.
  * @return the expanded collection.
  */
 private static EnvironmentCollection addUnknownGroupsToCollection(
     EnvironmentCollection environments, EnvironmentCollection toAdd) {
   EnvironmentCollection.Builder builder = new EnvironmentCollection.Builder();
   builder.putAll(environments);
   for (EnvironmentGroup candidateGroup : toAdd.getGroups()) {
     if (!environments.getGroups().contains(candidateGroup)) {
       builder.putAll(candidateGroup, toAdd.getEnvironments(candidateGroup));
     }
   }
   return builder.build();
 }
示例#5
0
  /**
   * Given a collection of environments and a collection of expected environments, returns the
   * missing environments that would cause constraint expectations to be violated. Includes the
   * effects of environment group defaults.
   */
  public static Collection<Label> getUnsupportedEnvironments(
      EnvironmentCollection actualEnvironments, EnvironmentCollection expectedEnvironments) {
    Set<Label> missingEnvironments = new LinkedHashSet<>();
    Collection<Label> actualEnvironmentLabels = actualEnvironments.getEnvironments();

    // Check if each explicitly expected environment is satisfied.
    for (EnvironmentWithGroup expectedEnv : expectedEnvironments.getGroupedEnvironments()) {
      EnvironmentGroup group = expectedEnv.group();
      Label environment = expectedEnv.environment();
      boolean isSatisfied = false;
      if (actualEnvironments.getGroups().contains(group)) {
        // If the actual environments include members from the expected environment's group, we
        // need to either find the environment itself or another one that transitively fulfills it.
        if (actualEnvironmentLabels.contains(environment)
            || intersect(actualEnvironmentLabels, group.getFulfillers(environment))) {
          isSatisfied = true;
        }
      } else {
        // If the actual environments don't reference the expected environment's group at all,
        // the group's defaults are implicitly included. So we need to check those defaults for
        // either the expected environment or another environment that transitively fulfills it.
        if (group.isDefault(environment)
            || intersect(group.getFulfillers(environment), group.getDefaults())) {
          isSatisfied = true;
        }
      }
      if (!isSatisfied) {
        missingEnvironments.add(environment);
      }
    }

    // For any environment group not referenced by the expected environments, its defaults are
    // implicitly expected. We can ignore this if the actual environments also don't reference the
    // group (since in that case the same defaults apply), otherwise we have to check.
    for (EnvironmentGroup group : actualEnvironments.getGroups()) {
      if (!expectedEnvironments.getGroups().contains(group)) {
        for (Label expectedDefault : group.getDefaults()) {
          if (!actualEnvironmentLabels.contains(expectedDefault)
              && !intersect(actualEnvironmentLabels, group.getFulfillers(expectedDefault))) {
            missingEnvironments.add(expectedDefault);
          }
        }
      }
    }

    return missingEnvironments;
  }