import optparse
import os
import math
+import re
+
+import cgi
## so we can call directly as scripts/build/output-distance.py
me_path = os.path.abspath (os.path.split (sys.argv[0])[0])
raise Exception ("failed")
return
-def shorten_string (s):
- threshold = 15
+def shorten_string (s, threshold = 15):
if len (s) > 2*threshold:
s = s[:threshold] + '..' + s[-threshold:]
return s
self.orphan_count (),
self.geometric_distance ())
+def scheme_float (s) :
+ if 'nan' not in s :
+ return float(s)
+ return float(s.split('.')[0])
+
def read_signature_file (name):
print 'reading', name
entries = open (name).read ().split ('\n')
def string_to_tup (s):
- return tuple (map (float, s.split (' ')))
+ return tuple (map (scheme_float, s.split (' ')))
def string_to_entry (s):
fields = s.split('@')
return ''
+ def directories (self):
+ return map (os.path.dirname, self.file_names)
+
def name (self):
base = os.path.basename (self.file_names[1])
base = os.path.splitext (base)[0]
base = hash_to_original_name.get (base, base)
base = os.path.splitext (base)[0]
- return base
+ return os.path.join (self.prefix (), base)
+
+ def prefix (self):
+ return os.path.dirname (os.path.commonprefix (self.file_names))
def extension (self):
return os.path.splitext (self.file_names[1])[1]
str = '\n'.join ([l[:80] for l in str.split ('\n')])
- str = '<font size="-2"><pre>%s</pre></font>' % str
+ str = '<font size="-2"><pre>%s</pre></font>' % cgi.escape (str)
return str
def calc_distance (self):
return d
+snippet_fn_re = re.compile (r"`\./([0-9a-f]{2}/lily-[0-9a-f]{8}).eps'");
class TextFileCompareLink (FileCompareLink):
def calc_distance (self):
import difflib
- diff = difflib.unified_diff (self.contents[0].strip().split ('\n'),
- self.contents[1].strip().split ('\n'),
+ # Extract the old and the new hashed snippet names from the log file
+ # and replace the old by the new, so file name changes don't show
+ # up as log differences...
+ cont0 = self.contents[0].strip();
+ cont1 = self.contents[1].strip();
+ m0 = re.search (snippet_fn_re, cont0);
+ m1 = re.search (snippet_fn_re, cont1);
+ if (m0 and m1 and (m0.group(1) != m1.group(1))):
+ cont0 = cont0.replace (m0.group(1), m1.group(1));
+
+ diff = difflib.unified_diff (cont0.split ('\n'),
+ cont1.split ('\n'),
fromfiledate = self.file_names[0],
tofiledate = self.file_names[1]
)
str = ''
if oldnew == 1:
str = '\n'.join ([d.replace ('\n','') for d in self.diff_lines])
- str = '<font size="-2"><pre>%s</pre></font>' % str
+ str = '<font size="-2"><pre>%s</pre></font>' % cgi.escape (str)
return str
class LogFileCompareLink (TextFileCompareLink):
str += '%-8s: %8d (%5.3f)\n' % (k, int (self.results[oldnew][k]),
self.get_ratio (k))
- return '<pre>%s</pre>' % str
+ return '<pre>%s</pre>' % cgi.escape (str)
def get_ratio (self, key):
(v1,v2) = (self.results[0].get (key, -1),
# Files/directories
import glob
-import re
def compare_signature_files (f1, f2):
s1 = read_signature_file (f1)
re.sub (r'\\sourcefilename "([^"]+)"',
note_original, open (sf).read ())
else:
- print 'no source for', val
+ print 'no source for', val.file_names[1]
def compare_trees (self, dir1, dir2):
self.compare_directories (dir1, dir2)
- (root, dirs, files) = os.walk (dir1).next ()
+ try:
+ (root, dirs, files) = os.walk (dir1).next ()
+ except StopIteration:
+ if dir1.endswith("-baseline"):
+ sys.stderr.write("Failed to walk through %s. This can be caused by forgetting to run make test-baseline.\n" % dir1)
+ else:
+ sys.stderr.write("Failed to walk through %s; please check it exists.\n" % dir1)
+ sys.exit(1)
+
for d in dirs:
+ # don't walk the share folders
+ if d.startswith("share"):
+ continue
+
d1 = os.path.join (dir1, d)
d2 = os.path.join (dir2, d)
self.compare_general_files (klasses[ext], f1, f2)
def compare_general_files (self, klass, f1, f2):
+ prefix = os.path.commonprefix ([f1, f2])
name = os.path.split (f1)[1]
+ name = os.path.join (prefix, name)
file_link = klass (f1, f2)
self.file_links[name] = file_link
def compare_signature_files (self, f1, f2):
+ prefix = os.path.commonprefix ([f1, f2])
name = os.path.split (f1)[1]
name = re.sub ('-[0-9]+.signature', '', name)
+ name = os.path.join (prefix, name)
file_link = None
try:
out.write ('%d below threshold\n' % len (below))
out.write ('%d unchanged\n' % len (unchanged))
- def create_text_result_page (self, dir1, dir2, dest_dir, threshold):
+ def create_text_result_page (self, dest_dir, threshold):
self.write_text_result_page (dest_dir + '/index.txt', threshold)
- def create_html_result_page (self, dir1, dir2, dest_dir, threshold):
- dir1 = dir1.replace ('//', '/')
- dir2 = dir2.replace ('//', '/')
-
+ def create_html_result_page (self, dest_dir, threshold):
(changed, below, unchanged) = self.thresholded_results (threshold)
-
- html = ''
- old_prefix = os.path.split (dir1)[1]
- for link in changed:
- html += link.html_record_string (dest_dir)
-
-
- short_dir1 = shorten_string (dir1)
- short_dir2 = shorten_string (dir2)
- html = '''<html>
-<table rules="rows" border bordercolor="blue">
+ header_row = '''
<tr>
<th>distance</th>
<th>%(short_dir1)s</th>
<th>%(short_dir2)s</th>
</tr>
-%(html)s
-</table>
-</html>''' % locals()
+'''
- html += ('<p>')
+ table_rows = ''
+ old_prefix = None
+ for link in changed:
+ this_prefix = link.prefix ()
+ if (old_prefix != this_prefix):
+ old_prefix = this_prefix
+ short_dir1 = shorten_string (link.directories ()[0], 30)
+ short_dir2 = shorten_string (link.directories ()[1], 30)
+ table_rows += header_row % locals()
+ table_rows += link.html_record_string (dest_dir)
+
+ summary = ''
below_count = len (below)
if below_count:
- html += ('<p>%d below threshold</p>' % below_count)
+ summary += '<p>%d below threshold</p>' % below_count
+
+ summary += '<p>%d unchanged</p>' % len (unchanged)
+
+ me = sys.argv[0]
+
+ html = '''<html>
+<head>
+<title>LilyPond regression test results</title>
+<meta name="author" content="This file was autogenerated by %(me)s">
+<script language="javascript" type="text/javascript">
+// <![CDATA[
+ var rows = document.getElementsByTagName("tr");
+ function showOnlyMatchingRows(substring) {
+ var rowcount = rows.length;
+ for (var i = 0; i < rowcount; i++) {
+ row = rows[i];
+ html = row.innerHTML;
+ row.style.display =
+ ((html.indexOf('>distance<') != -1) ||
+ (html.indexOf(substring + '">') != -1)) ? "" : "none";
+ }
+ }
+// ]]>
+</script>
+</head>
+<body>
+<p>
+ click to filter rows by type:
+ <a href="#" onClick="showOnlyMatchingRows('.ly')">ly</a> /
+ <a href="#" onClick="showOnlyMatchingRows('.profile')">profiling</a> /
+ <a href="#" onClick="showOnlyMatchingRows('.signature')">signature</a> /
+ <a href="#" onClick="showOnlyMatchingRows('.midi')">midi</a> /
+ <a href="#" onClick="showOnlyMatchingRows('.log')">log</a> /
+ <a href="#" onClick="showOnlyMatchingRows('.gittxt')">gittxt</a> /
+ <a href="#" onClick="showOnlyMatchingRows('')">reset to all</a>
+</p>
+
+<hr />
+
+%(summary)s
+
+<hr />
- html += ('<p>%d unchanged</p>' % len (unchanged))
+<table rules="rows" border bordercolor="blue">
+%(table_rows)s
+</table>
+</body>
+</html>''' % locals()
dest_file = dest_dir + '/index.html'
open_write_file (dest_file).write (html)
system ('rm -rf %s '% dest_dir)
data.write_changed (dest_dir, threshold)
- data.create_html_result_page (dir1, dir2, dest_dir, threshold)
- data.create_text_result_page (dir1, dir2, dest_dir, threshold)
+ data.create_html_result_page (dest_dir, threshold)
+ data.create_text_result_page (dest_dir, threshold)
################################################################
# TESTING
run_tests ()
sys.exit (0)
- if len (args) % 2:
+ if len (args) % 2 == 1:
p.print_usage ()
sys.exit (2)