예제 #1
0
파일: jvm_task.py 프로젝트: simudream/pants
    def classpath(self,
                  targets,
                  classpath_prefix=None,
                  classpath_product=None):
        """Builds a transitive classpath for the given targets.

    Optionally includes a classpath prefix or building from a non-default classpath product.

    :param targets: the targets for which to build the transitive classpath.
    :param classpath_prefix: optional additional entries to prepend to the classpath.
    :param classpath_product: an optional ClasspathProduct from which to build the classpath. if not
    specified, the runtime_classpath will be used.
    :return: a list of classpath strings.
    """
        classpath = list(classpath_prefix) if classpath_prefix else []

        classpath_product = classpath_product or self.context.products.get_data(
            'runtime_classpath')

        closure = BuildGraph.closure(targets, bfs=True)

        classpath_for_targets = ClasspathUtil.classpath(
            closure, classpath_product, self.confs)
        classpath.extend(classpath_for_targets)
        return classpath
예제 #2
0
    def test_closure_bfs(self):
        root = self.inject_graph(
            'a', {
                'a': ['b', 'c'],
                'b': ['d', 'e'],
                'c': ['f', 'g'],
                'd': ['h', 'i'],
                'e': ['j', 'k'],
                'f': ['l', 'm'],
                'g': ['n', 'o'],
                'h': [],
                'i': [],
                'j': [],
                'k': [],
                'l': [],
                'm': [],
                'n': [],
                'o': [],
            })

        bfs_closure = BuildGraph.closure([self.build_graph.get_target(root)],
                                         bfs=True)
        self.assertEquals(
            [t.address.target_name for t in bfs_closure],
            [
                str(six.unichr(x))
                for x in six.moves.xrange(ord('a'),
                                          ord('o') + 1)
            ],
        )
예제 #3
0
    def test_closure_bfs(self):
        root = self.inject_graph(
            "a",
            {
                "a": ["b", "c"],
                "b": ["d", "e"],
                "c": ["f", "g"],
                "d": ["h", "i"],
                "e": ["j", "k"],
                "f": ["l", "m"],
                "g": ["n", "o"],
                "h": [],
                "i": [],
                "j": [],
                "k": [],
                "l": [],
                "m": [],
                "n": [],
                "o": [],
            },
        )

        bfs_closure = BuildGraph.closure([self.build_graph.get_target(root)],
                                         bfs=True)
        self.assertEqual(
            [t.address.target_name for t in bfs_closure],
            [chr(x) for x in range(ord("a"),
                                   ord("o") + 1)],
        )
예제 #4
0
    def _compute_classpath(runtime_classpath, targets):
        closure = BuildGraph.closure(
            targets, bfs=True, include_scopes=Scopes.JVM_RUNTIME_SCOPES, respect_intransitive=True
        )
        classpath_for_targets = ClasspathUtil.classpath(closure, runtime_classpath)

        return classpath_for_targets
예제 #5
0
파일: jvm_task.py 프로젝트: Gointer/pants
  def classpath(self, targets, classpath_prefix=None, classpath_product=None, exclude_scopes=None,
                include_scopes=None):
    """Builds a transitive classpath for the given targets.

    Optionally includes a classpath prefix or building from a non-default classpath product.

    :param targets: the targets for which to build the transitive classpath.
    :param classpath_prefix: optional additional entries to prepend to the classpath.
    :param classpath_product: an optional ClasspathProduct from which to build the classpath. if not
    specified, the runtime_classpath will be used.
    :param :class:`pants.build_graph.target_scopes.Scope` exclude_scopes: Exclude targets which
      have at least one of these scopes on the classpath.
    :param :class:`pants.build_graph.target_scopes.Scope` include_scopes: Only include targets which
      have at least one of these scopes on the classpath. Defaults to Scopes.JVM_RUNTIME_SCOPES.
    :return: a list of classpath strings.
    """
    include_scopes = Scopes.JVM_RUNTIME_SCOPES if include_scopes is None else include_scopes
    classpath_product = classpath_product or self.context.products.get_data('runtime_classpath')
    closure = BuildGraph.closure(targets, bfs=True, include_scopes=include_scopes,
                                 exclude_scopes=exclude_scopes, respect_intransitive=True)

    classpath_for_targets = ClasspathUtil.classpath(closure, classpath_product, self.confs)
    classpath = list(classpath_prefix or ())
    classpath.extend(classpath_for_targets)
    return classpath
예제 #6
0
 def _filter_by_excludes(self, classpath_target_tuples, root_targets):
   # Excludes are always applied transitively, so regardless of whether a transitive
   # set of targets was included here, their closure must be included.
   closure = BuildGraph.closure(root_targets, bfs=True)
   excludes = self._excludes.get_for_targets(closure)
   return [target_tuple for target_tuple in classpath_target_tuples
           if _not_excluded_filter(excludes)(target_tuple)]
예제 #7
0
 def _filter_by_excludes(self, classpath_target_tuples, root_targets):
   # Excludes are always applied transitively, so regardless of whether a transitive
   # set of targets was included here, their closure must be included.
   closure = BuildGraph.closure(root_targets, bfs=True)
   excludes = self._excludes.get_for_targets(closure)
   return [target_tuple for target_tuple in classpath_target_tuples
           if _not_excluded_filter(excludes)(target_tuple)]
예제 #8
0
  def test_closure_bfs(self):
    root = self.inject_graph('a', {
      'a': ['b', 'c'],
      'b': ['d', 'e'],
      'c': ['f', 'g'],
      'd': ['h', 'i'],
      'e': ['j', 'k'],
      'f': ['l', 'm'],
      'g': ['n', 'o'],
      'h': [], 'i': [], 'j': [], 'k': [], 'l': [], 'm': [], 'n': [], 'o': [],
    })

    bfs_closure = BuildGraph.closure([self.build_graph.get_target(root)], bfs=True)
    self.assertEquals(
        [t.address.target_name for t in bfs_closure],
        [str(six.unichr(x)) for x in six.moves.xrange(ord('a'), ord('o') + 1)],
    )
예제 #9
0
    def test_closure(self):
        self.assertEqual(OrderedSet(), BuildGraph.closure([]))
        a = self.make_target("a")
        self.assertEqual(OrderedSet([a]), BuildGraph.closure([a]))
        b = self.make_target("b", dependencies=[a])
        self.assertEqual(OrderedSet([b, a]), BuildGraph.closure([b]))
        c = self.make_target("c", dependencies=[b])
        self.assertEqual(OrderedSet([c, b, a]), BuildGraph.closure([c]))
        d = self.make_target("d", dependencies=[a, c])
        self.assertEqual(OrderedSet([d, a, c, b]), BuildGraph.closure([d]))

        def d_gen():
            yield d

        self.assertEqual(OrderedSet([d, a, c, b]), BuildGraph.closure(d_gen()))

        empty_gen = iter(())
        self.assertEqual(OrderedSet([]), BuildGraph.closure(empty_gen))
예제 #10
0
파일: jvm_task.py 프로젝트: jduan/pants
  def classpath(self, targets, classpath_prefix=None, classpath_product=None):
    """Builds a transitive classpath for the given targets.

    Optionally includes a classpath prefix or building from a non-default classpath product.

    :param targets: the targets for which to build the transitive classpath.
    :param classpath_prefix: optional additional entries to prepend to the classpath.
    :param classpath_product: an optional ClasspathProduct from which to build the classpath. if not
    specified, the runtime_classpath will be used.
    :return: a list of classpath strings.
    """
    classpath = list(classpath_prefix) if classpath_prefix else []

    classpath_product = classpath_product or self.context.products.get_data('runtime_classpath')

    closure = BuildGraph.closure(targets, bfs=True)

    classpath_for_targets = ClasspathUtil.classpath(closure, classpath_product, self.confs)
    classpath.extend(classpath_for_targets)
    return classpath
예제 #11
0
  def test_closure(self):
    self.assertEquals([], BuildGraph.closure([]))
    a = self.make_target('a')
    self.assertEquals([a], BuildGraph.closure([a]))
    b = self.make_target('b', dependencies=[a])
    self.assertEquals([b, a], BuildGraph.closure([b]))
    c = self.make_target('c', dependencies=[b])
    self.assertEquals([c, b, a], BuildGraph.closure([c]))
    d = self.make_target('d', dependencies=[a, c])
    self.assertEquals([d, a, c, b], BuildGraph.closure([d]))

    def d_gen():
      yield d
    self.assertEquals([d, a, c, b], BuildGraph.closure(d_gen()))

    def empty_gen():
      return
      yield
    self.assertEquals([], BuildGraph.closure(empty_gen()))
예제 #12
0
  def test_closure(self):
    self.assertEquals([], BuildGraph.closure([]))
    a = self.make_target('a')
    self.assertEquals([a], BuildGraph.closure([a]))
    b = self.make_target('b', dependencies=[a])
    self.assertEquals([b, a], BuildGraph.closure([b]))
    c = self.make_target('c', dependencies=[b])
    self.assertEquals([c, b, a], BuildGraph.closure([c]))
    d = self.make_target('d', dependencies=[a, c])
    self.assertEquals([d, a, c, b], BuildGraph.closure([d]))

    def d_gen():
      yield d
    self.assertEquals([d, a, c, b], BuildGraph.closure(d_gen()))

    def empty_gen():
      return
      yield
    self.assertEquals([], BuildGraph.closure(empty_gen()))
예제 #13
0
    def test_closure(self):
        self.assertEqual([], BuildGraph.closure([]))
        a = self.make_target('a')
        self.assertEqual([a], BuildGraph.closure([a]))
        b = self.make_target('b', dependencies=[a])
        self.assertEqual([b, a], BuildGraph.closure([b]))
        c = self.make_target('c', dependencies=[b])
        self.assertEqual([c, b, a], BuildGraph.closure([c]))
        d = self.make_target('d', dependencies=[a, c])
        self.assertEqual([d, a, c, b], BuildGraph.closure([d]))

        def d_gen():
            yield d

        self.assertEqual([d, a, c, b], BuildGraph.closure(d_gen()))

        def empty_gen():
            return
            yield  # type: ignore[misc] # MyPy complains that this is not reachable

        self.assertEqual([], BuildGraph.closure(empty_gen()))
예제 #14
0
  def instrument(self, output_dir):
    for datafile in self._iter_datafiles(output_dir):
      os.unlink(datafile)

    self._canonical_datafile = os.path.join(output_dir, '{}.canonical'.format(self._DATAFILE_NAME))
    # It's conceivable we'll be executing a test that has no source file dependencies; ie: we'll
    # never generate a canonical coverage datafile below. Create an empty one here to allow the
    # test run to proceeed normally.
    touch(self._canonical_datafile)

    # Setup an instrumentation classpath based on the existing runtime classpath.
    runtime_classpath = self._context.products.get_data('runtime_classpath')
    instrumentation_classpath = self._context.products.safe_create_data('instrument_classpath',
                                                                        runtime_classpath.copy)
    self.initialize_instrument_classpath(output_dir,
                                         self._settings,
                                         self._targets,
                                         instrumentation_classpath)

    cobertura_cp = self._settings.tool_classpath('cobertura-instrument')
    files_to_instrument = []
    for target in self._targets:
      if Cobertura.is_coverage_target(target):
        paths = instrumentation_classpath.get_for_target(target)
        for (name, path) in paths:
          files_to_instrument.append(path)

    if len(files_to_instrument) > 0:
      unique_files = list(set(files_to_instrument))
      relativize_paths(unique_files, self._settings.workdir)

      args = [
        '--basedir',
        self._settings.workdir,
        '--datafile',
        self._canonical_datafile,
      ]

      if self._include_user_classpath:
        closure = BuildGraph.closure(self._targets, bfs=True, include_scopes=Scopes.JVM_TEST_SCOPES,
          respect_intransitive=True)

        aux_classpath = safe_classpath(
          ClasspathUtil.classpath(closure, runtime_classpath),
          synthetic_jar_dir=None)
        args.append('--auxClasspath')
        args.extend(aux_classpath)

      # apply class incl/excl filters
      if len(self._include_classes) > 0:
        for pattern in self._include_classes:
          args += ["--includeClasses", pattern]
      else:
        args += ["--includeClasses", '.*']  # default to instrumenting all classes
      for pattern in self._exclude_classes:
        args += ["--excludeClasses", pattern]

      with temporary_file() as tmp_file:
        tmp_file.write("\n".join(unique_files))
        tmp_file.flush()

        args += ["--listOfFilesToInstrument", tmp_file.name]

        main = 'net.sourceforge.cobertura.instrument.InstrumentMain'
        self._settings.log.debug(
          "executing cobertura instrumentation with the following args: {}".format(args))
        result = self._execute_java(classpath=cobertura_cp,
                                    main=main,
                                    jvm_options=self._settings.coverage_jvm_options,
                                    args=args,
                                    workunit_factory=self._context.new_workunit,
                                    workunit_name='cobertura-instrument')
        if result != 0:
          raise TaskError("java {0} ... exited non-zero ({1})"
                          " 'failed to instrument'".format(main, result))
예제 #15
0
    def instrument(self, output_dir):
        for datafile in self._iter_datafiles(output_dir):
            os.unlink(datafile)

        self._canonical_datafile = os.path.join(
            output_dir, '{}.canonical'.format(self._DATAFILE_NAME))
        # It's conceivable we'll be executing a test that has no source file dependencies; ie: we'll
        # never generate a canonical coverage datafile below. Create an empty one here to allow the
        # test run to proceeed normally.
        touch(self._canonical_datafile)

        # Setup an instrumentation classpath based on the existing runtime classpath.
        runtime_classpath = self._context.products.get_data(
            'runtime_classpath')
        instrumentation_classpath = self._context.products.safe_create_data(
            'instrument_classpath', runtime_classpath.copy)
        self.initialize_instrument_classpath(output_dir, self._settings,
                                             self._targets,
                                             instrumentation_classpath)

        cobertura_cp = self._settings.tool_classpath('cobertura-instrument')
        files_to_instrument = []
        for target in self._targets:
            if Cobertura.is_coverage_target(target):
                paths = instrumentation_classpath.get_for_target(target)
                for (name, path) in paths:
                    files_to_instrument.append(path)

        if len(files_to_instrument) > 0:
            unique_files = list(set(files_to_instrument))
            relativize_paths(unique_files, self._settings.workdir)

            args = [
                '--basedir',
                self._settings.workdir,
                '--datafile',
                self._canonical_datafile,
            ]

            if self._include_user_classpath:
                closure = BuildGraph.closure(
                    self._targets,
                    bfs=True,
                    include_scopes=Scopes.JVM_TEST_SCOPES,
                    respect_intransitive=True)

                aux_classpath = safe_classpath(ClasspathUtil.classpath(
                    closure, runtime_classpath),
                                               synthetic_jar_dir=None)
                args.append('--auxClasspath')
                args.extend(aux_classpath)

            # apply class incl/excl filters
            if len(self._include_classes) > 0:
                for pattern in self._include_classes:
                    args += ["--includeClasses", pattern]
            else:
                args += ["--includeClasses",
                         '.*']  # default to instrumenting all classes
            for pattern in self._exclude_classes:
                args += ["--excludeClasses", pattern]

            with temporary_file(binary_mode=False) as tmp_file:
                tmp_file.write("\n".join(unique_files))
                tmp_file.flush()

                args += ["--listOfFilesToInstrument", tmp_file.name]

                main = 'net.sourceforge.cobertura.instrument.InstrumentMain'
                self._settings.log.debug(
                    "executing cobertura instrumentation with the following args: {}"
                    .format(args))
                result = self._execute_java(
                    classpath=cobertura_cp,
                    main=main,
                    jvm_options=self._settings.coverage_jvm_options,
                    args=args,
                    workunit_factory=self._context.new_workunit,
                    workunit_name='cobertura-instrument')
                if result != 0:
                    raise TaskError("java {0} ... exited non-zero ({1})"
                                    " 'failed to instrument'".format(
                                        main, result))