async def run(self, ctx): diff = HtmlDiff() async with aclosing(ctx.detector.changed.stream_events()) as stream: async for event in stream: difference = diff.make_file(event.old_lines, event.new_lines, context=True) await ctx.mailer.create_and_deliver( subject='Change detected in %s' % event.source.url, html_body=difference) logger.info('Sent notification email')
def diff_text(text1, text2="", title1="", title2=""): txt1 = text1.splitlines(1) txt2 = text2.splitlines(1) d = HtmlDiff() result = d.make_file(txt1, txt2, title1, title2, context=True) return result
async def start(self, ctx): self.add_component('detector', ChangeDetectorComponent) self.add_component('mailer', backend='smtp') await super().start(ctx) diff = HtmlDiff() async for event in ctx.detector.changed.stream_events(): difference = diff.make_file(event.old_lines, event.new_lines, context=True) await ctx.mailer.create_and_deliver( subject='Change detected in %s' % event.source.url, html_body=difference) logger.info('Sent notification email')
def diff_working(repo,file,src=source.PATH): store=repo.object_store index=repo.open_index() tree=store[store[repo.head()].tree] parent_tree=store[store[store[repo.head()].parents[0]].tree] tree_ver=store[tree.lookup_path(store.peel_sha,file)[1]].data local_ver=open(os.path.join(repo.path,file)).read() h=HtmlDiff(wrapcolumn=70,tabsize=4) if src==source.PATH: f=h.make_file(tree_ver.splitlines(),local_ver.splitlines(), file, 'last commit:'+repo.head()) elif src==source.INDEX: index_ver=store[index._byname[file].sha].data f=h.make_file(tree_ver.splitlines(),index_ver.splitlines(),file+' staged change', 'last commit'+repo.head()) else: parent_tree_ver=store[parent_tree.lookup_path(store.peel_sha,file)[1]].data f=h.make_file(parent_tree_ver.splitlines(),tree_ver.splitlines(), file+' HEAD','HEAD^1') return f
def write_diff_file(updated_file, baseline_file): diff = HtmlDiff() updated_file = os.path.join(opt.data_root, 'characteristics', updated_file) baseline_file = os.path.join(opt.data_root, 'characteristics', baseline_file) with open(updated_file, 'r') as fh: updated_lines = fh.readlines() with open(baseline_file, 'r') as fh: baseline_lines = fh.readlines() diff_str = diff.make_file(baseline_lines, updated_lines, fromdesc=os.path.basename(baseline_file), todesc=os.path.basename(updated_file), context=True, numlines=5) diff_file = updated_file + '_diff.html' logger.info('Writing diff to {}'.format(diff_file)) with open(diff_file, 'w') as fh: fh.write(diff_str)
def admin_attempt_diff(request, contest=None, attempt_pk=None, quick=False): if not request.user.is_authenticated or not request.user.is_staff: return redirect("/admin/") attempt = get_object_or_404(models.Attempt, pk=attempt_pk) their_lines = [] my_lines = [] sizehint = [512] if quick else [] if attempt.outputfile: with open(attempt.outputfile.path) as theirs: their_lines = theirs.readlines(*sizehint) with open(attempt.get_outputfile_path()) as mine: my_lines = mine.readlines(*sizehint) differ = HtmlDiff() html = differ.make_file(their_lines, my_lines, fromdesc="User's output", todesc="Judge's output") return HttpResponse(html, content_type="text/html")
def html_diff_generate(target_path): """ Generate converted comparison file (. HTML) :param target_path: str, project path :return: bool, ignore """ htmlDiff = HtmlDiff() for file in find_files(path=target_path, pattern="*.py"): print(file) try: with open(file, "r", encoding='utf-8') as f: advanced = [line.strip('\n') for line in f.readlines()] with open(file + ".bak", "r", encoding='utf-8') as f: origin = [line.strip('\n') for line in f.readlines()] out_path = os.path.join(target_path, file.split("/")[-1].split(".")[0] + "_diff_comp.html") with open(out_path, 'w', encoding="utf-8") as f: f.writelines(htmlDiff.make_file(origin, advanced)) except Exception as e: raise e print(">>> *_diff_comp.html files had been generated!") return True
res != exp for res, exp in zip( resultSplit, expectedSplit)): failed = True resultPresentation = quote( result[section] ) if result[ section] else f'{WARNING}section was empty !{ENDC}' print( f'{BOLD}result was {WARNING}unexpected{ENDC} : {UNDERLINE}{file}{ENDC} ({section}){ENDLINE}{resultPresentation}' ) print( f'{BOLD}expected :{ENDC}{ENDLINE}{quote(expected[section])}' ) if VERBOSE: diff = HtmlDiff() htmlText = diff.make_file( resultSplit, expectedSplit) writeFile( file.replace( compExt.DEFAULT_CODE_EXTENSION, '_fail.html'), htmlText) else: print( f'{BOLD}{WARNING}results missing section {section}{ENDC}' ) sectionsMissingFromExpected = [ section for section in result.keys() if section not in expected ] if sectionsMissingFromExpected: vprint(
def htmlDiff(left, right): h = HtmlDiff(wrapcolumn=80) return h.make_file(htmlBeautify(left), htmlBeautify(right), context=True)
out_ref = open('out_ref.txt') out_stud = open('out_stud.txt') lines_ref = out_ref.read() lines_stud = out_stud.read() print lines_ref print lines_stud hd = HtmlDiff(tabsize=20, wrapcolumn=40, linejunk=lambda x: x == '5555\n', charjunk=lambda x: x == ' ') difference = hd.make_file(lines_stud, lines_ref) of = open('difference.html', 'w+') of.write(difference) of.close() dmp = diff_match_patch() of = open('difference_dmp.html', 'w+') diffs = dmp.diff_main(lines_stud, lines_ref) of.write(dmp.diff_prettyHtml(diffs)) of.close() dmp.diff_cleanupSemantic(diffs) for (flag, data) in diffs:
contentb = contentb.replace('\r\n','\n') if contenta == contentb: # 不同换行符导致不同 response['code'] = '202' return json.dumps(response) else: longer,shorter = (contenta,contentb) if len(contenta) >= len(contentb) else (contentb,contenta) if len(longer) - len(shorter) == 1 and longer[-1] == '\n': response['code'] = '203' return json.dumps(response) except Exception,e: response['code'] = '400' response['msg'] = repr(unicode(e)) return json.dumps(response) htmlDiff = HtmlDiff(tabsize=2,wrapcolumn=wrap_column,linejunk=IS_LINE_JUNK) fromdesc = filea.split('/',1)[0].encode('utf8') todesc = fileb.split('/',1)[0].encode('utf8') with open(os.path.join('static','tmp','tmp.html'),'w') as f: f.write(htmlDiff.make_file(contenta.splitlines(),contentb.splitlines(),fromdesc=fromdesc,todesc=todesc,context=is_context)) webbrowser.open_new_tab(os.path.join('static','tmp','tmp.html')) response['code'] = '200' return json.dumps(response) if __name__ == '__main__': try: port = int(sys.argv[1]) except Exception,e: warnings.warn('Invalid Input of port number. Will use default value 5050.') port = 5050 app.run(debug=True, port=port, threaded=True)
parser.add_argument('--encoding', default='utf-8') parser.add_argument('--nosoup', default=False, action='store_true') parser.add_argument('--soupthreshold', default=0.9, type=float) args = parser.parse_args() response = get_response(args.url, {}) original_body = response.body allow_soup = not args.nosoup tree = parse_response(body=original_body, encoding=args.encoding, allow_soup=allow_soup, soupthreshold=args.soupthreshold) parsed_body = etree.tostring(tree, method='html', encoding=args.encoding) original_body_lines = original_body.decode('utf-8').splitlines() parsed_body_lines = parsed_body.decode('utf-8').splitlines() output_file = '{fn}.diff.html'.format(fn=slug_from_url(args.url)) with(open(output_file, 'w')) as diff_file: htmldiff = HtmlDiff( wrapcolumn=59, charjunk=lambda c: c in [" ", "\t", "/"]) diff_html = htmldiff.make_file( original_body_lines, parsed_body_lines, context=True) diff_file.writelines(diff_html) print('opening diff in browser') subprocess.call(['open', output_file])
def run_edit_diff(): email_cnt = '''<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title></title> <style type="text/css"> table.diff {font-family:Courier; border:medium;} .diff_header {background-color:#e0e0e0} td.diff_header {text-align:right} .diff_next {background-color:#c0c0c0} .diff_add {background-color:#aaffaa} .diff_chg {background-color:#ffff77} .diff_sub {background-color:#ffaaaa} </style></head><body>''' mpost = MPost() mposthist = MPostHist() recent_posts = mpost.query_recent_edited(tools.timestamp() - 24 * 60 * 60) email_cnt = email_cnt + '<table border=1>' idx = 1 for recent_post in recent_posts: hist_rec = mposthist.get_last(recent_post.uid) if hist_rec: foo_str = ''' <tr><td>{0}</td><td class="diff_chg">Edit</td><td>{1}</td> <td><a href="{2}">{2}</a></td></tr> '''.format( idx, recent_post.title, os.path.join(site_url, 'post', recent_post.uid + '.html')) email_cnt = email_cnt + foo_str else: foo_str = ''' <tr><td>{0}</td><td class="diff_add">New </td><td>{1}</td> <td><a href="{2}">{2}</a></td></tr> '''.format( idx, recent_post.title, os.path.join(site_url, 'post', recent_post.uid + '.html')) email_cnt = email_cnt + foo_str idx = idx + 1 email_cnt = email_cnt + '</table>' recent_posts = mpost.query_recent_edited(tools.timestamp() - 24 * 60 * 60) diff_str = '' for recent_post in recent_posts: hist_rec = mposthist.get_last(recent_post.uid) if hist_rec: print('=' * 10) print(recent_post.title) raw_title = hist_rec.title new_title = recent_post.title test = HtmlDiff.make_file(HtmlDiff(), [raw_title], [new_title]) # if len(test) > 1: start = test.find('<table class="diff"') # 起点记录查询位置 end = test.find('</table>') infobox = test[start:end] + '</table>' if ('diff_add' in infobox) or ('diff_chg' in infobox) or ('diff_sub' in infobox): diff_str = diff_str + '<h2 style="color:red; font-size:larger; font-weight:70;">TITLE: {0}</h2> TITLE'.format( recent_post.title) + infobox raw_md = hist_rec.cnt_md.split('\n') new_md = recent_post.cnt_md.split('\n') test = HtmlDiff.make_file(HtmlDiff(), raw_md, new_md) # if len(test) >1 : start = test.find('<table class="diff"') # 起点记录查询位置 end = test.find('</table>') infobox = test[start:end] + '</table>' if ('diff_add' in infobox) or ('diff_chg' in infobox) or ('diff_sub' in infobox): diff_str = diff_str + '<h2 style="color:red; font-size:larger; font-weight:70;">TITLE: {0}</h2> CONTENT'.format( recent_post.title) + infobox + '</hr>' else: continue if len(diff_str) < 8000: email_cnt = email_cnt + diff_str email_cnt = email_cnt + '''<table class="diff" summary="Legends"> <tr> <th colspan="2"> Legends </th> </tr> <tr> <td> <table border="" summary="Colors"> <tr><th> Colors </th> </tr> <tr><td class="diff_add"> Added </td></tr> <tr><td class="diff_chg">Changed</td> </tr> <tr><td class="diff_sub">Deleted</td> </tr> </table></td> <td> <table border="" summary="Links"> <tr><th colspan="2"> Links </th> </tr> <tr><td>(f)irst change</td> </tr> <tr><td>(n)ext change</td> </tr> <tr><td>(t)op</td> </tr> </table></td> </tr> </table></body>''' print(email_cnt) send_mail(post_emails, "{0}|{1}|{2}".format(smtp_cfg['name'], '文档更新情况', datestr), email_cnt)
def run(self, args): job1_dir, job1_id = self._setup_job(args.jobids[0]) job2_dir, job2_id = self._setup_job(args.jobids[1]) job1_data = self._get_job_data(job1_dir) job2_data = self._get_job_data(job2_dir) report_header = 'Avocado Job Report\n' job1_results = [report_header] job2_results = [report_header] if 'cmdline' in args.diff_filter: cmdline1 = self._get_command_line(job1_dir) cmdline2 = self._get_command_line(job2_dir) if str(cmdline1) != str(cmdline2): command_line_header = ['\n', '# COMMAND LINE\n'] job1_results.extend(command_line_header) job1_results.append(cmdline1) job2_results.extend(command_line_header) job2_results.append(cmdline2) if 'time' in args.diff_filter: time1 = '%.2f s\n' % job1_data['time'] time2 = '%.2f s\n' % job2_data['time'] if str(time1) != str(time2): total_time_header = ['\n', '# TOTAL TIME\n'] job1_results.extend(total_time_header) job1_results.append(time1) job2_results.extend(total_time_header) job2_results.append(time2) if 'variants' in args.diff_filter: variants1 = self._get_variants(job1_dir) variants2 = self._get_variants(job2_dir) if str(variants1) != str(variants2): variants_header = ['\n', '# VARIANTS\n'] job1_results.extend(variants_header) job1_results.extend(variants1) job2_results.extend(variants_header) job2_results.extend(variants2) if 'results' in args.diff_filter: results1 = [] for test in job1_data['tests']: test_result = '%s: %s\n' % (str(test['url']), str(test['status'])) results1.append(test_result) results2 = [] for test in job2_data['tests']: test_result = '%s: %s\n' % (str(test['url']), str(test['status'])) results2.append(test_result) if str(results1) != str(results2): test_results_header = ['\n', '# TEST RESULTS\n'] job1_results.extend(test_results_header) job1_results.extend(results1) job2_results.extend(test_results_header) job2_results.extend(results2) if 'config' in args.diff_filter: config1 = self._get_config(job1_dir) config2 = self._get_config(job2_dir) if str(config1) != str(config2): config_header = ['\n', '# SETTINGS\n'] job1_results.extend(config_header) job1_results.extend(config1) job2_results.extend(config_header) job2_results.extend(config2) if 'sysinfo' in args.diff_filter: sysinfo_pre1 = self._get_sysinfo(job1_dir, 'pre') sysinfo_pre2 = self._get_sysinfo(job2_dir, 'pre') if str(sysinfo_pre1) != str(sysinfo_pre2): sysinfo_header_pre = ['\n', '# SYSINFO PRE\n'] job1_results.extend(sysinfo_header_pre) job1_results.extend(sysinfo_pre1) job2_results.extend(sysinfo_header_pre) job2_results.extend(sysinfo_pre2) sysinfo_post1 = self._get_sysinfo(job1_dir, 'post') sysinfo_post2 = self._get_sysinfo(job2_dir, 'post') if str(sysinfo_post1) != str(sysinfo_post2): sysinfo_header_post = ['\n', '# SYSINFO POST\n'] job1_results.extend(sysinfo_header_post) job1_results.extend(sysinfo_post1) job2_results.extend(sysinfo_header_post) job2_results.extend(sysinfo_post2) if getattr(args, 'create_reports', False): self.std_diff_output = False prefix = 'avocado_diff_%s_' % job1_id[:7] tmp_file1 = tempfile.NamedTemporaryFile(prefix=prefix, suffix='.txt', delete=False) tmp_file1.writelines(job1_results) tmp_file1.close() prefix = 'avocado_diff_%s_' % job2_id[:7] tmp_file2 = tempfile.NamedTemporaryFile(prefix=prefix, suffix='.txt', delete=False) tmp_file2.writelines(job2_results) tmp_file2.close() LOG.info('%s %s', tmp_file1.name, tmp_file2.name) if (getattr(args, 'open_browser', False) and getattr(args, 'html', None) is None): prefix = 'avocado_diff_%s_%s_' % (job1_id[:7], job2_id[:7]) tmp_file = tempfile.NamedTemporaryFile(prefix=prefix, suffix='.html', delete=False) setattr(args, 'html', tmp_file.name) if getattr(args, 'html', None) is not None: self.std_diff_output = False try: html_diff = HtmlDiff() html_diff._legend = """ <table class="diff" summary="Legends"> <tr> <td> <table border="" summary="Colors"> <tr><th> Colors </th> </tr> <tr><td class="diff_add"> Added </td></tr> <tr><td class="diff_chg">Changed</td> </tr> <tr><td class="diff_sub">Deleted</td> </tr> </table></td> <td> <table border="" summary="Links"> <tr><th colspan="2"> Links </th> </tr> <tr><td>(f)irst change</td> </tr> <tr><td>(n)ext change</td> </tr> <tr><td>(t)op</td> </tr> </table></td> </tr> </table>""" job_diff_html = html_diff.make_file((_.decode("utf-8") for _ in job1_results), (_.decode("utf-8") for _ in job2_results), fromdesc=job1_id, todesc=job2_id) with open(args.html, 'w') as html_file: html_file.writelines(job_diff_html.encode("utf-8")) LOG.info(args.html) except IOError as exception: LOG.error(exception) sys.exit(exit_codes.AVOCADO_FAIL) if getattr(args, 'open_browser', False): setsid = getattr(os, 'setsid', None) if not setsid: setsid = getattr(os, 'setpgrp', None) with open(os.devnull, "r+") as inout: cmd = ['xdg-open', args.html] subprocess.Popen(cmd, close_fds=True, stdin=inout, stdout=inout, stderr=inout, preexec_fn=setsid) if self.std_diff_output: if self.term.enabled: for line in self._cdiff(unified_diff(job1_results, job2_results, fromfile=job1_id, tofile=job2_id)): LOG.debug(line.strip()) else: for line in unified_diff(job1_results, job2_results, fromfile=job1_id, tofile=job2_id): LOG.debug(line.strip())
def run(self, config): def _get_name(test): return str(test['id']) def _get_name_no_id(test): return str(test['id']).split('-', 1)[1] job1_dir, job1_id = self._setup_job(config.get('diff.jobids')[0]) job2_dir, job2_id = self._setup_job(config.get('diff.jobids')[1]) job1_data = self._get_job_data(job1_dir) job2_data = self._get_job_data(job2_dir) report_header = 'Avocado Job Report\n' job1_results = [report_header] job2_results = [report_header] diff_filter = config.get('diff.filter') if 'cmdline' in diff_filter: cmdline1 = self._get_command_line(job1_dir) cmdline2 = self._get_command_line(job2_dir) if str(cmdline1) != str(cmdline2): command_line_header = ['\n', '# COMMAND LINE\n'] job1_results.extend(command_line_header) job1_results.append(cmdline1) job2_results.extend(command_line_header) job2_results.append(cmdline2) if 'time' in diff_filter: time1 = '%.2f s\n' % job1_data['time'] time2 = '%.2f s\n' % job2_data['time'] if str(time1) != str(time2): total_time_header = ['\n', '# TOTAL TIME\n'] job1_results.extend(total_time_header) job1_results.append(time1) job2_results.extend(total_time_header) job2_results.append(time2) if 'variants' in diff_filter: variants1 = self._get_variants(job1_dir) variants2 = self._get_variants(job2_dir) if str(variants1) != str(variants2): variants_header = ['\n', '# VARIANTS\n'] job1_results.extend(variants_header) job1_results.extend(variants1) job2_results.extend(variants_header) job2_results.extend(variants2) if 'results' in diff_filter: results1 = [] if config.get('diff.strip_id'): get_name = _get_name_no_id else: get_name = _get_name for test in job1_data['tests']: test_result = '%s: %s\n' % (get_name(test), str( test['status'])) results1.append(test_result) results2 = [] for test in job2_data['tests']: test_result = '%s: %s\n' % (get_name(test), str( test['status'])) results2.append(test_result) if str(results1) != str(results2): test_results_header = ['\n', '# TEST RESULTS\n'] job1_results.extend(test_results_header) job1_results.extend(results1) job2_results.extend(test_results_header) job2_results.extend(results2) if 'config' in diff_filter: config1 = self._get_config(job1_dir) config2 = self._get_config(job2_dir) if str(config1) != str(config2): config_header = ['\n', '# SETTINGS\n'] job1_results.extend(config_header) job1_results.extend(config1) job2_results.extend(config_header) job2_results.extend(config2) if 'sysinfo' in diff_filter: sysinfo_pre1 = self._get_sysinfo(job1_dir, 'pre') sysinfo_pre2 = self._get_sysinfo(job2_dir, 'pre') if str(sysinfo_pre1) != str(sysinfo_pre2): sysinfo_header_pre = ['\n', '# SYSINFO PRE\n'] job1_results.extend(sysinfo_header_pre) job1_results.extend(sysinfo_pre1) job2_results.extend(sysinfo_header_pre) job2_results.extend(sysinfo_pre2) sysinfo_post1 = self._get_sysinfo(job1_dir, 'post') sysinfo_post2 = self._get_sysinfo(job2_dir, 'post') if str(sysinfo_post1) != str(sysinfo_post2): sysinfo_header_post = ['\n', '# SYSINFO POST\n'] job1_results.extend(sysinfo_header_post) job1_results.extend(sysinfo_post1) job2_results.extend(sysinfo_header_post) job2_results.extend(sysinfo_post2) if config.get('diff.create_reports'): self.std_diff_output = False prefix = 'avocado_diff_%s_' % job1_id[:7] tmp_file1 = tempfile.NamedTemporaryFile(mode='w', prefix=prefix, suffix='.txt', delete=False) tmp_file1.writelines(job1_results) tmp_file1.close() prefix = 'avocado_diff_%s_' % job2_id[:7] tmp_file2 = tempfile.NamedTemporaryFile(mode='w', prefix=prefix, suffix='.txt', delete=False) tmp_file2.writelines(job2_results) tmp_file2.close() LOG_UI.info('%s %s', tmp_file1.name, tmp_file2.name) html_file = config.get('diff.html') open_browser = config.get('diff.open_browser') if open_browser and html_file is None: prefix = 'avocado_diff_%s_%s_' % (job1_id[:7], job2_id[:7]) tmp_file = tempfile.NamedTemporaryFile(mode='w', prefix=prefix, suffix='.html', delete=False) html_file = tmp_file.name if html_file is not None: self.std_diff_output = False try: html_diff = HtmlDiff() # pylint: disable=W0212 html_diff._legend = """ <table class="diff" summary="Legends"> <tr> <td> <table border="" summary="Colors"> <tr><th> Colors </th> </tr> <tr><td class="diff_add"> Added </td></tr> <tr><td class="diff_chg">Changed</td> </tr> <tr><td class="diff_sub">Deleted</td> </tr> </table></td> <td> <table border="" summary="Links"> <tr><th colspan="2"> Links </th> </tr> <tr><td>(f)irst change</td> </tr> <tr><td>(n)ext change</td> </tr> <tr><td>(t)op</td> </tr> </table></td> </tr> </table>""" job_diff_html = html_diff.make_file((_ for _ in job1_results), (_ for _ in job2_results), fromdesc=job1_id, todesc=job2_id) with open(html_file, 'w') as fp: fp.writelines(job_diff_html) LOG_UI.info(html_file) except IOError as exception: LOG_UI.error(exception) sys.exit(exit_codes.AVOCADO_FAIL) if open_browser: setsid = getattr(os, 'setsid', None) if not setsid: setsid = getattr(os, 'setpgrp', None) with open(os.devnull, "r+") as inout: cmd = ['xdg-open', html_file] subprocess.Popen( cmd, close_fds=True, stdin=inout, # pylint: disable=W1509 stdout=inout, stderr=inout, preexec_fn=setsid) if self.std_diff_output: if self.term.enabled: for line in self._cdiff( unified_diff(job1_results, job2_results, fromfile=job1_id, tofile=job2_id)): LOG_UI.debug(line.strip()) else: for line in unified_diff(job1_results, job2_results, fromfile=job1_id, tofile=job2_id): LOG_UI.debug(line.strip())
def run(self, config): def _get_name(test): return str(test["id"]) def _get_name_no_id(test): return str(test["id"]).split("-", 1)[1] job1_dir, job1_id = self._setup_job(config.get("diff.jobids")[0]) job2_dir, job2_id = self._setup_job(config.get("diff.jobids")[1]) job1_data = self._get_job_data(job1_dir) job2_data = self._get_job_data(job2_dir) report_header = "Avocado Job Report\n" job1_results = [report_header] job2_results = [report_header] diff_filter = config.get("diff.filter") if "cmdline" in diff_filter: cmdline1 = self._get_command_line(job1_dir) cmdline2 = self._get_command_line(job2_dir) if str(cmdline1) != str(cmdline2): command_line_header = ["\n", "# COMMAND LINE\n"] job1_results.extend(command_line_header) job1_results.append(cmdline1) job2_results.extend(command_line_header) job2_results.append(cmdline2) if "time" in diff_filter: time1 = f"{job1_data['time']:.2f} s\n" time2 = f"{job2_data['time']:.2f} s\n" if str(time1) != str(time2): total_time_header = ["\n", "# TOTAL TIME\n"] job1_results.extend(total_time_header) job1_results.append(time1) job2_results.extend(total_time_header) job2_results.append(time2) if "variants" in diff_filter: variants1 = self._get_variants(job1_dir) variants2 = self._get_variants(job2_dir) if str(variants1) != str(variants2): variants_header = ["\n", "# VARIANTS\n"] job1_results.extend(variants_header) job1_results.extend(variants1) job2_results.extend(variants_header) job2_results.extend(variants2) if "results" in diff_filter: results1 = [] if config.get("diff.strip_id"): get_name = _get_name_no_id else: get_name = _get_name for test in job1_data["tests"]: test_result = f"{get_name(test)}: {str(test['status'])}\n" results1.append(test_result) results2 = [] for test in job2_data["tests"]: test_result = f"{get_name(test)}: {str(test['status'])}\n" results2.append(test_result) if str(results1) != str(results2): test_results_header = ["\n", "# TEST RESULTS\n"] job1_results.extend(test_results_header) job1_results.extend(results1) job2_results.extend(test_results_header) job2_results.extend(results2) if "config" in diff_filter: config1 = self._get_config(job1_dir) config2 = self._get_config(job2_dir) if str(config1) != str(config2): config_header = ["\n", "# SETTINGS\n"] job1_results.extend(config_header) job1_results.extend(config1) job2_results.extend(config_header) job2_results.extend(config2) if "sysinfo" in diff_filter: sysinfo_pre1 = self._get_sysinfo(job1_dir, "pre") sysinfo_pre2 = self._get_sysinfo(job2_dir, "pre") if str(sysinfo_pre1) != str(sysinfo_pre2): sysinfo_header_pre = ["\n", "# SYSINFO PRE\n"] job1_results.extend(sysinfo_header_pre) job1_results.extend(sysinfo_pre1) job2_results.extend(sysinfo_header_pre) job2_results.extend(sysinfo_pre2) sysinfo_post1 = self._get_sysinfo(job1_dir, "post") sysinfo_post2 = self._get_sysinfo(job2_dir, "post") if str(sysinfo_post1) != str(sysinfo_post2): sysinfo_header_post = ["\n", "# SYSINFO POST\n"] job1_results.extend(sysinfo_header_post) job1_results.extend(sysinfo_post1) job2_results.extend(sysinfo_header_post) job2_results.extend(sysinfo_post2) if config.get("diff.create_reports"): self.std_diff_output = False prefix = f"avocado_diff_{job1_id[:7]}_" tmp_file1 = tempfile.NamedTemporaryFile(mode="w", prefix=prefix, suffix=".txt", delete=False) tmp_file1.writelines(job1_results) tmp_file1.close() prefix = f"avocado_diff_{job2_id[:7]}_" tmp_file2 = tempfile.NamedTemporaryFile(mode="w", prefix=prefix, suffix=".txt", delete=False) tmp_file2.writelines(job2_results) tmp_file2.close() LOG_UI.info("%s %s", tmp_file1.name, tmp_file2.name) html_file = config.get("diff.html") open_browser = config.get("diff.open_browser") if open_browser and html_file is None: prefix = f"avocado_diff_{job1_id[:7]}_{job2_id[:7]}_" tmp_file = tempfile.NamedTemporaryFile(mode="w", prefix=prefix, suffix=".html", delete=False) html_file = tmp_file.name if html_file is not None: self.std_diff_output = False try: html_diff = HtmlDiff() # pylint: disable=W0212 html_diff._legend = """ <table class="diff" summary="Legends"> <tr> <td> <table border="" summary="Colors"> <tr><th> Colors </th> </tr> <tr><td class="diff_add"> Added </td></tr> <tr><td class="diff_chg">Changed</td> </tr> <tr><td class="diff_sub">Deleted</td> </tr> </table></td> <td> <table border="" summary="Links"> <tr><th colspan="2"> Links </th> </tr> <tr><td>(f)irst change</td> </tr> <tr><td>(n)ext change</td> </tr> <tr><td>(t)op</td> </tr> </table></td> </tr> </table>""" job_diff_html = html_diff.make_file( (_ for _ in job1_results), (_ for _ in job2_results), fromdesc=job1_id, todesc=job2_id, ) with open(html_file, "w", encoding="utf-8") as fp: fp.writelines(job_diff_html) LOG_UI.info(html_file) except IOError as exception: LOG_UI.error(exception) sys.exit(exit_codes.AVOCADO_FAIL) if open_browser: setsid = getattr(os, "setsid", None) if not setsid: setsid = getattr(os, "setpgrp", None) with open(os.devnull, "r+", encoding="utf-8") as inout: cmd = ["xdg-open", html_file] subprocess.Popen( # pylint: disable=W1509 cmd, close_fds=True, stdin=inout, stdout=inout, stderr=inout, preexec_fn=setsid, ) if self.std_diff_output: if self.term.enabled: for line in self._cdiff( unified_diff(job1_results, job2_results, fromfile=job1_id, tofile=job2_id)): LOG_UI.debug(line.strip()) else: for line in unified_diff(job1_results, job2_results, fromfile=job1_id, tofile=job2_id): LOG_UI.debug(line.strip())