private static PathFragment getOutputFilePath(
     ConfiguredTarget base, RuleContext ruleContext, String suffix) {
   PathFragment packagePathFragment =
       ruleContext.getLabel().getPackageIdentifier().getPathFragment();
   String name = base.getLabel().getName();
   return new PathFragment(packagePathFragment, new PathFragment(name + suffix));
 }
Exemplo n.º 2
0
  /**
   * Takes a set of configured targets, and checks if the distribution methods declared for the
   * targets are compatible with the constraints imposed by their prerequisites' licenses.
   *
   * @param configuredTargets the targets to check
   * @param keepGoing if false, and a licensing error is encountered, both generates an error
   *     message on the reporter, <em>and</em> throws an exception. If true, then just generates a
   *     message on the reporter.
   * @throws ViewCreationFailedException if the license checking failed (and not --keep_going)
   */
  private void validateLicensingForTargets(
      Iterable<ConfiguredTarget> configuredTargets, boolean keepGoing)
      throws ViewCreationFailedException {
    for (ConfiguredTarget configuredTarget : configuredTargets) {
      final Target target = configuredTarget.getTarget();

      if (TargetUtils.isTestRule(target)) {
        continue; // Tests are exempt from license checking
      }

      final Set<DistributionType> distribs = target.getDistributions();
      BuildConfiguration config = configuredTarget.getConfiguration();
      boolean staticallyLinked = (config != null) && config.performsStaticLink();
      staticallyLinked |=
          (config != null)
              && (target instanceof Rule)
              && ((Rule) target).getRuleClassObject().hasAttr("linkopts", Type.STRING_LIST)
              && ConfiguredAttributeMapper.of((RuleConfiguredTarget) configuredTarget)
                  .get("linkopts", Type.STRING_LIST)
                  .contains("-static");

      LicensesProvider provider = configuredTarget.getProvider(LicensesProvider.class);
      if (provider != null) {
        NestedSet<TargetLicense> licenses = provider.getTransitiveLicenses();
        for (TargetLicense targetLicense : licenses) {
          if (!targetLicense
              .getLicense()
              .checkCompatibility(
                  distribs, target, targetLicense.getLabel(), getReporter(), staticallyLinked)) {
            if (!keepGoing) {
              throw new ViewCreationFailedException("Build aborted due to licensing error");
            }
          }
        }
      } else if (configuredTarget.getTarget() instanceof InputFile) {
        // Input file targets do not provide licenses because they do not
        // depend on the rule where their license is taken from. This is usually
        // not a problem, because the transitive collection of licenses always
        // hits the rule they come from, except when the input file is a
        // top-level target. Thus, we need to handle that case specially here.
        //
        // See FileTarget#getLicense for more information about the handling of
        // license issues with File targets.
        License license = configuredTarget.getTarget().getLicense();
        if (!license.checkCompatibility(
            distribs, target, configuredTarget.getLabel(), getReporter(), staticallyLinked)) {
          if (!keepGoing) {
            throw new ViewCreationFailedException("Build aborted due to licensing error");
          }
        }
      }
    }
  }
Exemplo n.º 3
0
  /**
   * Helper for differential analysis which aggregates the TestSummary for an individual target,
   * reporting runs on the EventBus if necessary.
   */
  private TestSummary.Builder aggregateAndReportSummary(
      ConfiguredTarget testTarget, AggregatingTestListener listener) {

    // If already reported by the listener, no work remains for this target.
    TestSummary.Builder summary = listener.getCurrentSummary(testTarget);
    Label testLabel = testTarget.getLabel();
    Preconditions.checkNotNull(
        summary, "%s did not complete test filtering, but has a test result", testLabel);
    if (listener.targetReported(testTarget)) {
      return summary;
    }

    Collection<Artifact> incompleteRuns = listener.getIncompleteRuns(testTarget);
    Map<Artifact, TestResult> statusMap = listener.getStatusMap();

    // We will get back multiple TestResult instances if test had to be retried several
    // times before passing. Sharding and multiple runs of the same test without retries
    // will be represented by separate artifacts and will produce exactly one TestResult.
    for (Artifact testStatus : TestProvider.getTestStatusArtifacts(testTarget)) {
      // When a build is interrupted ( eg. a broken target with --nokeep_going ) runResult could
      // be null for an unrelated test because we were not able to even try to execute the test.
      // In that case, for tests that were previously passing we return null ( == NO STATUS),
      // because checking if the cached test target is up-to-date would require running the
      // dependency checker transitively.
      TestResult runResult = statusMap.get(testStatus);
      boolean isIncompleteRun = incompleteRuns.contains(testStatus);
      if (runResult == null) {
        summary = markIncomplete(summary);
      } else if (isIncompleteRun) {
        // Only process results which were not recorded by the listener.

        boolean newlyFetched = !statusMap.containsKey(testStatus);
        summary = incrementalAnalyze(summary, runResult);
        if (newlyFetched) {
          eventBus.post(runResult);
        }
        Preconditions.checkState(
            listener.getIncompleteRuns(testTarget).contains(testStatus) == isIncompleteRun,
            "TestListener changed in differential analysis. Ensure it isn't still registered.");
      }
    }

    // The target was not posted by the listener and must be posted now.
    eventBus.post(summary.build());
    return summary;
  }
Exemplo n.º 4
0
  /**
   * Checks that if this is an environment-restricted build, all top-level targets support the
   * expected environments.
   *
   * @param topLevelTargets the build's top-level targets
   * @throws ViewCreationFailedException if constraint enforcement is on, the build declares
   *     environment-restricted top level configurations, and any top-level target doesn't support
   *     the expected environments
   */
  private void checkTargetEnvironmentRestrictions(
      Iterable<ConfiguredTarget> topLevelTargets, PackageManager packageManager)
      throws ViewCreationFailedException {
    for (ConfiguredTarget topLevelTarget : topLevelTargets) {
      BuildConfiguration config = topLevelTarget.getConfiguration();
      if (config == null) {
        // TODO(bazel-team): support file targets (they should apply package-default constraints).
        continue;
      } else if (!config.enforceConstraints() || config.getTargetEnvironments().isEmpty()) {
        continue;
      }

      // Parse and collect this configuration's environments.
      EnvironmentCollection.Builder builder = new EnvironmentCollection.Builder();
      for (Label envLabel : config.getTargetEnvironments()) {
        try {
          Target env = packageManager.getLoadedTarget(envLabel);
          builder.put(ConstraintSemantics.getEnvironmentGroup(env), envLabel);
        } catch (NoSuchPackageException
            | NoSuchTargetException
            | ConstraintSemantics.EnvironmentLookupException e) {
          throw new ViewCreationFailedException("invalid target environment", e);
        }
      }
      EnvironmentCollection expectedEnvironments = builder.build();

      // Now check the target against those environments.
      SupportedEnvironmentsProvider provider =
          Verify.verifyNotNull(topLevelTarget.getProvider(SupportedEnvironmentsProvider.class));
      Collection<Label> missingEnvironments =
          ConstraintSemantics.getUnsupportedEnvironments(
              provider.getEnvironments(), expectedEnvironments);
      if (!missingEnvironments.isEmpty()) {
        throw new ViewCreationFailedException(
            String.format(
                "This is a restricted-environment build. %s does not support"
                    + " required environment%s %s",
                topLevelTarget.getLabel(),
                missingEnvironments.size() == 1 ? "" : "s",
                Joiner.on(", ").join(missingEnvironments)));
      }
    }
  }
  private AndroidStudioInfoFilesProvider createIdeBuildArtifact(
      ConfiguredTarget base,
      RuleContext ruleContext,
      Kind ruleKind,
      DependenciesResult dependenciesResult,
      AndroidStudioInfoFilesProvider.Builder providerBuilder) {

    Artifact ideInfoFile = derivedArtifact(base, ruleContext, ASWB_BUILD_SUFFIX);
    Artifact ideInfoTextFile = derivedArtifact(base, ruleContext, ASWB_BUILD_TEXT_SUFFIX);
    providerBuilder.ideInfoFilesBuilder().add(ideInfoFile);
    providerBuilder.ideInfoTextFilesBuilder().add(ideInfoTextFile);
    NestedSetBuilder<Artifact> ideResolveArtifacts = providerBuilder.ideResolveFilesBuilder();

    RuleIdeInfo.Builder outputBuilder = RuleIdeInfo.newBuilder();

    outputBuilder.setLabel(base.getLabel().toString());

    outputBuilder.setBuildFile(
        ruleContext.getRule().getPackage().getBuildFile().getPath().toString());

    outputBuilder.setBuildFileArtifactLocation(
        makeArtifactLocation(ruleContext.getRule().getPackage()));

    if (ruleKind != Kind.UNRECOGNIZED) {
      outputBuilder.setKind(ruleKind);
    }
    outputBuilder.setKindString(ruleContext.getRule().getRuleClass());

    // Java rules
    JavaRuleOutputJarsProvider outputJarsProvider =
        base.getProvider(JavaRuleOutputJarsProvider.class);
    if (outputJarsProvider != null) {
      Artifact packageManifest = createPackageManifest(base, ruleContext);
      if (packageManifest != null) {
        providerBuilder.ideInfoFilesBuilder().add(packageManifest);
        ruleContext.registerAction(
            makePackageManifestAction(ruleContext, packageManifest, getJavaSources(ruleContext)));
      }

      JavaRuleIdeInfo javaRuleIdeInfo =
          makeJavaRuleIdeInfo(
              base, ruleContext, outputJarsProvider, ideResolveArtifacts, packageManifest);
      outputBuilder.setJavaRuleIdeInfo(javaRuleIdeInfo);
    }

    // C rules
    CppCompilationContext cppCompilationContext = base.getProvider(CppCompilationContext.class);
    if (cppCompilationContext != null) {
      CRuleIdeInfo cRuleIdeInfo = makeCRuleIdeInfo(base, ruleContext, cppCompilationContext);
      outputBuilder.setCRuleIdeInfo(cRuleIdeInfo);
    }

    // CCToolchain rule
    CppConfiguration cppConfiguration = getCppConfiguration(base);
    if (cppConfiguration != null) {
      CToolchainIdeInfo cToolchainIdeInfo = makeCToolchainIdeInfo(ruleContext, cppConfiguration);
      if (cToolchainIdeInfo != null) {
        outputBuilder.setCToolchainIdeInfo(cToolchainIdeInfo);
      }
    }

    // Android rules
    AndroidIdeInfoProvider androidIdeInfoProvider = base.getProvider(AndroidIdeInfoProvider.class);
    if (androidIdeInfoProvider != null) {
      outputBuilder.setAndroidRuleIdeInfo(
          makeAndroidRuleIdeInfo(
              base, androidIdeInfoProvider, dependenciesResult, ideResolveArtifacts));
    }

    AndroidStudioInfoFilesProvider provider = providerBuilder.build();

    outputBuilder.addAllDependencies(transform(dependenciesResult.deps, LABEL_TO_STRING));
    outputBuilder.addAllRuntimeDeps(transform(dependenciesResult.runtimeDeps, LABEL_TO_STRING));
    outputBuilder.addAllTags(base.getTarget().getAssociatedRule().getRuleTags());

    final RuleIdeInfo ruleIdeInfo = outputBuilder.build();

    ruleContext.registerAction(
        makeProtoWriteAction(ruleContext.getActionOwner(), ruleIdeInfo, ideInfoFile));
    ruleContext.registerAction(
        makeProtoTextWriteAction(ruleContext.getActionOwner(), ruleIdeInfo, ideInfoTextFile));

    return provider;
  }