## 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
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
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 ())
################################################################
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
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:
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 ()
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 ()
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.
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):
self.diff_lines = [l for l in diff]
self.diff_lines = self.diff_lines[2:]
- return float (len (self.diff_lines))
+ return math.sqrt (float (len ([l for l in self.diff_lines if l[0] in '-+'])))
def get_cell (self, oldnew):
str = ''
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'):
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
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
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 = []
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)
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)
pairs = []
missing = []
- for f in files[0].keys ():
+ for f in files[0]:
try:
files[1].pop (f)
pairs.append (f)
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)
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]
ext = os.path.splitext (f1)[1]
klasses = {
'.midi': MidiFileLink,
- '.log' : TextFileCompareLink,
+ '.log' : LogFileCompareLink,
'.profile': ProfileFileLink,
+ '.gittxt': GitFileCompareLink,
}
if klasses.has_key (ext):
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)
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)
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')
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 ():
names = [d['name'] for d in dicts]
- system ('lilypond -ddump-profile -dseparate-log-files -ddump-signatures --png -b eps ' + ' '.join (names))
+ system ('lilypond -ddump-profile -dseparate-log-files -ddump-signatures --png -dbackend=eps ' + ' '.join (names))
multipage_str = r'''
test_compare_signatures (names)
def test_compare_signatures (names, timing=False):
-
import time
times = 1
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,
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,
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()