def execute(self):
     basedir = os.path.join(self.get_options().pants_distdir,
                            self._output_folder)
     runtime_classpath = self.context.products.get_data('runtime_classpath')
     targets = self.context.targets()
     if self.get_options().manifest_jar_only:
         classpath = ClasspathUtil.classpath(targets, runtime_classpath)
         # Safely create e.g. dist/export-classpath/manifest.jar
         safe_classpath(classpath, basedir, "manifest.jar")
     else:
         ClasspathProducts.create_canonical_classpath(
             runtime_classpath, targets, basedir, save_classpath_file=True)
 def execute(self):
   basedir = os.path.join(self.get_options().pants_distdir, self._output_folder)
   runtime_classpath = self.context.products.get_data('runtime_classpath')
   targets = self.context.targets()
   if self.get_options().manifest_jar_only:
     classpath = ClasspathUtil.classpath(targets, runtime_classpath)
     # Safely create e.g. dist/export-classpath/manifest.jar
     safe_classpath(classpath, basedir, "manifest.jar")
   else:
     ClasspathProducts.create_canonical_classpath(runtime_classpath,
                                                  targets,
                                                  basedir,
                                                  save_classpath_file=True)
Example #3
0
    def test_safe_classpath(self):
        """For directory structure like:

       ./
       ./libs/A.jar
       ./libs/resources/
       ./synthetic_jar_dir

       Verify a synthetic jar with the following classpath in manifest is created:

        Class-Path: ../libs/A.jar:../libs/resources/
    """
        RESOURCES = 'resources'
        LIB_DIR = 'libs'
        JAR_FILE = 'A.jar'
        SYNTHENTIC_JAR_DIR = 'synthetic_jar_dir'

        basedir = safe_mkdtemp()
        lib_dir = os.path.join(basedir, LIB_DIR)
        synthetic_jar_dir = os.path.join(basedir, SYNTHENTIC_JAR_DIR)
        resource_dir = os.path.join(lib_dir, RESOURCES)
        jar_file = os.path.join(lib_dir, JAR_FILE)

        for dir in (lib_dir, resource_dir, synthetic_jar_dir):
            safe_mkdir(dir)
        touch(jar_file)

        classpath = [jar_file, resource_dir]

        safe_cp = safe_classpath(classpath, synthetic_jar_dir)
        self.assertEqual(1, len(safe_cp))
        safe_jar = safe_cp[0]
        self.assertTrue(os.path.exists(safe_jar))
        self.assertEqual(synthetic_jar_dir, os.path.dirname(safe_jar))

        with open_zip(safe_jar) as synthetic_jar:
            self.assertEqual([Manifest.PATH], synthetic_jar.namelist())
            # manifest should contain the relative path of both jar and resource directory
            expected = ('{}: ../{}/{} ../{}/{}/\n'.format(
                Manifest.CLASS_PATH, LIB_DIR, JAR_FILE, LIB_DIR,
                RESOURCES).encode('utf-8'))
            self.assertEqual(
                expected,
                synthetic_jar.read(Manifest.PATH).replace(b'\n ', b''))
Example #4
0
  def test_safe_classpath(self):
    """For directory structure like:

       ./
       ./libs/A.jar
       ./libs/resources/
       ./synthetic_jar_dir

       Verify a synthetic jar with the following classpath in manifest is created:

        Class-Path: ../libs/A.jar:../libs/resources/
    """
    RESOURCES = 'resources'
    LIB_DIR = 'libs'
    JAR_FILE = 'A.jar'
    SYNTHENTIC_JAR_DIR = 'synthetic_jar_dir'

    basedir = safe_mkdtemp()
    lib_dir = os.path.join(basedir, LIB_DIR)
    synthetic_jar_dir = os.path.join(basedir, SYNTHENTIC_JAR_DIR)
    resource_dir = os.path.join(lib_dir, RESOURCES)
    jar_file = os.path.join(lib_dir, JAR_FILE)

    for dir in (lib_dir, resource_dir, synthetic_jar_dir):
      safe_mkdir(dir)
    touch(jar_file)

    classpath = [jar_file, resource_dir]

    safe_cp = safe_classpath(classpath, synthetic_jar_dir)
    self.assertEqual(1, len(safe_cp))
    safe_jar = safe_cp[0]
    self.assertTrue(os.path.exists(safe_jar))
    self.assertEqual(synthetic_jar_dir, os.path.dirname(safe_jar))

    with open_zip(safe_jar) as synthetic_jar:
      self.assertEqual([Manifest.PATH], synthetic_jar.namelist())
      # manifest should contain the relative path of both jar and resource directory
      expected = ('{}: ../{}/{} ../{}/{}/\n'
                  .format(Manifest.CLASS_PATH, LIB_DIR, JAR_FILE, LIB_DIR, RESOURCES)
                  .encode('utf-8'))
      self.assertEqual(expected, synthetic_jar.read(Manifest.PATH).replace(b'\n ', b''))
Example #5
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))
Example #6
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))