]> git.donarmstrong.com Git - lilypond.git/blobdiff - buildscripts/output-distance.py
Merge branch 'lilypond/translation' of ssh://jomand@git.sv.gnu.org/srv/git/lilypond
[lilypond.git] / buildscripts / output-distance.py
index 5af4570e05dcc67f743ae571457cf76a5831352c..8586d2481ab9cb9beb45bcd06c4b64685eee63b7 100644 (file)
@@ -7,9 +7,7 @@ import math
 ## so we can call directly as buildscripts/output-distance.py
 me_path = os.path.abspath (os.path.split (sys.argv[0])[0])
 sys.path.insert (0, me_path + '/../python/')
-
-
-import safeeval
+sys.path.insert (0, me_path + '/../python/out/')
 
 
 X_AXIS = 0
@@ -30,7 +28,7 @@ class TempDirectory:
         print 'dir is', self.dir
     def __del__ (self):
         print 'rm -rf %s' % self.dir 
-        os.system ('rm -rf %s' % self.dir )
+        os.system ('rm -rf %s' % self.dir)
     def __call__ (self):
         return self.dir
 
@@ -93,7 +91,7 @@ def compare_png_images (old, new, dest_dir):
 
     system ("convert  -depth 8 %(dir)s/diff.png -blur 0x3 -negate -channel alpha,blue -type TrueColorMatte -fx 'intensity'    %(dir)s/matte.png" % locals ())
 
-    system ("composite -quality 65 %(dir)s/matte.png %(new)s %(dest)s" % locals ())
+    system ("composite -compose atop -quality 65 %(dir)s/matte.png %(new)s %(dest)s" % locals ())
 
 
 ################################################################
@@ -349,7 +347,10 @@ class FileLink:
         
     def text_record_string (self):
         return '%-30f %-20s\n' % (self.distance (),
-                                  self.name ())
+                                  self.name ()
+                                  + os.path.splitext (self.file_names[1])[1]
+                                  )
+    
     def calc_distance (self):
         return 0.0
 
@@ -359,17 +360,24 @@ class FileLink:
 
         return self._distance
     
+    def source_file (self):
+        for ext in ('.ly', '.ly.txt'):
+            base = os.path.splitext (self.file_names[1])[0]
+            f = base + ext
+            if os.path.exists (f):
+                return f
+            
+        return ''
         
     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
-
+    
     def extension (self):
-        return '<undefined>'
+        return os.path.splitext (self.file_names[1])[1]
 
     def link_files_for_html (self, dest_dir):
         for f in self.file_names:
@@ -378,15 +386,13 @@ class FileLink:
     def get_distance_details (self):
         return ''
 
-    def get_cell (oldnew):
+    def get_cell (self, oldnew):
         return ''
     
     def get_file (self, oldnew):
         return self.file_names[oldnew]
     
     def html_record_string (self, dest_dir):
-        self.link_files_for_html (dest_dir)
-        
         dist = self.distance()
         
         details = self.get_distance_details ()
@@ -394,7 +400,7 @@ class FileLink:
             details_base = os.path.splitext (self.file_names[1])[0]
             details_base += '.details.html'
             fn = dest_dir + '/'  + details_base
-            open (fn, 'w').write (details)
+            open_write_file (fn).write (details)
 
             details = '<br>(<a href="%(details_base)s">details</a>)' % locals ()
 
@@ -422,9 +428,6 @@ class FileCompareLink (FileLink):
                          self.get_content (self.file_names[1]))
         
 
-    def extension (self):
-        return '.ext'
-
     def calc_distance (self):
         ## todo: could use import MIDI to pinpoint
         ## what & where changed.
@@ -438,7 +441,27 @@ class FileCompareLink (FileLink):
         print 'reading', f
         s = open (f).read ()
         return s
+
+
+class GitFileCompareLink (FileCompareLink):
+    def get_cell (self, oldnew):
+        str = self.contents[oldnew]
+
+        # truncate long lines
+        str = '\n'.join ([l[:80] for l in str.split ('\n')])
+
+        
+        str = '<font size="-2"><pre>%s</pre></font>' % str
+        return str
     
+    def calc_distance (self):
+        if self.contents[0] == self.contents[1]:
+            d = 0.0
+        else:
+            d = 1.0001 *options.threshold
+
+        return d
+
         
 class TextFileCompareLink (FileCompareLink):
     def calc_distance (self):
@@ -452,7 +475,7 @@ class TextFileCompareLink (FileCompareLink):
         self.diff_lines =  [l for l in diff]
         self.diff_lines = self.diff_lines[2:]
         
-        return float (len ([l for l in self.diff_lines if l[0] in '-+']))
+        return math.sqrt (float (len ([l for l in self.diff_lines if l[0] in '-+'])))
         
     def get_cell (self, oldnew):
         str = ''
@@ -461,21 +484,17 @@ class TextFileCompareLink (FileCompareLink):
         str = '<font size="-2"><pre>%s</pre></font>' % str
         return str
 
-    def extension (self):
-        return '.txt'
-    
 class LogFileCompareLink (TextFileCompareLink):
-    def extension (self):
-        return '.log'
-
+  def get_content (self, f):
+      c = TextFileCompareLink.get_content (self, f)
+      c = re.sub ("\nProcessing `[^\n]+'\n", '', c)
+      return c
+        
 class ProfileFileLink (FileCompareLink):
     def __init__ (self, f1, f2):
         FileCompareLink.__init__ (self, f1, f2)
         self.results = [{}, {}]
     
-    def extension (self):
-        return '.profile'
-
     def get_cell (self, oldnew):
         str = ''
         for k in ('time', 'cells'):
@@ -483,7 +502,7 @@ class ProfileFileLink (FileCompareLink):
                 str += '%-8s: %d\n' %  (k, int (self.results[oldnew][k]))
             else:
                 str += '%-8s: %8d (%5.3f)\n' % (k, int (self.results[oldnew][k]),
-                                         self.get_ratio (k))
+                                                self.get_ratio (k))
 
         return '<pre>%s</pre>' % str
             
@@ -505,40 +524,48 @@ class ProfileFileLink (FileCompareLink):
                     note_info, self.contents[oldnew])
 
         dist = 0.0
-        factor = {'time': 1.0 ,
-                  'cells': 10.0,
-                  }
+        factor = {
+            'time': 0.1,
+            'cells': 5.0,
+            }
         
         for k in ('time', 'cells'):
-            dist += math.exp (self.get_ratio (k) * factor[k]) - 1
+            real_val = math.tan (self.get_ratio (k) * 0.5 * math.pi)
+            dist += math.exp (math.fabs (real_val) * factor[k])  - 1
 
         dist = min (dist, 100)
         return dist
 
-class MidiFileLink (FileCompareLink):
-    def get_content (self, f):
-        s = FileCompareLink.get_content (self, f)
-        s = re.sub ('LilyPond [0-9.]+', '', s)
-        return s
     
-    def get_cell (self, oldnew):
+class MidiFileLink (TextFileCompareLink):
+    def get_content (self, oldnew):
+        import midi
+        
+        data = FileCompareLink.get_content (self, oldnew)
+        midi = midi.parse (data)
+        tracks = midi[1]
+
         str = ''
-        if oldnew == 1 and self.distance () > 0:
-            str = 'changed' 
+        j = 0
+        for t in tracks:
+            str += 'track %d' % j
+            j += 1
+
+            for e in t:
+                ev_str = repr (e)
+                if re.search ('LilyPond [0-9.]+', ev_str):
+                    continue
+                
+                str += '  ev %s\n' % `e`
         return str
-        
-    def extension (self):
-        return '.midi'
     
 
+
 class SignatureFileLink (FileLink):
     def __init__ (self, f1, f2 ):
         FileLink.__init__ (self, f1, f2)
         self.system_links = {}
 
-    def extension (self):
-        return '.ly'
-
     def add_system_link (self, link, number):
         self.system_links[number] = link
 
@@ -552,12 +579,6 @@ class SignatureFileLink (FileLink):
             
         return d + orphan_distance
 
-    def source_file (self):
-        for ext in ('.ly', '.ly.txt'):
-            if os.path.exists (self.base_names[1] + ext):
-                return self.base_names[1] + ext
-        return ''
-    
     def add_file_compare (self, f1, f2):
         system_index = [] 
 
@@ -571,18 +592,6 @@ class SignatureFileLink (FileLink):
         self.base_names = (os.path.normpath (base1),
                            os.path.normpath (base2))
 
-        def note_original (match):
-            hash_to_original_name[os.path.basename (self.base_names[1])] = match.group (1)
-            return ''
-        
-        ## ugh: drop the .ly.txt
-        for ext in ('.ly', '.ly.txt'):
-            try:
-                re.sub (r'\\sourcefilename "([^"]+)"',
-                        note_original, open (base1 + ext).read ())
-            except IOError:
-                pass
-                
         s1 = read_signature_file (f1)
         s2 = read_signature_file (f2)
 
@@ -600,12 +609,17 @@ class SignatureFileLink (FileLink):
             for f in glob.glob (pat):
                 infile = f
                 outfile = (dest_dir + '/' + f).replace ('.eps', '.png')
-
+                data_option = ''
+                if options.local_data_dir:
+                    data_option = ('-slilypond-datadir=%s/../share/lilypond/current '
+                                   % os.path.dirname(infile))
+                
                 mkdir (os.path.split (outfile)[0])
                 cmd = ('gs -sDEVICE=png16m -dGraphicsAlphaBits=4 -dTextAlphaBits=4 '
+                       ' %(data_option)s '
                        ' -r101 '
                        ' -sOutputFile=%(outfile)s -dNOSAFER -dEPSCrop -q -dNOPAUSE '
-                       ' %(infile)s  -c quit '  % locals ())
+                       ' %(infile)s  -c quit ') % locals ()
 
                 files_created[oldnew].append (outfile)
                 system (cmd)
@@ -759,7 +773,7 @@ def paired_files (dir1, dir2, pattern):
         
     pairs = []
     missing = []
-    for f in files[0].keys ():
+    for f in files[0]:
         try:
             files[1].pop (f)
             pairs.append (f)
@@ -775,6 +789,23 @@ class ComparisonData:
         self.added = []
         self.file_links = {}
 
+    def read_sources (self):
+
+        ## ugh: drop the .ly.txt
+        for (key, val) in self.file_links.items ():
+            
+            def note_original (match, ln=val):
+                key = ln.name ()
+                hash_to_original_name[key] = match.group (1)
+                return ''
+
+            sf = val.source_file ()
+            if sf:
+                re.sub (r'\\sourcefilename "([^"]+)"',
+                        note_original, open (sf).read ())
+            else:
+                print 'no source for', val
+        
     def compare_trees (self, dir1, dir2):
         self.compare_directories (dir1, dir2)
         
@@ -790,7 +821,11 @@ class ComparisonData:
                 self.compare_trees (d1, d2)
     
     def compare_directories (self, dir1, dir2):
-        for ext in ['signature', 'midi', 'log', 'profile']:
+        for ext in ['signature',
+                    'midi',
+                    'log',
+                    'profile',
+                    'gittxt']:
             (paired, m1, m2) = paired_files (dir1, dir2, '*.' + ext)
 
             self.missing += [(dir1, m) for m in m1] 
@@ -812,8 +847,9 @@ class ComparisonData:
             ext = os.path.splitext (f1)[1]
             klasses = {
                 '.midi': MidiFileLink,
-                '.log' : TextFileCompareLink,
+                '.log' : LogFileCompareLink,
                 '.profile': ProfileFileLink,
+                '.gittxt': GitFileCompareLink, 
                 }
             
             if klasses.has_key (ext):
@@ -840,13 +876,15 @@ class ComparisonData:
 
         file_link.add_file_compare (f1, f2)
 
-    def remove_changed (self, dir, threshold):
+    def write_changed (self, dest_dir, threshold):
         (changed, below, unchanged) = self.thresholded_results (threshold)
-        for link in changed:
-            try:
-                system ('rm -f %s*' % link.base_names[1])
-            except AttributeError: ### UGH.
-                system ('rm -f %s/%s*' % (dir, link.name ()))
+
+        str = '\n'.join ([os.path.splitext (link.file_names[1])[0]
+                        for link in changed])
+        fn = dest_dir + '/changed.txt'
+        
+        open_write_file (fn).write (str)
+                
     def thresholded_results (self, threshold):
         ## todo: support more scores.
         results = [(link.distance(), link)
@@ -917,22 +955,27 @@ class ComparisonData:
 
         dest_file = dest_dir + '/index.html'
         open_write_file (dest_file).write (html)
+
+
+        for link in changed:
+            link.link_files_for_html (dest_dir)
         
+
     def print_results (self, threshold):
         self.write_text_result_page ('', threshold)
 
 def compare_trees (dir1, dir2, dest_dir, threshold):
     data = ComparisonData ()
     data.compare_trees (dir1, dir2)
-    data.print_results (threshold)
+    data.read_sources ()
 
-    if options.remove_changed:
-        data.remove_changed (dir2, threshold)
-        return
     
+    data.print_results (threshold)
+
     if os.path.isdir (dest_dir):
         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)
     
@@ -996,6 +1039,8 @@ def test_compare_trees ():
     system ('cp 19.sub{-*.signature,.ly,.png,.eps,.log,.profile} dir2/subdir/')
     system ('cp 20grob{-*.signature,.ly,.png,.eps,.log,.profile} dir2/')
     system ('cp 20grob{-*.signature,.ly,.png,.eps,.log,.profile} dir1/')
+    system ('echo HEAD is 1 > dir1/tree.gittxt')
+    system ('echo HEAD is 2 > dir2/tree.gittxt')
 
     ## introduce differences
     system ('cp 19-1.signature dir2/20-1.signature')
@@ -1014,7 +1059,7 @@ def test_compare_trees ():
     system ('cp 19multipage.log dir1/log-differ.log')
     system ('cp 19multipage.log dir2/log-differ.log &&  echo different >> dir2/log-differ.log &&  echo different >> dir2/log-differ.log')
 
-    compare_trees ('dir1', 'dir2', 'compare-dir1dir2', 0.5)
+    compare_trees ('dir1', 'dir2', 'compare-dir1dir2', options.threshold)
 
 
 def test_basic_compare ():
@@ -1067,7 +1112,7 @@ def test_basic_compare ():
         
     names = [d['name'] for d in dicts]
 
-    system ('lilypond -ddump-profile -dseparate-log-files -ddump-signatures --png -eps ' + ' '.join (names))
+    system ('lilypond -ddump-profile -dseparate-log-files -ddump-signatures --png -dbackend=eps ' + ' '.join (names))
     
 
     multipage_str = r'''
@@ -1086,7 +1131,6 @@ def test_basic_compare ():
     test_compare_signatures (names)
     
 def test_compare_signatures (names, timing=False):
-
     import time
 
     times = 1
@@ -1169,13 +1213,6 @@ def main ():
                   type="float",
                   help='threshold for geometric distance')
 
-
-    p.add_option ('--remove-changed',
-                  dest="remove_changed",
-                  default=False,
-                  action="store_true",
-                  help="Remove all files from tree2 that are over the threshold.")
-
     p.add_option ('--no-compare-images',
                   dest="compare_images",
                   default=True,
@@ -1188,6 +1225,13 @@ def main ():
                   action="store_true",
                   help="Create PNGs from EPSes")
 
+
+    p.add_option ('--local-datadir',
+                  dest="local_data_dir",
+                  default=False,
+                  action="store_true",
+                  help='whether to use the share/lilypond/ directory in the test directory')
+
     p.add_option ('-o', '--output-dir',
                   dest="output_dir",
                   default=None,
@@ -1196,22 +1240,22 @@ def main ():
                   help='where to put the test results [tree2/compare-tree1tree2]')
 
     global options
-    (options, a) = p.parse_args ()
+    (options, args) = p.parse_args ()
 
     if options.run_test:
         run_tests ()
         sys.exit (0)
 
-    if len (a) != 2:
+    if len (args) != 2:
         p.print_usage()
         sys.exit (2)
 
     name = options.output_dir
     if not name:
-        name = a[0].replace ('/', '')
-        name = os.path.join (a[1], 'compare-' + shorten_string (name))
+        name = args[0].replace ('/', '')
+        name = os.path.join (args[1], 'compare-' + shorten_string (name))
     
-    compare_trees (a[0], a[1], name, options.threshold)
+    compare_trees (args[0], args[1], name, options.threshold)
 
 if __name__ == '__main__':
     main()