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)
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''))
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''))
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))
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))