Beispiel #1
0
  /**
   * Create all the modules we are capable of representing in IntelliJ from the supplied graph.
   *
   * @param targetGraph graph whose nodes will be converted to {@link IjModule}s.
   * @return map which for every BuildTarget points to the corresponding IjModule. Multiple
   *     BuildTarget can point to one IjModule (many:one mapping), the BuildTargets which can't be
   *     prepresented in IntelliJ are missing from this mapping.
   */
  public static ImmutableMap<BuildTarget, IjModule> createModules(
      TargetGraph targetGraph, IjModuleFactory moduleFactory) {
    ImmutableSet<TargetNode<?>> supportedTargets =
        FluentIterable.from(targetGraph.getNodes())
            .filter(IjModuleFactory.SUPPORTED_MODULE_TYPES_PREDICATE)
            .toSet();
    ImmutableListMultimap<Path, TargetNode<?>> baseTargetPathMultimap =
        FluentIterable.from(supportedTargets)
            .index(
                new Function<TargetNode<?>, Path>() {
                  @Override
                  public Path apply(TargetNode<?> input) {
                    return input.getBuildTarget().getBasePath();
                  }
                });

    ImmutableMap.Builder<BuildTarget, IjModule> moduleMapBuilder = new ImmutableMap.Builder<>();

    for (Path baseTargetPath : baseTargetPathMultimap.keySet()) {
      ImmutableSet<TargetNode<?>> targets =
          FluentIterable.from(baseTargetPathMultimap.get(baseTargetPath)).toSet();

      IjModule module = moduleFactory.createModule(baseTargetPath, targets);

      for (TargetNode<?> target : targets) {
        moduleMapBuilder.put(target.getBuildTarget(), module);
      }
    }

    return moduleMapBuilder.build();
  }
Beispiel #2
0
 private void registerInputsUnderSymlinks(Path buildFile, TargetNode<?> node) throws IOException {
   Map<Path, Path> newSymlinksEncountered = Maps.newHashMap();
   if (inputFilesUnderSymlink(
       node.getInputs(),
       node.getRuleFactoryParams().getProjectFilesystem(),
       symlinkExistenceCache,
       newSymlinksEncountered)) {
     ParserConfig.AllowSymlinks allowSymlinks =
         Preconditions.checkNotNull(
             cellSymlinkAllowability.get(node.getBuildTarget().getCellPath()));
     if (allowSymlinks == ParserConfig.AllowSymlinks.FORBID) {
       throw new HumanReadableException(
           "Target %s contains input files under a path which contains a symbolic link "
               + "(%s). To resolve this, use separate rules and declare dependencies instead of "
               + "using symbolic links.",
           node.getBuildTarget(), newSymlinksEncountered);
     }
     LOG.warn(
         "Disabling caching for target %s, because one or more input files are under a "
             + "symbolic link (%s). This will severely impact performance! To resolve this, use "
             + "separate rules and declare dependencies instead of using symbolic links.",
         node.getBuildTarget(), newSymlinksEncountered);
     buildInputPathsUnderSymlink.add(buildFile);
   }
 }
  /** Verify that owners are correctly detected: - one owner, multiple inputs */
  @Test
  public void verifyInputsWithOneOwnerAreCorrectlyReported()
      throws CmdLineException, IOException, InterruptedException {
    FakeProjectFilesystem filesystem =
        new FakeProjectFilesystem() {
          @Override
          public File getFileForRelativePath(String pathRelativeToProjectRoot) {
            return new ExistingFile(getRootPath(), pathRelativeToProjectRoot);
          }
        };

    ImmutableSet<String> inputs =
        ImmutableSet.of(
            "java/somefolder/badfolder/somefile.java",
            "java/somefolder/perfect.java",
            "com/test/subtest/random.java");
    ImmutableSet<Path> inputPaths = MorePaths.asPaths(inputs);

    BuildTarget target = BuildTargetFactory.newInstance("//base:name");
    TargetNode<?> targetNode = createTargetNode(target, inputPaths);

    CommandRunnerParams params = createAuditOwnerCommandRunnerParams(filesystem);
    AuditOwnerCommand.OwnersReport report =
        AuditOwnerCommand.generateOwnersReport(params, targetNode, inputs, false);
    assertTrue(report.nonFileInputs.isEmpty());
    assertTrue(report.nonExistentInputs.isEmpty());
    assertTrue(report.inputsWithNoOwners.isEmpty());

    assertEquals(inputs.size(), report.owners.size());
    assertTrue(report.owners.containsKey(targetNode));
    assertEquals(targetNode.getInputs(), report.owners.get(targetNode));
  }
Beispiel #4
0
 /** Given a set of target nodes, returns the build targets. */
 private static Set<BuildTarget> getTargetsFromNodes(Iterable<TargetNode<?>> input) {
   Set<BuildTarget> result = new LinkedHashSet<>();
   for (TargetNode<?> node : input) {
     result.add(node.getBuildTarget());
   }
   return result;
 }
  /**
   * @param buildTarget target to process.
   * @return the set of {@link BuildTarget}s that must be appended to the dependencies of a node Y
   *     if node Y depends on X.
   */
  public ImmutableSet<BuildTarget> getExportedDepsClosure(BuildTarget buildTarget) {
    if (index.containsKey(buildTarget)) {
      return index.get(buildTarget);
    }

    ImmutableSet<BuildTarget> exportedDeps = ImmutableSet.of();
    TargetNode<?> targetNode = Preconditions.checkNotNull(targetGraph.get(buildTarget));
    if (targetNode.getType().equals(JavaLibraryDescription.TYPE)) {
      JavaLibraryDescription.Arg arg = (JavaLibraryDescription.Arg) targetNode.getConstructorArg();
      exportedDeps = arg.exportedDeps.get();
    } else if (targetNode.getType().equals(AndroidLibraryDescription.TYPE)) {
      AndroidLibraryDescription.Arg arg =
          (AndroidLibraryDescription.Arg) targetNode.getConstructorArg();
      exportedDeps = arg.exportedDeps.get();
    }

    ImmutableSet<BuildTarget> exportedDepsClosure =
        FluentIterable.from(exportedDeps)
            .transformAndConcat(
                new Function<BuildTarget, Iterable<BuildTarget>>() {
                  @Override
                  public Iterable<BuildTarget> apply(BuildTarget input) {
                    return Iterables.concat(ImmutableSet.of(input), getExportedDepsClosure(input));
                  }
                })
            .toSet();
    index.put(buildTarget, exportedDepsClosure);
    return exportedDepsClosure;
  }
 private static <T> BuildRule createBuildRule(
     TargetGraph targetGraph,
     BuildRuleParams params,
     BuildRuleResolver ruleResolver,
     TargetNode<T> node,
     Flavor... flavors) {
   BuildTarget target = BuildTarget.builder(params.getBuildTarget()).addFlavors(flavors).build();
   Description<T> description = node.getDescription();
   T args = node.getConstructorArg();
   return description.createBuildRule(
       targetGraph,
       params.copyWithChanges(target, params.getDeclaredDeps(), params.getExtraDeps()),
       ruleResolver,
       args);
 }
Beispiel #7
0
  /** Print only targets which were identified as owners in JSON. */
  @VisibleForTesting
  void printOwnersOnlyJsonReport(CommandRunnerParams params, OwnersReport report)
      throws IOException {
    final Multimap<String, String> output = TreeMultimap.create();

    Set<TargetNode<?>> sortedTargetNodes = report.owners.keySet();
    for (TargetNode<?> targetNode : sortedTargetNodes) {
      Set<Path> files = report.owners.get(targetNode);
      for (Path input : files) {
        output.put(input.toString(), targetNode.getBuildTarget().getFullyQualifiedName());
      }
    }

    params.getObjectMapper().writeValue(params.getConsole().getStdOut(), output.asMap());
  }
  @Test
  @SuppressWarnings("unchecked")
  public void testWriteModule() throws Exception {
    TargetNode<?> guavaTargetNode =
        JavaLibraryBuilder.createBuilder(
                BuildTargetFactory.newInstance("//third_party/guava:guava"))
            .addSrc(Paths.get("third_party/guava/src/Collections.java"))
            .build();

    TargetNode<?> baseTargetNode =
        JavaLibraryBuilder.createBuilder(
                BuildTargetFactory.newInstance("//java/com/example/base:base"))
            .addDep(guavaTargetNode.getBuildTarget())
            .addSrc(Paths.get("java/com/example/base/Base.java"))
            .build();

    IjModuleGraph moduleGraph =
        IjModuleGraphTest.createModuleGraph(ImmutableSet.of(guavaTargetNode, baseTargetNode));
    IjModule baseModule = IjModuleGraphTest.getModuleForTarget(moduleGraph, baseTargetNode);

    IjProjectTemplateDataPreparer dataPreparer =
        new IjProjectTemplateDataPreparer(javaPackageFinder, moduleGraph, filesystem);

    ContentRoot contentRoot = dataPreparer.getContentRoot(baseModule);
    assertEquals("file://$MODULE_DIR$/../../java/com/example/base", contentRoot.getUrl());

    IjSourceFolder baseSourceFolder = contentRoot.getFolders().first();
    assertEquals("sourceFolder", baseSourceFolder.getType());
    assertFalse(baseSourceFolder.getIsTestSource());
    assertEquals("com.example.base", baseSourceFolder.getPackagePrefix());
    assertEquals("file://$MODULE_DIR$/../../java/com/example/base", baseSourceFolder.getUrl());

    assertThat(
        dataPreparer.getDependencies(baseModule),
        contains(
            allOf(
                hasProperty("type", equalTo(IjDependencyListBuilder.Type.MODULE)),
                hasProperty(
                    "data",
                    equalTo(
                        Optional.of(
                            DependencyEntryData.builder()
                                .setName("third_party_guava")
                                .setScope(IjDependencyListBuilder.Scope.COMPILE)
                                .setExported(false)
                                .build())))),
            allOf(hasProperty("type", equalTo(IjDependencyListBuilder.Type.SOURCE_FOLDER)))));
  }
  @Test
  public void testModuleIndex() throws Exception {
    TargetNode<?> guavaTargetNode =
        PrebuiltJarBuilder.createBuilder(
                BuildTargetFactory.newInstance("//third-party/guava:guava"))
            .setBinaryJar(Paths.get("third-party/guava/guava.jar"))
            .build();

    TargetNode<?> baseTargetNode =
        JavaLibraryBuilder.createBuilder(
                BuildTargetFactory.newInstance("//java/com/example/base:base"))
            .addDep(guavaTargetNode.getBuildTarget())
            .addSrc(Paths.get("java/com/example/base/Base.java"))
            .build();

    TargetNode<?> baseTestsTargetNode =
        JavaTestBuilder.createBuilder(
                BuildTargetFactory.newInstance("//javatests/com/example/base:base"))
            .addDep(baseTargetNode.getBuildTarget())
            .addSrc(Paths.get("javatests/com/example/base/Base.java"))
            .build();

    IjModuleGraph moduleGraph =
        IjModuleGraphTest.createModuleGraph(
            ImmutableSet.of(guavaTargetNode, baseTargetNode, baseTestsTargetNode));
    IjProjectTemplateDataPreparer dataPreparer =
        new IjProjectTemplateDataPreparer(javaPackageFinder, moduleGraph, filesystem);

    // Libraries don't go into the index.
    assertEquals(
        ImmutableSet.of(
            ModuleIndexEntry.builder()
                .setFileUrl("file://$PROJECT_DIR$/.idea/modules/project_root.iml")
                .setFilePath(Paths.get(".idea/modules/project_root.iml"))
                .build(),
            ModuleIndexEntry.builder()
                .setGroup("modules")
                .setFileUrl("file://$PROJECT_DIR$/.idea/modules/java_com_example_base.iml")
                .setFilePath(Paths.get(".idea/modules/java_com_example_base.iml"))
                .build(),
            ModuleIndexEntry.builder()
                .setGroup("modules")
                .setFileUrl("file://$PROJECT_DIR$/.idea/modules/javatests_com_example_base.iml")
                .setFilePath(Paths.get(".idea/modules/javatests_com_example_base.iml"))
                .build()),
        dataPreparer.getModuleIndexEntries());
  }
 @Test
 public void testImplicitDepsAreAddedCorrectly() throws NoSuchBuildTargetException {
   Description<GenruleDescription.Arg> genruleDescription = new GenruleDescription();
   Map<String, Object> instance =
       ImmutableMap.<String, Object>of(
           "srcs", ImmutableList.of(":baz", "//biz:baz"),
           "out", "AndroidManifest.xml",
           "cmd", "$(exe //bin:executable) $(location :arg)");
   ProjectFilesystem projectFilesystem = new AllExistingProjectFilesystem();
   BuildRuleFactoryParams params =
       new BuildRuleFactoryParams(projectFilesystem, BuildTargetFactory.newInstance("//foo:bar"));
   ConstructorArgMarshaller marshaller =
       new ConstructorArgMarshaller(
           new DefaultTypeCoercerFactory(ObjectMappers.newDefaultInstance()));
   ImmutableSet.Builder<BuildTarget> declaredDeps = ImmutableSet.builder();
   ImmutableSet.Builder<VisibilityPattern> visibilityPatterns = ImmutableSet.builder();
   GenruleDescription.Arg constructorArg = genruleDescription.createUnpopulatedConstructorArg();
   try {
     marshaller.populate(
         createCellRoots(projectFilesystem),
         projectFilesystem,
         params,
         constructorArg,
         declaredDeps,
         visibilityPatterns,
         instance);
   } catch (ConstructorArgMarshalException e) {
     fail("Expected constructorArg to be correctly populated.");
   }
   TargetNode<GenruleDescription.Arg> targetNode =
       new TargetNodeFactory(new DefaultTypeCoercerFactory(ObjectMappers.newDefaultInstance()))
           .create(
               Hashing.sha1().hashString(params.target.getFullyQualifiedName(), UTF_8),
               genruleDescription,
               constructorArg,
               params,
               declaredDeps.build(),
               visibilityPatterns.build(),
               createCellRoots(projectFilesystem));
   assertEquals(
       "SourcePaths and targets from cmd string should be extracted as extra deps.",
       ImmutableSet.of("//foo:baz", "//biz:baz", "//bin:executable", "//foo:arg"),
       FluentIterable.from(targetNode.getExtraDeps())
           .transform(Functions.toStringFunction())
           .toSet());
 }
Beispiel #11
0
  /** Print detailed report on all owners. */
  private void printFullReport(CommandRunnerParams params, OwnersReport report) {
    PrintStream out = params.getConsole().getStdOut();
    Ansi ansi = params.getConsole().getAnsi();
    if (report.owners.isEmpty()) {
      out.println(ansi.asErrorText("No owners found"));
    } else {
      out.println(ansi.asSuccessText("Owners:"));
      for (TargetNode<?> targetNode : report.owners.keySet()) {
        out.println(targetNode.getBuildTarget().getFullyQualifiedName());
        Set<Path> files = report.owners.get(targetNode);
        for (Path input : files) {
          out.println(FILE_INDENT + input);
        }
      }
    }

    if (!report.inputsWithNoOwners.isEmpty()) {
      out.println();
      out.println(ansi.asErrorText("Files without owners:"));
      for (Path input : report.inputsWithNoOwners) {
        out.println(FILE_INDENT + input);
      }
    }

    if (!report.nonExistentInputs.isEmpty()) {
      out.println();
      out.println(ansi.asErrorText("Non existent files:"));
      for (String input : report.nonExistentInputs) {
        out.println(FILE_INDENT + input);
      }
    }

    if (!report.nonFileInputs.isEmpty()) {
      out.println();
      out.println(ansi.asErrorText("Non-file inputs:"));
      for (String input : report.nonFileInputs) {
        out.println(FILE_INDENT + input);
      }
    }
  }
Beispiel #12
0
 @Test
 public void testImplicitDepsAreAddedCorrectly()
     throws NoSuchBuildTargetException, TargetNode.InvalidSourcePathInputException {
   Description<GenruleDescription.Arg> genruleDescription = new GenruleDescription();
   Map<String, Object> instance =
       ImmutableMap.<String, Object>of(
           "srcs", ImmutableList.of(":baz", "//biz:baz"),
           "out", "AndroidManifest.xml",
           "cmd", "$(exe //bin:executable) $(location :arg)");
   ProjectFilesystem projectFilesystem = new AllExistingProjectFilesystem();
   BuildRuleFactoryParams params =
       new BuildRuleFactoryParams(
           projectFilesystem,
           BuildTargetFactory.newInstance("//foo:bar"),
           new InMemoryBuildFileTree(ImmutableList.<BuildTarget>of()),
           /* enforeBuckBoundaryCheck */ true);
   ConstructorArgMarshaller marshaller = new ConstructorArgMarshaller();
   ImmutableSet.Builder<BuildTarget> declaredDeps = ImmutableSet.builder();
   ImmutableSet.Builder<BuildTargetPattern> visibilityPatterns = ImmutableSet.builder();
   GenruleDescription.Arg constructorArg = genruleDescription.createUnpopulatedConstructorArg();
   try {
     marshaller.populate(
         projectFilesystem, params, constructorArg, declaredDeps, visibilityPatterns, instance);
   } catch (ConstructorArgMarshalException e) {
     fail("Expected constructorArg to be correctly populated.");
   }
   TargetNode<GenruleDescription.Arg> targetNode =
       new TargetNode<>(
           genruleDescription,
           constructorArg,
           params,
           declaredDeps.build(),
           visibilityPatterns.build());
   assertEquals(
       "SourcePaths and targets from cmd string should be extracted as extra deps.",
       ImmutableSet.of("//foo:baz", "//biz:baz", "//bin:executable", "//foo:arg"),
       FluentIterable.from(targetNode.getExtraDeps())
           .transform(Functions.toStringFunction())
           .toSet());
 }
Beispiel #13
0
  @VisibleForTesting
  static OwnersReport generateOwnersReport(
      CommandRunnerParams params,
      TargetNode<?> targetNode,
      Iterable<String> filePaths,
      boolean guessForDeletedEnabled) {

    // Process arguments assuming they are all relative file paths.
    Set<Path> inputs = Sets.newHashSet();
    Set<String> nonExistentInputs = Sets.newHashSet();
    Set<String> nonFileInputs = Sets.newHashSet();

    for (String filePath : filePaths) {
      File file = params.getCell().getFilesystem().getFileForRelativePath(filePath);
      if (!file.exists()) {
        nonExistentInputs.add(filePath);
      } else if (!file.isFile()) {
        nonFileInputs.add(filePath);
      } else {
        inputs.add(Paths.get(filePath));
      }
    }

    // Try to find owners for each valid and existing file.
    Set<Path> inputsWithNoOwners = Sets.newHashSet(inputs);
    SetMultimap<TargetNode<?>, Path> owners = TreeMultimap.create();
    for (final Path commandInput : inputs) {
      Predicate<Path> startsWith =
          new Predicate<Path>() {
            @Override
            public boolean apply(Path input) {
              return !commandInput.equals(input) && commandInput.startsWith(input);
            }
          };

      Set<Path> ruleInputs = targetNode.getInputs();
      if (ruleInputs.contains(commandInput)
          || FluentIterable.from(ruleInputs).anyMatch(startsWith)) {
        inputsWithNoOwners.remove(commandInput);
        owners.put(targetNode, commandInput);
      }
    }

    // Try to guess owners for nonexistent files.
    if (guessForDeletedEnabled) {
      for (String nonExistentInput : nonExistentInputs) {
        owners.put(targetNode, new File(nonExistentInput).toPath());
      }
    }

    return new OwnersReport(owners, inputsWithNoOwners, nonExistentInputs, nonFileInputs);
  }
  @Test
  public void testCreatePackageLookupPahtSet() {
    TargetNode<?> guavaTargetNode =
        PrebuiltJarBuilder.createBuilder(BuildTargetFactory.newInstance("//lib:guava"))
            .setBinaryJar(Paths.get("lib/guava.jar"))
            .build();

    Path sourcePath = Paths.get("java/com/src/Source.java");
    Path subSourcePath = Paths.get("java/com/src/subpackage/SubSource.java");
    TargetNode<?> srcTargetNode =
        JavaLibraryBuilder.createBuilder(BuildTargetFactory.newInstance("//java/com/src:src"))
            .addDep(guavaTargetNode.getBuildTarget())
            .addSrc(sourcePath)
            .addSrc(subSourcePath)
            .build();

    IjModuleGraph moduleGraph =
        IjModuleGraphTest.createModuleGraph(ImmutableSet.of(guavaTargetNode, srcTargetNode));

    assertThat(
        IjProjectTemplateDataPreparer.createPackageLookupPathSet(moduleGraph),
        containsInAnyOrder(subSourcePath, sourcePath));
  }
Beispiel #15
0
  /**
   * Create all the modules we are capable of representing in IntelliJ from the supplied graph.
   *
   * @param targetGraph graph whose nodes will be converted to {@link IjModule}s.
   * @return map which for every BuildTarget points to the corresponding IjModule. Multiple
   *     BuildTarget can point to one IjModule (many:one mapping), the BuildTargets which can't be
   *     prepresented in IntelliJ are missing from this mapping.
   */
  private static ImmutableMap<BuildTarget, IjModule> createModules(
      TargetGraph targetGraph,
      IjModuleFactory moduleFactory,
      final Function<Path, Path> basePathTransform) {
    ImmutableSet<TargetNode<?>> supportedTargets =
        FluentIterable.from(targetGraph.getNodes())
            .filter(IjModuleFactory.SUPPORTED_MODULE_TYPES_PREDICATE)
            .toSet();
    ImmutableListMultimap<Path, TargetNode<?>> baseTargetPathMultimap =
        FluentIterable.from(supportedTargets)
            .index(
                new Function<TargetNode<?>, Path>() {
                  @Override
                  public Path apply(TargetNode<?> input) {
                    if (!(input.getConstructorArg() instanceof AndroidResourceDescription.Arg)) {
                      return basePathTransform.apply(input.getBuildTarget().getBasePath());
                    }

                    return input.getBuildTarget().getBasePath();
                  }
                });

    ImmutableMap.Builder<BuildTarget, IjModule> moduleMapBuilder = new ImmutableMap.Builder<>();

    for (Path baseTargetPath : baseTargetPathMultimap.keySet()) {
      ImmutableSet<TargetNode<?>> targets =
          FluentIterable.from(baseTargetPathMultimap.get(baseTargetPath)).toSet();

      IjModule module = moduleFactory.createModule(baseTargetPath, targets);

      for (TargetNode<?> target : targets) {
        moduleMapBuilder.put(target.getBuildTarget(), module);
      }
    }

    return moduleMapBuilder.build();
  }
Beispiel #16
0
    @Override
    public void run() {
      while (shouldWaitForWork()) {
        try (BuildTargetProcessingScope processingScope = startProcessingBuildTarget()) {
          // If we've already parsed this in another thread, we can skip doing any work.
          if (permState.hasCachedTargetNodeForBuildTarget(processingScope.getBuildTarget())) {
            continue;
          }
          TargetNode<?> node;
          try (SimplePerfEvent.Scope scope =
              Parser.getTargetNodeEventScope(eventBus, processingScope.getBuildTarget())) {
            try {
              node = getTargetNode(processingScope.getBuildTarget());
            } catch (BuildFileParseException | BuildTargetException | IOException e) {
              // It's okay to not raise this further up because in `Parser` we build the target
              // graph and while doing so will hit the same error (the parsing will have been
              // cached).
              abortDoingMoreWork();
              return;
            }
          }

          processingScope.addDepsToProcess(
              FluentIterable.from(node.getDeps())
                  .filter(permState.getHasCachedTargetNodeForBuildTargetPredicate())
                  .toSet());
        } catch (TimeoutException e) {
          // We timed out waiting to process something on the queue.  This could mean we are done,
          // so run through the while statement again.
          continue;
        } catch (InterruptedException e) {
          abortDoingMoreWork();
          return;
        }
      }
    }
  private <A extends Arg> BuildRule getFlavoredBinaryRule(
      TargetGraph targetGraph,
      final BuildRuleParams params,
      final BuildRuleResolver resolver,
      A args) {
    // Cxx targets must have one Platform Flavor set otherwise nothing gets compiled.
    ImmutableSet<Flavor> flavors =
        params
            .getBuildTarget()
            .withoutFlavors(ImmutableSet.of(ReactNativeFlavors.DO_NOT_BUNDLE))
            .getFlavors();
    if (!cxxPlatformFlavorDomain.containsAnyOf(flavors)) {
      flavors =
          new ImmutableSet.Builder<Flavor>()
              .addAll(flavors)
              .add(defaultCxxPlatform.getFlavor())
              .build();
    }

    final TargetNode<?> binaryTargetNode = Preconditions.checkNotNull(targetGraph.get(args.binary));
    // If the binary target of the AppleBundle is an AppleLibrary then the build flavor
    // must be specified.
    if (binaryTargetNode.getDescription() instanceof AppleLibraryDescription
        && (Sets.intersection(
                    SUPPORTED_LIBRARY_FLAVORS, binaryTargetNode.getBuildTarget().getFlavors())
                .size()
            != 1)) {
      throw new HumanReadableException(
          "AppleExtension bundle [%s] must have exactly one of these flavors: [%s].",
          binaryTargetNode.getBuildTarget().toString(),
          Joiner.on(", ").join(SUPPORTED_LIBRARY_FLAVORS));
    }

    BuildRuleParams binaryRuleParams =
        new BuildRuleParams(
            args.binary,
            Suppliers.ofInstance(
                BuildRules.toBuildRulesFor(
                    params.getBuildTarget(), resolver, binaryTargetNode.getDeclaredDeps())),
            Suppliers.ofInstance(
                BuildRules.toBuildRulesFor(
                    params.getBuildTarget(), resolver, binaryTargetNode.getExtraDeps())),
            params.getProjectFilesystem(),
            params.getCellRoots(),
            params.getRuleKeyBuilderFactory());

    return CxxDescriptionEnhancer.requireBuildRule(
        targetGraph, binaryRuleParams, resolver, flavors.toArray(new Flavor[0]));
  }
Beispiel #18
0
 /** Print only targets which were identified as owners. */
 private void printOwnersOnlyReport(CommandRunnerParams params, OwnersReport report) {
   Set<TargetNode<?>> sortedTargetNodes = report.owners.keySet();
   for (TargetNode<?> targetNode : sortedTargetNodes) {
     params.getConsole().getStdOut().println(targetNode.getBuildTarget().getFullyQualifiedName());
   }
 }
  @Test
  public void testExcludePaths() throws Exception {
    /**
     * Fake filesystem structure .idea |- misc.xml .git |- HEAD java |- com |- BUCK |- data |-
     * wsad.txt |- src |- BUCK |- Source.java |- foo |- Foo.java |- src2 |- Code.java |- org |- bar
     * |- Bar.java lib |- BUCK |- guava.jar
     */
    ImmutableSet<Path> paths =
        ImmutableSet.of(
            Paths.get(".idea/misc.xml"),
            Paths.get(".git/HEAD"),
            Paths.get("java/com/BUCK"),
            Paths.get("java/com/data/wsad.txt"),
            Paths.get("java/com/src/BUCK"),
            Paths.get("java/com/src/Source.java"),
            Paths.get("java/com/src/foo/Foo.java"),
            Paths.get("java/org/bar/Bar.java"),
            Paths.get("lib/BUCK"),
            Paths.get("lib/guava.jar"));

    FakeProjectFilesystem filesystemForExcludesTest =
        new FakeProjectFilesystem(new FakeClock(0), Paths.get(".").toAbsolutePath(), paths);

    TargetNode<?> guavaTargetNode =
        PrebuiltJarBuilder.createBuilder(BuildTargetFactory.newInstance("//lib:guava"))
            .setBinaryJar(Paths.get("lib/guava.jar"))
            .build();

    TargetNode<?> srcTargetNode =
        JavaLibraryBuilder.createBuilder(BuildTargetFactory.newInstance("//java/com/src:src"))
            .addDep(guavaTargetNode.getBuildTarget())
            .addSrc(Paths.get("java/com/src/Source.java"))
            .build();

    TargetNode<?> src2TargetNode =
        JavaLibraryBuilder.createBuilder(BuildTargetFactory.newInstance("//java/com:src2"))
            .addDep(guavaTargetNode.getBuildTarget())
            .addSrc(Paths.get("java/com/src2/Code.java"))
            .build();

    TargetNode<?> rootTargetNode =
        JavaLibraryBuilder.createBuilder(BuildTargetFactory.newInstance("//:root")).build();

    IjModuleGraph moduleGraph =
        IjModuleGraphTest.createModuleGraph(
            ImmutableSet.of(guavaTargetNode, srcTargetNode, src2TargetNode, rootTargetNode));
    IjModule srcModule = IjModuleGraphTest.getModuleForTarget(moduleGraph, srcTargetNode);
    IjModule src2Module = IjModuleGraphTest.getModuleForTarget(moduleGraph, src2TargetNode);
    IjModule rootModule = IjModuleGraphTest.getModuleForTarget(moduleGraph, rootTargetNode);

    IjProjectTemplateDataPreparer dataPreparer =
        new IjProjectTemplateDataPreparer(
            javaPackageFinder, moduleGraph, filesystemForExcludesTest);

    assertEquals(
        ImmutableSet.of(Paths.get("java/com/src/foo")),
        distillExcludeFolders(dataPreparer.createExcludes(srcModule)));

    assertEquals(
        ImmutableSet.of(Paths.get("java/com/data")),
        distillExcludeFolders(dataPreparer.createExcludes(src2Module)));

    // In this case it's fine to exclude "lib" as there is no source code there.
    assertEquals(
        ImmutableSet.of(Paths.get(".git"), Paths.get("java/org"), Paths.get("lib")),
        distillExcludeFolders(dataPreparer.createExcludes(rootModule)));
  }
  @Test
  @SuppressWarnings("unchecked")
  public void testDependencies() throws Exception {
    TargetNode<?> hamcrestTargetNode =
        PrebuiltJarBuilder.createBuilder(
                BuildTargetFactory.newInstance("//third-party/hamcrest:hamcrest"))
            .setBinaryJar(Paths.get("third-party/hamcrest/hamcrest.jar"))
            .build();

    TargetNode<?> guavaTargetNode =
        PrebuiltJarBuilder.createBuilder(
                BuildTargetFactory.newInstance("//third-party/guava:guava"))
            .setBinaryJar(Paths.get("third-party/guava/guava.jar"))
            .build();

    TargetNode<?> baseTargetNode =
        JavaLibraryBuilder.createBuilder(
                BuildTargetFactory.newInstance("//java/com/example/base:base"))
            .addDep(guavaTargetNode.getBuildTarget())
            .addSrc(Paths.get("java/com/example/base/Base.java"))
            .build();

    TargetNode<?> baseGenruleTarget =
        GenruleBuilder.newGenruleBuilder(
                BuildTargetFactory.newInstance("//java/com/example/base:genrule"))
            .build();

    TargetNode<?> baseInlineTestsTargetNode =
        JavaLibraryBuilder.createBuilder(
                BuildTargetFactory.newInstance("//java/com/example/base:tests"))
            .addDep(hamcrestTargetNode.getBuildTarget())
            .addSrc(Paths.get("java/com/example/base/TestBase.java"))
            .addSrcTarget(baseGenruleTarget.getBuildTarget())
            .build();

    TargetNode<?> baseTestsTargetNode =
        JavaTestBuilder.createBuilder(
                BuildTargetFactory.newInstance("//javatests/com/example/base:base"))
            .addDep(baseTargetNode.getBuildTarget())
            .addDep(hamcrestTargetNode.getBuildTarget())
            .addSrc(Paths.get("javatests/com/example/base/Base.java"))
            .build();

    IjModuleGraph moduleGraph =
        IjModuleGraphTest.createModuleGraph(
            ImmutableSet.of(
                hamcrestTargetNode,
                guavaTargetNode,
                baseTargetNode,
                baseGenruleTarget,
                baseInlineTestsTargetNode,
                baseTestsTargetNode),
            ImmutableMap.<TargetNode<?>, Path>of(
                baseInlineTestsTargetNode, Paths.get("buck-out/baseInlineTests.jar")),
            Functions.constant(Optional.<Path>absent()));
    IjLibrary hamcrestLibrary =
        IjModuleGraphTest.getLibraryForTarget(moduleGraph, hamcrestTargetNode);
    IjLibrary guavaLibrary = IjModuleGraphTest.getLibraryForTarget(moduleGraph, guavaTargetNode);
    IjModule baseModule = IjModuleGraphTest.getModuleForTarget(moduleGraph, baseTargetNode);
    IjModule baseTestModule =
        IjModuleGraphTest.getModuleForTarget(moduleGraph, baseTestsTargetNode);

    IjProjectTemplateDataPreparer dataPreparer =
        new IjProjectTemplateDataPreparer(javaPackageFinder, moduleGraph, filesystem);

    assertEquals(
        IjModuleGraphTest.getModuleForTarget(moduleGraph, baseInlineTestsTargetNode),
        IjModuleGraphTest.getModuleForTarget(moduleGraph, baseTargetNode));

    DependencyEntryData.Builder dependencyEntryBuilder =
        DependencyEntryData.builder().setExported(false);

    assertThat(
        dataPreparer.getDependencies(baseModule),
        contains(
            allOf(
                hasProperty("type", equalTo(IjDependencyListBuilder.Type.LIBRARY)),
                hasProperty(
                    "data",
                    equalTo(
                        Optional.of(
                            dependencyEntryBuilder
                                .setName(guavaLibrary.getName())
                                .setScope(IjDependencyListBuilder.Scope.COMPILE)
                                .build())))),
            allOf(
                hasProperty("type", equalTo(IjDependencyListBuilder.Type.LIBRARY)),
                hasProperty(
                    "data",
                    equalTo(
                        Optional.of(
                            dependencyEntryBuilder
                                .setName(hamcrestLibrary.getName())
                                .setScope(IjDependencyListBuilder.Scope.COMPILE)
                                .build())))),
            allOf(hasProperty("type", equalTo(IjDependencyListBuilder.Type.SOURCE_FOLDER))),
            allOf(
                hasProperty("type", equalTo(IjDependencyListBuilder.Type.LIBRARY)),
                hasProperty(
                    "data",
                    equalTo(
                        Optional.of(
                            DependencyEntryData.builder()
                                .setExported(true)
                                .setName("library_java_com_example_base_tests")
                                .setScope(IjDependencyListBuilder.Scope.PROVIDED)
                                .build()))))));

    assertThat(
        dataPreparer.getDependencies(baseTestModule),
        contains(
            allOf(
                hasProperty("type", equalTo(IjDependencyListBuilder.Type.MODULE)),
                hasProperty(
                    "data",
                    equalTo(
                        Optional.of(
                            dependencyEntryBuilder
                                .setName(baseModule.getName())
                                .setScope(IjDependencyListBuilder.Scope.TEST)
                                .build())))),
            allOf(
                hasProperty("type", equalTo(IjDependencyListBuilder.Type.LIBRARY)),
                hasProperty(
                    "data",
                    equalTo(
                        Optional.of(
                            dependencyEntryBuilder
                                .setName(hamcrestLibrary.getName())
                                .setScope(IjDependencyListBuilder.Scope.TEST)
                                .build())))),
            allOf(hasProperty("type", equalTo(IjDependencyListBuilder.Type.SOURCE_FOLDER)))));
  }
Beispiel #21
0
  @Override
  public int runWithoutHelp(CommandRunnerParams params) throws IOException, InterruptedException {
    LOG.debug("Running with arguments %s", getArguments());

    try (CommandThreadManager pool =
        new CommandThreadManager(
            "Test",
            params.getBuckConfig().getWorkQueueExecutionOrder(),
            getConcurrencyLimit(params.getBuckConfig()))) {
      // Post the build started event, setting it to the Parser recorded start time if appropriate.
      BuildEvent.Started started = BuildEvent.started(getArguments());
      if (params.getParser().getParseStartTime().isPresent()) {
        params.getBuckEventBus().post(started, params.getParser().getParseStartTime().get());
      } else {
        params.getBuckEventBus().post(started);
      }

      // The first step is to parse all of the build files. This will populate the parser and find
      // all of the test rules.
      TargetGraph targetGraph;
      ImmutableSet<BuildTarget> explicitBuildTargets;

      try {

        // If the user asked to run all of the tests, parse all of the build files looking for any
        // test rules.
        if (isRunAllTests()) {
          targetGraph =
              params
                  .getParser()
                  .buildTargetGraphForTargetNodeSpecs(
                      params.getBuckEventBus(),
                      params.getCell(),
                      getEnableProfiling(),
                      pool.getExecutor(),
                      ImmutableList.of(
                          TargetNodePredicateSpec.of(
                              new Predicate<TargetNode<?>>() {
                                @Override
                                public boolean apply(TargetNode<?> input) {
                                  return input.getType().isTestRule();
                                }
                              },
                              BuildFileSpec.fromRecursivePath(Paths.get("")))))
                  .getSecond();
          explicitBuildTargets = ImmutableSet.of();

          // Otherwise, the user specified specific test targets to build and run, so build a graph
          // around these.
        } else {
          LOG.debug("Parsing graph for arguments %s", getArguments());
          Pair<ImmutableSet<BuildTarget>, TargetGraph> result =
              params
                  .getParser()
                  .buildTargetGraphForTargetNodeSpecs(
                      params.getBuckEventBus(),
                      params.getCell(),
                      getEnableProfiling(),
                      pool.getExecutor(),
                      parseArgumentsAsTargetNodeSpecs(params.getBuckConfig(), getArguments()));
          targetGraph = result.getSecond();
          explicitBuildTargets = result.getFirst();

          LOG.debug("Got explicit build targets %s", explicitBuildTargets);
          ImmutableSet.Builder<BuildTarget> testTargetsBuilder = ImmutableSet.builder();
          for (TargetNode<?> node : targetGraph.getAll(explicitBuildTargets)) {
            ImmutableSortedSet<BuildTarget> nodeTests = TargetNodes.getTestTargetsForNode(node);
            if (!nodeTests.isEmpty()) {
              LOG.debug("Got tests for target %s: %s", node.getBuildTarget(), nodeTests);
              testTargetsBuilder.addAll(nodeTests);
            }
          }
          ImmutableSet<BuildTarget> testTargets = testTargetsBuilder.build();
          if (!testTargets.isEmpty()) {
            LOG.debug("Got related test targets %s, building new target graph...", testTargets);
            targetGraph =
                params
                    .getParser()
                    .buildTargetGraph(
                        params.getBuckEventBus(),
                        params.getCell(),
                        getEnableProfiling(),
                        pool.getExecutor(),
                        Iterables.concat(explicitBuildTargets, testTargets));
            LOG.debug("Finished building new target graph with tests.");
          }
        }

      } catch (BuildTargetException | BuildFileParseException e) {
        params
            .getBuckEventBus()
            .post(ConsoleEvent.severe(MoreExceptions.getHumanReadableOrLocalizedMessage(e)));
        return 1;
      }

      TargetGraphToActionGraph targetGraphToActionGraph =
          new TargetGraphToActionGraph(
              params.getBuckEventBus(), new BuildTargetNodeToBuildRuleTransformer());
      Pair<ActionGraph, BuildRuleResolver> actionGraphAndResolver =
          Preconditions.checkNotNull(targetGraphToActionGraph.apply(targetGraph));

      // Look up all of the test rules in the action graph.
      Iterable<TestRule> testRules =
          Iterables.filter(actionGraphAndResolver.getFirst().getNodes(), TestRule.class);

      // Unless the user requests that we build filtered tests, filter them out here, before
      // the build.
      if (!isBuildFiltered(params.getBuckConfig())) {
        testRules = filterTestRules(params.getBuckConfig(), explicitBuildTargets, testRules);
      }

      if (isDryRun()) {
        printMatchingTestRules(params.getConsole(), testRules);
      }

      CachingBuildEngine cachingBuildEngine =
          new CachingBuildEngine(
              pool.getExecutor(),
              params.getFileHashCache(),
              getBuildEngineMode().or(params.getBuckConfig().getBuildEngineMode()),
              params.getBuckConfig().getDependencySchedulingOrder(),
              params.getBuckConfig().getBuildDepFiles(),
              params.getBuckConfig().getBuildMaxDepFileCacheEntries(),
              actionGraphAndResolver.getSecond());
      try (Build build =
          createBuild(
              params.getBuckConfig(),
              actionGraphAndResolver.getFirst(),
              actionGraphAndResolver.getSecond(),
              params.getAndroidPlatformTargetSupplier(),
              cachingBuildEngine,
              params.getArtifactCache(),
              params.getConsole(),
              params.getBuckEventBus(),
              getTargetDeviceOptional(),
              params.getPlatform(),
              params.getEnvironment(),
              params.getObjectMapper(),
              params.getClock(),
              Optional.of(getAdbOptions(params.getBuckConfig())),
              Optional.of(getTargetDeviceOptions()))) {

        // Build all of the test rules.
        int exitCode =
            build.executeAndPrintFailuresToEventBus(
                testRules,
                isKeepGoing(),
                params.getBuckEventBus(),
                params.getConsole(),
                getPathToBuildReport(params.getBuckConfig()));
        params.getBuckEventBus().post(BuildEvent.finished(started, exitCode));
        if (exitCode != 0) {
          return exitCode;
        }

        // If the user requests that we build tests that we filter out, then we perform
        // the filtering here, after we've done the build but before we run the tests.
        if (isBuildFiltered(params.getBuckConfig())) {
          testRules = filterTestRules(params.getBuckConfig(), explicitBuildTargets, testRules);
        }

        // Once all of the rules are built, then run the tests.
        Optional<ImmutableList<String>> externalTestRunner =
            params.getBuckConfig().getExternalTestRunner();
        if (externalTestRunner.isPresent()) {
          return runTestsExternal(params, build, externalTestRunner.get(), testRules);
        }
        return runTestsInternal(params, cachingBuildEngine, build, testRules);
      }
    }
  }