]> git.donarmstrong.com Git - lilypond.git/blobdiff - scripts/build/output-distance.py
Issue 4364: Allow ImageMagick's compare to exit with status 1
[lilypond.git] / scripts / build / output-distance.py
index d2d55d77fab4cc0479869262e5116f06ac25fa71..49a659b73febd69fff0f79f01b0536b016cf7c1c 100755 (executable)
@@ -53,8 +53,7 @@ def system (c):
         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
@@ -90,7 +89,7 @@ def compare_png_images (old, new, dest_dir):
     system ('convert -depth 8 -crop %dx%d+0+0 %s %s/crop1.png' % (dims + (old, dir)))
     system ('convert -depth 8 -crop %dx%d+0+0 %s %s/crop2.png' % (dims + (new, dir)))
 
-    system ('compare -depth 8 -dissimilarity-threshold 1 %(dir)s/crop1.png %(dir)s/crop2.png %(dir)s/diff.png' % locals ())
+    system1 ('compare -depth 8 -dissimilarity-threshold 1 %(dir)s/crop1.png %(dir)s/crop2.png %(dir)s/diff.png' % locals ())
 
     system ("convert  -depth 8 %(dir)s/diff.png -blur 0x3 -negate -channel alpha,blue -type TrueColorMatte -fx 'intensity'    %(dir)s/matte.png" % locals ())
 
@@ -377,12 +376,18 @@ class FileLink:
 
         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]
@@ -500,7 +505,7 @@ class TextFileCompareLink (FileCompareLink):
         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):
@@ -523,7 +528,7 @@ class ProfileFileLink (FileCompareLink):
                 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),
@@ -822,13 +827,25 @@ class ComparisonData:
                 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)
 
@@ -874,14 +891,18 @@ class ComparisonData:
                 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:
@@ -934,25 +955,31 @@ class ComparisonData:
         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)
 
+        header_row = '''
+<tr>
+<th>distance</th>
+<th>%(short_dir1)s</th>
+<th>%(short_dir2)s</th>
+</tr>
+'''
 
         table_rows = ''
-        old_prefix = os.path.split (dir1)[1]
+        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)
 
-
-        short_dir1 = shorten_string (dir1)
-        short_dir2 = shorten_string (dir2)
-
         summary = ''
         below_count = len (below)
 
@@ -961,9 +988,12 @@ class ComparisonData:
 
         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");
@@ -973,7 +1003,8 @@ class ComparisonData:
             row = rows[i];
             html = row.innerHTML;
             row.style.display =
-                (html.indexOf(substring + '">') != -1) ? "" : "none";
+                ((html.indexOf('>distance<') != -1) ||
+                 (html.indexOf(substring + '">') != -1)) ? "" : "none";
         }
     }
 // ]]>
@@ -998,11 +1029,6 @@ class ComparisonData:
 <hr />
 
 <table rules="rows" border bordercolor="blue">
-<tr>
-<th>distance</th>
-<th>%(short_dir1)s</th>
-<th>%(short_dir2)s</th>
-</tr>
 %(table_rows)s
 </table>
 </body>
@@ -1031,8 +1057,8 @@ def compare_tree_pairs (tree_pairs, dest_dir, threshold):
         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
@@ -1063,6 +1089,12 @@ def system (x):
     stat = os.system (x)
     assert stat == 0
 
+def system1 (x):
+# Allow exit status 0 and 1
+    print 'invoking', x
+    stat = os.system (x)
+    assert (stat == 0) or (stat == 256) # This return value convention is sick.
+
 
 def test_paired_files ():
     print paired_files (os.environ["HOME"] + "/src/lilypond/scripts/",