def execute(self): pages = [] targets = self.context.targets() for target in targets: if isinstance(target, Page): for wiki_artifact in target.payload.provides: pages.append((target, wiki_artifact)) urls = list() genmap = self.context.products.get('wiki_html') for page, wiki_artifact in pages: html_info = genmap.get((wiki_artifact, page)) if len(html_info) > 1: raise TaskError('Unexpected resources for {}: {}'.format(page, html_info)) basedir, htmls = html_info.items()[0] if len(htmls) != 1: raise TaskError('Unexpected resources for {}: {}'.format(page, htmls)) with safe_open(os.path.join(basedir, htmls[0])) as contents: url = self.publish_page( page.address, wiki_artifact.config['space'], wiki_artifact.config['title'], contents.read(), # Default to none if not present in the hash. parent=wiki_artifact.config.get('parent') ) if url: urls.append(url) self.context.log.info('Published {} to {}'.format(page, url)) if self.open and urls: binary_util.ui_open(*urls)
def _open_project(self): if self.open: if self.open_with: null = open(os.devnull, 'w') subprocess.Popen([self.open_with, self.project_filename], stdout=null, stderr=null) else: binary_util.ui_open(self.project_filename)
def report(self, targets, tests, execute_java_for_targets, tests_failed_exception=None): if self._nothing_to_instrument: self._context.log.warn("Nothing found to instrument, skipping report...") return if tests_failed_exception: self._context.log.warn("Test failed: {0}".format(tests_failed_exception)) if self._coverage_force: self._context.log.warn("Generating report even though tests failed.") else: return cobertura_cp = self._settings.tool_classpath("cobertura-report") source_roots = {t.target_base for t in targets if self.is_coverage_target(t)} for report_format in ["xml", "html"]: report_dir = os.path.join(self._settings.coverage_dir, report_format) safe_mkdir(report_dir, clean=True) args = list(source_roots) args += ["--datafile", self._coverage_datafile, "--destination", report_dir, "--format", report_format] main = "net.sourceforge.cobertura.reporting.ReportMain" result = execute_java_for_targets( targets, classpath=cobertura_cp, main=main, jvm_options=self._coverage_jvm_options, args=args, workunit_factory=self._context.new_workunit, workunit_name="cobertura-report-" + report_format, ) if result != 0: raise TaskError("java {0} ... exited non-zero ({1})" " 'failed to report'".format(main, result)) if self._coverage_open: coverage_html_file = os.path.join(self._settings.coverage_dir, "html", "index.html") binary_util.ui_open(coverage_html_file)
def execute(self): """Stages IDE project artifacts to a project directory and generates IDE configuration files.""" # Grab the targets in-play before the context is replaced by `self._prepare_project()` below. targets = self.context.targets() self._prepare_project() if self.context.options.is_known_scope('compile.checkstyle'): checkstyle_classpath = self.tool_classpath( 'checkstyle', scope='compile.checkstyle') else: # Checkstyle not enabled. checkstyle_classpath = [] if self.skip_scala: scalac_classpath = [] else: scalac_classpath = self.tool_classpath('scalac', scope='scala-platform') self._project.set_tool_classpaths(checkstyle_classpath, scalac_classpath) self.map_internal_jars(targets) self.map_external_jars(targets) idefile = self.generate_project(self._project) if idefile: binary_util.ui_open(idefile)
def execute(self): pages = [] targets = self.context.targets() for target in targets: if isinstance(target, Page): for wiki_artifact in target.payload.provides: pages.append((target, wiki_artifact)) urls = list() genmap = self.context.products.get('wiki_html') for page, wiki_artifact in pages: html_info = genmap.get((wiki_artifact, page)) if len(html_info) > 1: raise TaskError('Unexpected resources for {}: {}'.format( page, html_info)) basedir, htmls = html_info.items()[0] if len(htmls) != 1: raise TaskError('Unexpected resources for {}: {}'.format( page, htmls)) with safe_open(os.path.join(basedir, htmls[0])) as contents: url = self.publish_page( page.address, wiki_artifact.config['space'], wiki_artifact.config['title'], contents.read(), # Default to none if not present in the hash. parent=wiki_artifact.config.get('parent')) if url: urls.append(url) self.context.log.info('Published {} to {}'.format( page, url)) if self.open and urls: binary_util.ui_open(*urls)
def _do_report(exception=None): if self._coverage: self._coverage.report( targets, tests_and_targets.keys(), self.execute_java_for_coverage, tests_failed_exception=exception) if self._html_report: html_file_path = JUnitHtmlReport().report(self.workdir, os.path.join(self.workdir, 'reports')) if self._open: binary_util.ui_open(html_file_path)
def report(self, targets, tests, tests_failed_exception=None): if tests_failed_exception: self._context.log.warn('Test failed: {0}'.format( str(tests_failed_exception))) if self._coverage_force: self._context.log.warn( 'Generating report even though tests failed') else: return args = [ 'report', '-in', self._coverage_metadata_file, '-in', self._coverage_file, '-exit' ] source_bases = set() def collect_source_base(target): if self.is_coverage_target(target): source_bases.add(target.target_base) for target in targets: target.walk(collect_source_base) for source_base in source_bases: args.extend(['-sp', source_base]) sorting = ['-Dreport.sort', '+name,+class,+method,+block'] args.extend([ '-r', 'txt', '-Dreport.txt.out.file={0}'.format( self._coverage_console_file) ] + sorting) args.extend([ '-r', 'xml', '-Dreport.xml.out.file={0}'.format(self._coverage_xml_file) ]) args.extend([ '-r', 'html', '-Dreport.html.out.file={0}'.format( self._coverage_html_file), '-Dreport.out.encoding=UTF-8' ] + sorting) main = 'emma' execute_java = self.preferred_jvm_distribution_for_targets( targets).execute_java result = execute_java(classpath=self._emma_classpath, main=main, jvm_options=self._coverage_jvm_options, args=args, workunit_factory=self._context.new_workunit, workunit_name='emma-report') if result != 0: raise TaskError( "java {0} ... exited non-zero ({1})" " 'failed to generate code coverage reports'".format( main, result)) with safe_open(self._coverage_console_file) as console_report: sys.stdout.write(console_report.read()) if self._coverage_open: binary_util.ui_open(self._coverage_html_file)
def visualize_execution_graph(scheduler): with temporary_file() as fp: for line in create_digraph(scheduler): fp.write(line) fp.write('\n') fp.close() with temporary_file_path(cleanup=False, suffix='.svg') as image_file: subprocess.check_call('dot -Tsvg -o{} {}'.format(image_file, fp.name), shell=True) binary_util.ui_open(image_file)
def visualize_execution_graph(execution_graph): with temporary_file() as fp: for line in create_digraph(execution_graph): fp.write(line) fp.write("\n") fp.close() with temporary_file_path(cleanup=False) as image_file: subprocess.check_call("dot -Tsvg -o{} {}".format(image_file, fp.name), shell=True) binary_util.ui_open(image_file)
def visualize_execution_graph(scheduler, request): with temporary_file_path(cleanup=False, suffix='.dot') as dot_file: scheduler.visualize_graph_to_file(request.roots, dot_file) print('dot file saved to: {}'.format(dot_file)) with temporary_file_path(cleanup=False, suffix='.svg') as image_file: subprocess.check_call('dot -Tsvg -o{} {}'.format(image_file, dot_file), shell=True) print('svg file saved to: {}'.format(image_file)) binary_util.ui_open(image_file)
def visualize_execution_graph(scheduler, storage, request): with temporary_file(cleanup=False, suffix='.dot') as fp: for line in create_digraph(scheduler, storage, request): fp.write(line) fp.write('\n') print('dot file saved to: {}'.format(fp.name)) with temporary_file_path(cleanup=False, suffix='.svg') as image_file: subprocess.check_call('dot -Tsvg -o{} {}'.format(image_file, fp.name), shell=True) print('svg file saved to: {}'.format(image_file)) binary_util.ui_open(image_file)
def _generate_combined(self, classpath, targets, create_jvmdoc_command): gendir = os.path.join(self.workdir, 'combined') if targets: safe_mkdir(gendir, clean=True) command = create_jvmdoc_command(classpath, gendir, *targets) if command: self.context.log.debug("Running create_jvmdoc in {} with {}".format(gendir, " ".join(command))) result, gendir = create_jvmdoc(command, gendir) self._handle_create_jvmdoc_result(targets, result, command) if self.open: binary_util.ui_open(os.path.join(gendir, 'index.html'))
def _do_report(exception=None): if self._coverage: self._coverage.report(targets, tests_and_targets.keys(), self.execute_java_for_coverage, tests_failed_exception=exception) if self._html_report: html_file_path = JUnitHtmlReport().report( self.workdir, os.path.join(self.workdir, 'reports')) if self._open: binary_util.ui_open(html_file_path)
def report(self, targets, tests, execute_java_for_targets, tests_failed_exception=None): if self._nothing_to_instrument: self._context.log.warn( 'Nothing found to instrument, skipping report...') return if tests_failed_exception: self._context.log.warn( 'Test failed: {0}'.format(tests_failed_exception)) if self._coverage_force: self._context.log.warn( 'Generating report even though tests failed.') else: return cobertura_cp = self._settings.tool_classpath('cobertura-report') source_roots = { t.target_base for t in targets if self.is_coverage_target(t) } for report_format in ['xml', 'html']: report_dir = os.path.join(self._settings.coverage_dir, report_format) safe_mkdir(report_dir, clean=True) args = list(source_roots) args += [ '--datafile', self._coverage_datafile, '--destination', report_dir, '--format', report_format, ] main = 'net.sourceforge.cobertura.reporting.ReportMain' result = execute_java_for_targets( targets, classpath=cobertura_cp, main=main, jvm_options=self._coverage_jvm_options, args=args, workunit_factory=self._context.new_workunit, workunit_name='cobertura-report-' + report_format) if result != 0: raise TaskError("java {0} ... exited non-zero ({1})" " 'failed to report'".format(main, result)) if self._coverage_open: coverage_html_file = os.path.join(self._settings.coverage_dir, 'html', 'index.html') binary_util.ui_open(coverage_html_file)
def execute(self): """Stages IDE project artifacts to a project directory and generates IDE configuration files.""" # Grab the targets in-play before the context is replaced by `self._prepare_project()` below. self._prepare_project() ide_file = self.generate_project(self._project) if ide_file and self.get_options().open: open_with = self.get_options().open_with if open_with: null = open(os.devnull, 'w') subprocess.Popen([open_with, ide_file], stdout=null, stderr=null) else: binary_util.ui_open(ide_file)
def report(self, targets, tests, tests_failed_exception=None): if tests_failed_exception: self._context.log.warn('Test failed: {0}'.format(str(tests_failed_exception))) if self._coverage_force: self._context.log.warn('Generating report even though tests failed') else: return args = [ 'report', '-in', self._coverage_metadata_file, '-in', self._coverage_file, '-exit' ] source_bases = set() def collect_source_base(target): if self.is_coverage_target(target): source_bases.add(target.target_base) for target in self._test_target_candidates(targets): target.walk(collect_source_base) for source_base in source_bases: args.extend(['-sp', source_base]) sorting = ['-Dreport.sort', '+name,+class,+method,+block'] args.extend(['-r', 'txt', '-Dreport.txt.out.file={0}'.format(self._coverage_console_file)] + sorting) args.extend(['-r', 'xml', '-Dreport.xml.out.file={0}'.format(self._coverage_xml_file)]) args.extend(['-r', 'html', '-Dreport.html.out.file={0}'.format(self._coverage_html_file), '-Dreport.out.encoding=UTF-8'] + sorting) main = 'emma' execute_java = self.preferred_jvm_distribution_for_targets(targets).execute_java result = execute_java(classpath=self._emma_classpath, main=main, jvm_options=self._coverage_jvm_options, args=args, workunit_factory=self._context.new_workunit, workunit_name='emma-report') if result != 0: raise TaskError("java {0} ... exited non-zero ({1})" " 'failed to generate code coverage reports'".format(main, result)) with safe_open(self._coverage_console_file) as console_report: sys.stdout.write(console_report.read()) if self._coverage_open: binary_util.ui_open(self._coverage_html_file)
def execute(self): """Stages IDE project artifacts to a project directory and generates IDE configuration files.""" self._prepare_project() if self.context.options.is_known_scope('compile.checkstyle'): checkstyle_classpath = self.tool_classpath('checkstyle', scope='compile.checkstyle') else: # Checkstyle not enabled. checkstyle_classpath = [] if self.skip_scala: scalac_classpath = [] else: scalac_classpath = self.tool_classpath('scalac', scope='scala-platform') self._project.set_tool_classpaths(checkstyle_classpath, scalac_classpath) targets = self.context.targets() self.map_internal_jars(targets) self.map_external_jars() idefile = self.generate_project(self._project) if idefile: binary_util.ui_open(idefile)
def execute(self): """Stages IDE project artifacts to a project directory and generates IDE configuration files.""" # Grab the targets in-play before the context is replaced by `self._prepare_project()` below. targets = self.context.targets() self._prepare_project() if self.context.options.is_known_scope('compile.checkstyle'): checkstyle_classpath = self.tool_classpath('checkstyle', scope='compile.checkstyle') else: # Checkstyle not enabled. checkstyle_classpath = [] if self.skip_scala: scalac_classpath = [] else: scalac_classpath = ScalaPlatform.global_instance().compiler_classpath(self.context.products) self._project.set_tool_classpaths(checkstyle_classpath, scalac_classpath) self.map_internal_jars(targets) self.map_external_jars(targets) idefile = self.generate_project(self._project) if idefile: binary_util.ui_open(idefile)
def _maybe_open(self, port): if self.get_options().open: binary_util.ui_open('http://localhost:{port}'.format(port=port))
def report(self, targets, tests, tests_failed_exception=None): if self._nothing_to_instrument: self._context.log.warn( 'Nothing found to instrument, skipping report...') return if tests_failed_exception: self._context.log.warn( 'Test failed: {0}'.format(tests_failed_exception)) if self._coverage_force: self._context.log.warn( 'Generating report even though tests failed.') else: return cobertura_cp = self._task_exports.tool_classpath('cobertura-report') # Link files in the real source tree to files named using the classname. # Do not include class file names containing '$', as these will always have # a corresponding $-less class file, and they all point back to the same # source. # Put all these links to sources under self._coverage_dir/src all_classes = set() for basedir, classes in self._rootdirs.items(): all_classes.update([cls for cls in classes if '$' not in cls]) sources_by_class = self._build_sources_by_class() coverage_source_root_dir = os.path.join(self._coverage_dir, 'src') safe_rmtree(coverage_source_root_dir) for cls in all_classes: source_file = sources_by_class.get(cls) if source_file: # the class in @cls # (e.g., 'org/pantsbuild/example/hello/welcome/WelcomeEverybody.class') # was compiled from the file in @source_file # (e.g., 'src/scala/org/pantsbuild/example/hello/welcome/Welcome.scala') # Note that, in the case of scala files, the path leading up to Welcome.scala does not # have to match the path in the corresponding .class file AT ALL. In this example, # @source_file could very well have been 'src/hello-kitty/Welcome.scala'. # However, cobertura expects the class file path to match the corresponding source # file path below the source base directory(ies) (passed as (a) positional argument(s)), # while it still gets the source file basename from the .class file. # Here we create a fake hierachy under coverage_dir/src to mimic what cobertura expects. class_dir = os.path.dirname( cls) # e.g., 'org/pantsbuild/example/hello/welcome' fake_source_directory = os.path.join(coverage_source_root_dir, class_dir) safe_mkdir(fake_source_directory) fake_source_file = os.path.join(fake_source_directory, os.path.basename(source_file)) try: os.symlink( os.path.relpath(source_file, fake_source_directory), fake_source_file) except OSError as e: # These warnings appear when source files contain multiple classes. self._context.log.warn( 'Could not symlink {0} to {1}: {2}'.format( source_file, fake_source_file, e)) else: self._context.log.error( 'class {0} does not exist in a source file!'.format(cls)) report_formats = [] report_formats.append('xml') report_formats.append('html') for report_format in report_formats: report_dir = os.path.join(self._coverage_dir, report_format) safe_mkdir(report_dir, clean=True) args = [ coverage_source_root_dir, '--datafile', self._coverage_datafile, '--destination', report_dir, '--format', report_format, ] main = 'net.sourceforge.cobertura.reporting.ReportMain' execute_java = self.preferred_jvm_distribution_for_targets( targets).execute_java result = execute_java(classpath=cobertura_cp, main=main, jvm_options=self._coverage_jvm_options, args=args, workunit_factory=self._context.new_workunit, workunit_name='cobertura-report-' + report_format) if result != 0: raise TaskError("java {0} ... exited non-zero ({1})" " 'failed to report'".format(main, result)) if self._coverage_open: coverage_html_file = os.path.join(self._coverage_dir, 'html', 'index.html') binary_util.ui_open(coverage_html_file)
def execute(self): # TODO(John Sirois): consider adding change detection outdir = os.path.join(self.get_options().pants_distdir, 'markdown') css_path = os.path.join(outdir, 'css', 'codehighlight.css') css = emit_codehighlight_css(css_path, self.code_style) if css: self.context.log.info('Emitted {}'.format(css)) def is_page(target): return isinstance(target, Page) roots = set() interior_nodes = set() if self.open: dependencies_by_page = self.context.dependents( on_predicate=is_page, from_predicate=is_page) roots.update(dependencies_by_page.keys()) for dependencies in dependencies_by_page.values(): interior_nodes.update(dependencies) roots.difference_update(dependencies) for page in self.context.targets(is_page): # There are no in or out edges so we need to show show this isolated page. if not page.dependencies and page not in interior_nodes: roots.add(page) with self.context.new_workunit(name='render', labels=[WorkUnitLabel.MULTITOOL]): plaingenmap = self.context.products.get('markdown_html') wikigenmap = self.context.products.get('wiki_html') show = [] for page in self.context.targets(is_page): def process_page(key, outdir, url_builder, genmap, fragment=False): if page.format == 'rst': with self.context.new_workunit(name='rst') as workunit: html_path = self.process_rst( workunit, page, os.path.join(outdir, page_to_html_path(page)), os.path.join(page.payload.sources.rel_path, page.source), self.fragment or fragment, ) else: with self.context.new_workunit(name='md'): html_path = self.process_md( os.path.join(outdir, page_to_html_path(page)), os.path.join(page.payload.sources.rel_path, page.source), self.fragment or fragment, url_builder, css=css, ) self.context.log.info('Processed {} to {}'.format( page.source, html_path)) relpath = os.path.relpath(html_path, outdir) genmap.add(key, outdir, [relpath]) return html_path def url_builder(linked_page): dest = page_to_html_path(linked_page) src_dir = os.path.dirname(page_to_html_path(page)) return linked_page.name, os.path.relpath(dest, src_dir) page_path = os.path.join(outdir, 'html') html = process_page(page, page_path, url_builder, plaingenmap) if css and not self.fragment: plaingenmap.add(page, self.workdir, list(css_path)) if self.open and page in roots: show.append(html) if page.provides: for wiki in page.provides: basedir = os.path.join(self.workdir, str(hash(wiki))) process_page((wiki, page), basedir, wiki.wiki.url_builder, wikigenmap, fragment=True) if show: binary_util.ui_open(*show)
def _generate_ivy_report(self, result): def make_empty_report(report, organisation, module, conf): no_deps_xml_template = dedent( """<?xml version="1.0" encoding="UTF-8"?> <?xml-stylesheet type="text/xsl" href="ivy-report.xsl"?> <ivy-report version="1.0"> <info organisation="{organisation}" module="{module}" revision="latest.integration" conf="{conf}" confs="{conf}" date="{timestamp}"/> </ivy-report> """).format( organisation=organisation, module=module, conf=conf, timestamp=time.strftime('%Y%m%d%H%M%S'), ) with open(report, 'w') as report_handle: print(no_deps_xml_template, file=report_handle) tool_classpath = self.tool_classpath('xalan') report = None org = IvyUtils.INTERNAL_ORG_NAME name = result.resolve_hash_name xsl = os.path.join(self.ivy_cache_dir, 'ivy-report.xsl') # Xalan needs this dir to exist - ensure that, but do no more - we have no clue where this # points. safe_mkdir(self._outdir, clean=False) for conf in self.get_options().confs: xml_path = result.report_for_conf(conf) if not os.path.exists(xml_path): # Make it clear that this is not the original report from Ivy by changing its name. xml_path = xml_path[:-4] + "-empty.xml" make_empty_report(xml_path, org, name, conf) out = os.path.join( self._outdir, '{org}-{name}-{conf}.html'.format(org=org, name=name, conf=conf)) args = ['-IN', xml_path, '-XSL', xsl, '-OUT', out] # The ivy-report.xsl genrates tab links to files with extension 'xml' by default, we # override that to point to the html files we generate. args.extend(['-param', 'extension', 'html']) if 0 != self.runjava(classpath=tool_classpath, main='org.apache.xalan.xslt.Process', args=args, workunit_name='report'): raise self.Error( 'Failed to create html report from xml ivy report.') # The ivy-report.xsl is already smart enough to generate an html page with tab links to all # confs for a given report coordinate (org, name). We need only display 1 of the generated # htmls and the user can then navigate to the others via the tab links. if report is None: report = out css = os.path.join(self._outdir, 'ivy-report.css') if os.path.exists(css): os.unlink(css) shutil.copy(os.path.join(self.ivy_cache_dir, 'ivy-report.css'), self._outdir) if self._open and report: binary_util.ui_open(report)
def execute(self): # TODO(John Sirois): consider adding change detection outdir = os.path.join(self.get_options().pants_distdir, 'markdown') css_path = os.path.join(outdir, 'css', 'codehighlight.css') css = util().emit_codehighlight_css(css_path, self.code_style) if css: self.context.log.info('Emitted {}'.format(css)) def is_page(target): return isinstance(target, Page) roots = set() interior_nodes = set() if self.open: dependencies_by_page = self.context.dependents(on_predicate=is_page, from_predicate=is_page) roots.update(dependencies_by_page.keys()) for dependencies in dependencies_by_page.values(): interior_nodes.update(dependencies) roots.difference_update(dependencies) for page in self.context.targets(is_page): # There are no in or out edges so we need to show show this isolated page. if not page.dependencies and page not in interior_nodes: roots.add(page) with self.context.new_workunit(name='render', labels=[WorkUnitLabel.MULTITOOL]): plaingenmap = self.context.products.get('markdown_html') wikigenmap = self.context.products.get('wiki_html') show = [] for page in self.context.targets(is_page): def process_page(key, outdir, url_builder, genmap, fragment=False): if page.format == 'rst': with self.context.new_workunit(name='rst') as workunit: html_path = self.process_rst( workunit, page, os.path.join(outdir, util().page_to_html_path(page)), os.path.join(page.payload.sources.rel_path, page.source), self.fragment or fragment, ) else: with self.context.new_workunit(name='md'): html_path = self.process_md( os.path.join(outdir, util().page_to_html_path(page)), os.path.join(page.payload.sources.rel_path, page.source), self.fragment or fragment, url_builder, css=css, ) self.context.log.info('Processed {} to {}'.format(page.source, html_path)) relpath = os.path.relpath(html_path, outdir) genmap.add(key, outdir, [relpath]) return html_path def url_builder(linked_page): dest = util().page_to_html_path(linked_page) src_dir = os.path.dirname(util().page_to_html_path(page)) return linked_page.name, os.path.relpath(dest, src_dir) page_path = os.path.join(outdir, 'html') html = process_page(page, page_path, url_builder, plaingenmap) if css and not self.fragment: plaingenmap.add(page, self.workdir, list(css_path)) if self.open and page in roots: show.append(html) if page.provides: for wiki in page.provides: basedir = os.path.join(self.workdir, str(hash(wiki))) process_page((wiki, page), basedir, wiki.wiki.url_builder, wikigenmap, fragment=True) if show: binary_util.ui_open(*show)
def report(self, targets, tests, tests_failed_exception=None): if self._nothing_to_instrument: self._context.log.warn('Nothing found to instrument, skipping report...') return if tests_failed_exception: self._context.log.warn('Test failed: {0}'.format(tests_failed_exception)) if self._coverage_force: self._context.log.warn('Generating report even though tests failed.') else: return cobertura_cp = self._task_exports.tool_classpath('cobertura-report') # Link files in the real source tree to files named using the classname. # Do not include class file names containing '$', as these will always have # a corresponding $-less class file, and they all point back to the same # source. # Put all these links to sources under self._coverage_dir/src all_classes = set() for basedir, classes in self._rootdirs.items(): all_classes.update([cls for cls in classes if '$' not in cls]) sources_by_class = self._build_sources_by_class() coverage_source_root_dir = os.path.join(self._coverage_dir, 'src') safe_rmtree(coverage_source_root_dir) for cls in all_classes: source_file = sources_by_class.get(cls) if source_file: # the class in @cls # (e.g., 'org/pantsbuild/example/hello/welcome/WelcomeEverybody.class') # was compiled from the file in @source_file # (e.g., 'src/scala/org/pantsbuild/example/hello/welcome/Welcome.scala') # Note that, in the case of scala files, the path leading up to Welcome.scala does not # have to match the path in the corresponding .class file AT ALL. In this example, # @source_file could very well have been 'src/hello-kitty/Welcome.scala'. # However, cobertura expects the class file path to match the corresponding source # file path below the source base directory(ies) (passed as (a) positional argument(s)), # while it still gets the source file basename from the .class file. # Here we create a fake hierachy under coverage_dir/src to mimic what cobertura expects. class_dir = os.path.dirname(cls) # e.g., 'org/pantsbuild/example/hello/welcome' fake_source_directory = os.path.join(coverage_source_root_dir, class_dir) safe_mkdir(fake_source_directory) fake_source_file = os.path.join(fake_source_directory, os.path.basename(source_file)) try: os.symlink(os.path.relpath(source_file, fake_source_directory), fake_source_file) except OSError as e: # These warnings appear when source files contain multiple classes. self._context.log.warn( 'Could not symlink {0} to {1}: {2}'.format(source_file, fake_source_file, e)) else: self._context.log.error('class {0} does not exist in a source file!'.format(cls)) report_formats = [] report_formats.append('xml') report_formats.append('html') for report_format in report_formats: report_dir = os.path.join(self._coverage_dir, report_format) safe_mkdir(report_dir, clean=True) args = [ coverage_source_root_dir, '--datafile', self._coverage_datafile, '--destination', report_dir, '--format', report_format, ] main = 'net.sourceforge.cobertura.reporting.ReportMain' execute_java = self.preferred_jvm_distribution_for_targets(targets).execute_java result = execute_java(classpath=cobertura_cp, main=main, jvm_options=self._coverage_jvm_options, args=args, workunit_factory=self._context.new_workunit, workunit_name='cobertura-report-' + report_format) if result != 0: raise TaskError("java {0} ... exited non-zero ({1})" " 'failed to report'".format(main, result)) if self._coverage_open: coverage_html_file = os.path.join(self._coverage_dir, 'html', 'index.html') binary_util.ui_open(coverage_html_file)
def _generate_ivy_report(self, resolve_hash_name): def make_empty_report(report, organisation, module, conf): no_deps_xml_template = dedent( """<?xml version="1.0" encoding="UTF-8"?> <?xml-stylesheet type="text/xsl" href="ivy-report.xsl"?> <ivy-report version="1.0"> <info organisation="{organisation}" module="{module}" revision="latest.integration" conf="{conf}" confs="{conf}" date="{timestamp}"/> </ivy-report> """ ).format(organisation=organisation, module=module, conf=conf, timestamp=time.strftime("%Y%m%d%H%M%S")) with open(report, "w") as report_handle: print(no_deps_xml_template, file=report_handle) tool_classpath = self.tool_classpath("xalan") report = None org = IvyUtils.INTERNAL_ORG_NAME name = resolve_hash_name xsl = os.path.join(self.ivy_cache_dir, "ivy-report.xsl") # Xalan needs this dir to exist - ensure that, but do no more - we have no clue where this # points. safe_mkdir(self._outdir, clean=False) for conf in self.confs: xml_path = self._get_report_path(conf, resolve_hash_name) if not os.path.exists(xml_path): # Make it clear that this is not the original report from Ivy by changing its name. xml_path = xml_path[:-4] + "-empty.xml" make_empty_report(xml_path, org, name, conf) out = os.path.join(self._outdir, "{org}-{name}-{conf}.html".format(org=org, name=name, conf=conf)) args = ["-IN", xml_path, "-XSL", xsl, "-OUT", out] # The ivy-report.xsl genrates tab links to files with extension 'xml' by default, we # override that to point to the html files we generate. args.extend(["-param", "extension", "html"]) if 0 != self.runjava( classpath=tool_classpath, main="org.apache.xalan.xslt.Process", args=args, workunit_name="report" ): raise self.Error("Failed to create html report from xml ivy report.") # The ivy-report.xsl is already smart enough to generate an html page with tab links to all # confs for a given report coordinate (org, name). We need only display 1 of the generated # htmls and the user can then navigate to the others via the tab links. if report is None: report = out css = os.path.join(self._outdir, "ivy-report.css") if os.path.exists(css): os.unlink(css) shutil.copy(os.path.join(self.ivy_cache_dir, "ivy-report.css"), self._outdir) if self._open and report: binary_util.ui_open(report)