mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-12-21 05:00:59 +00:00
322 lines
8.2 KiB
Python
322 lines
8.2 KiB
Python
|
#!/usr/bin/python
|
||
|
# -*- coding: utf-8 -*-
|
||
|
|
||
|
import os
|
||
|
from subprocess import call, check_call
|
||
|
from random import randrange
|
||
|
import getpass
|
||
|
|
||
|
|
||
|
outfilename = "/tmp/cache-bisect." + getpass.getuser() + ".log"
|
||
|
outfile = open(outfilename, 'w')
|
||
|
print 'BBBISECT_BEGIN'
|
||
|
#print >> outfile, 'BBBISECT_BEGIN'
|
||
|
#print >> outfile, 'BBBISECT_BEGIN'
|
||
|
#print >> outfile, 'BBBISECT_BEGIN'
|
||
|
#print >> outfile, 'BBBISECT_BEGIN'
|
||
|
#print >> outfile, 'BBBISECT_BEGIN'
|
||
|
#print 'BBBISECT_BEGIN'
|
||
|
|
||
|
source_dir = '/mnt/big/xp/src/lyx-1.6.x-bisect' # must NOT end in a slash
|
||
|
cache_dir = source_dir + '.cache/' # must end in a slash
|
||
|
source_dir = '/mnt/big/xp/src/lyx-1.6.x-bisect2' # must NOT end in a slash
|
||
|
|
||
|
#make_cmd = 'autoconf && ./configure && cd src && echo __________ `pwd` && sleep 9 && make'
|
||
|
make_cmd = 'rm -rf autom4te.cache && autoconf && ./configure && cd src && make'
|
||
|
|
||
|
reverse_search = True
|
||
|
reverse_search = False
|
||
|
must_make = True # If we fail to make the file, we could this a "bad" rather than "canot test"
|
||
|
must_make = False
|
||
|
|
||
|
# ToDo:
|
||
|
# replace .tmp with .partial_copy and .not_yet_made
|
||
|
|
||
|
|
||
|
def set_revision(new_v, tmp_d):
|
||
|
#check_call(['svn', 'up', '-r' + new_v, '--force'], cwd=tmp_d)
|
||
|
os.system ('cd "'+tmp_d+'" && yes tf | svn up -r'+new_v+'--force')
|
||
|
|
||
|
def cmp_version(x, y):
|
||
|
return cmp(int(x), int(y))
|
||
|
|
||
|
|
||
|
def get_cached_versions():
|
||
|
vers = [f for f in os.listdir(cache_dir) if not f.count('.')]
|
||
|
vers.sort(cmp_version)
|
||
|
return vers
|
||
|
|
||
|
|
||
|
def version_in_range(v, lo, hi):
|
||
|
if cmp_version(v, lo) < 0:
|
||
|
return False
|
||
|
elif cmp_version(v, hi) > 0:
|
||
|
return False
|
||
|
return True
|
||
|
|
||
|
def killall_p (s):
|
||
|
# Unlike killall, this searchs within command parameters, as well as the
|
||
|
# command name
|
||
|
|
||
|
#os.system("kPID=`ps a | grep '"+s+"' | grep -v grep | sed 's/^ *//g'| sed 's/ .*$//'`
|
||
|
os.system("(kPID=`ps a | grep '"+s+
|
||
|
"' | grep -v grep | sed 's/^ *//g'| sed 's/ .*$//'`\n\
|
||
|
echo kPID $kPID "+s+"\n\
|
||
|
echo kill $kPID\n\
|
||
|
kill $kPID\n\
|
||
|
sleep 0.1\n\
|
||
|
echo kill -9 $kPID\n\
|
||
|
kill -9 $kPID) 2> /dev/null")
|
||
|
|
||
|
def clean_up ():
|
||
|
killall_p("autolyx")
|
||
|
killall_p("lyx")
|
||
|
killall_p("keytest.py")
|
||
|
killall_p("xclip")
|
||
|
|
||
|
def filter_versions(vers, lo, hi):
|
||
|
return [v for v in vers if cmp]
|
||
|
|
||
|
|
||
|
def ver2dir(v):
|
||
|
return cache_dir + v
|
||
|
|
||
|
|
||
|
def make_ver(new_v, old_v=None, alt_v=None):
|
||
|
print 'MAKING', new_v, old_v, alt_v
|
||
|
new_d = ver2dir(new_v)
|
||
|
if old_v is None:
|
||
|
old_d = source_dir
|
||
|
else:
|
||
|
old_d = ver2dir(old_v)
|
||
|
fail_d = new_d + '.fail'
|
||
|
tmp_d = new_d + '.tmp'
|
||
|
if os.path.exists(cache_dir + fail_d):
|
||
|
return 1
|
||
|
if os.path.exists(new_d):
|
||
|
return 0
|
||
|
if not os.path.exists(tmp_d):
|
||
|
if not os.path.exists(old_d):
|
||
|
old_d = old_d + '.tmp'
|
||
|
call(['rm', '-rf', tmp_d + '.cp'])
|
||
|
call(['cp', '-rvu', old_d, tmp_d + '.cp'])
|
||
|
check_call(['mv', tmp_d + '.cp', tmp_d])
|
||
|
set_revision(new_v, tmp_d)
|
||
|
call('pwd && sleep 5 && echo ' + make_cmd, cwd=tmp_d, shell=True)
|
||
|
result = call(make_cmd, cwd=tmp_d, shell=True)
|
||
|
if result == 0:
|
||
|
print 'Make successful'
|
||
|
check_call(['mv', tmp_d, new_d])
|
||
|
return result
|
||
|
|
||
|
|
||
|
def change_after(cmd, v):
|
||
|
result = run_cmd(cmd, v)
|
||
|
ca = result_after(result)
|
||
|
print >> outfile, 'BISECT_change_after', v, ca
|
||
|
print 'BISECT_change_after', v, ca
|
||
|
return ca
|
||
|
|
||
|
|
||
|
def change_before(cmd, v):
|
||
|
result = run_cmd(cmd, v)
|
||
|
cb = result_before(result)
|
||
|
print >> outfile, 'BISECT_change_before', v, cb
|
||
|
print 'BISECT_change_before', v, cb
|
||
|
return cb
|
||
|
|
||
|
|
||
|
def result_after(i):
|
||
|
if reverse_search:
|
||
|
return result_bad(i)
|
||
|
else:
|
||
|
return result_good(i)
|
||
|
|
||
|
|
||
|
def result_before(i):
|
||
|
if reverse_search:
|
||
|
return result_good(i)
|
||
|
else:
|
||
|
return result_bad(i)
|
||
|
|
||
|
|
||
|
def result_good(i):
|
||
|
return i == 0
|
||
|
|
||
|
|
||
|
def result_bad(i):
|
||
|
return not result_ugly(i) and not result_good(i)
|
||
|
|
||
|
|
||
|
def result_ugly(i):
|
||
|
return i == 125 # Like git, we treat 125 as "We cannot test this version"
|
||
|
|
||
|
|
||
|
def run_cmd(cmd, v):
|
||
|
#result = call('pwd ; echo SS ' + cmd, shell=True, cwd=ver2dir(v))
|
||
|
print "CMD", cmd
|
||
|
print "V2D", ver2dir(v)
|
||
|
os
|
||
|
#result = subprocess.call(cmd, shell=True, cwd=ver2dir(v))
|
||
|
result = call(cmd, cwd=ver2dir(v))
|
||
|
clean_up()
|
||
|
print cmd, result
|
||
|
return result
|
||
|
|
||
|
|
||
|
def do_bisect(cmd, vers, build):
|
||
|
lo = 0
|
||
|
hi = len(vers) - 1
|
||
|
m = (lo + hi) / 2
|
||
|
|
||
|
print lo, hi, m
|
||
|
print vers[lo], vers[hi], vers[m]
|
||
|
print vers
|
||
|
|
||
|
print >> outfile, 'VERS', final_vers
|
||
|
|
||
|
while len(vers) > 2:
|
||
|
print 'i', lo, hi, m, cmd
|
||
|
print 'v', vers[lo], vers[hi], vers[m], cmd
|
||
|
print vers
|
||
|
|
||
|
print '#ugly = Nonese'
|
||
|
|
||
|
if build or must_make:
|
||
|
ugly = False
|
||
|
result = make_ver(vers[m], vers[lo], vers[hi])
|
||
|
print 'AMKE RESULT', result
|
||
|
if not must_make:
|
||
|
if result > 0 and not must_make:
|
||
|
ugly = True # Not good, or bad, just ugly.
|
||
|
else:
|
||
|
result = run_cmd(cmd, vers[m])
|
||
|
if not ugly:
|
||
|
if result > 127:
|
||
|
os._exit(1)
|
||
|
ugly = result_ugly(result)
|
||
|
if ugly:
|
||
|
print vers[m] + ' is UGLY'
|
||
|
del vers[m]
|
||
|
hi = len(vers) - 1
|
||
|
m = randrange(0, len(vers))
|
||
|
else:
|
||
|
if result_after(result):
|
||
|
print vers[m] + ' is AFTER'
|
||
|
del vers[lo:m]
|
||
|
else:
|
||
|
print vers[m] + ' is BEFORE'
|
||
|
del vers[m + 1:hi + 1]
|
||
|
hi = len(vers) - 1
|
||
|
m = (lo + hi) / 2
|
||
|
|
||
|
print 'VERS REMAINING:', vers
|
||
|
|
||
|
return vers
|
||
|
|
||
|
|
||
|
def check_bisect(cmd, vers):
|
||
|
lo = 0
|
||
|
hi = len(vers) - 1
|
||
|
l = vers[lo]
|
||
|
h = vers[hi]
|
||
|
if make_ver(l):
|
||
|
return False
|
||
|
if make_ver(h):
|
||
|
return False
|
||
|
if change_before(cmd, l):
|
||
|
print 'Cannot bisect, change before ' + l\
|
||
|
+ ' or regression test invalid'
|
||
|
return False
|
||
|
if change_after(cmd, h):
|
||
|
print 'Cannot bisect, change after ' + h\
|
||
|
+ ' or regression test invalid'
|
||
|
return False
|
||
|
return True
|
||
|
|
||
|
|
||
|
def do_check_bisect(cmd, vers, build):
|
||
|
print vers
|
||
|
if check_bisect(cmd, vers):
|
||
|
return do_bisect(cmd, vers, build)
|
||
|
else:
|
||
|
return
|
||
|
|
||
|
|
||
|
def open_and_readlines(fname):
|
||
|
f = open(fname, 'r')
|
||
|
lines = f.readlines()
|
||
|
for i in range(0, len(lines)):
|
||
|
lines[i] = lines[i].rstrip('\n')
|
||
|
return lines
|
||
|
|
||
|
|
||
|
def get_versions_between(l, h):
|
||
|
vers = [f for f in open_and_readlines('all_versions')
|
||
|
if version_in_range(f, l, h)]
|
||
|
vers.sort(cmp_version)
|
||
|
return vers
|
||
|
|
||
|
|
||
|
def get_cached_versions_between(l, h):
|
||
|
vers = [f for f in get_cached_versions() if version_in_range(f, l, h)]
|
||
|
vers.sort(cmp_version)
|
||
|
print 'BTWN', l, h, vers
|
||
|
return vers
|
||
|
|
||
|
|
||
|
def two_level_bisect(cmd, LO, HI):
|
||
|
if make_ver(LO):
|
||
|
return False
|
||
|
if make_ver(HI):
|
||
|
return False
|
||
|
vers = get_cached_versions_between(LO, HI)
|
||
|
print 'CACHED_VERSIONS', vers
|
||
|
vers = do_check_bisect(cmd, vers, False)
|
||
|
print 'Closest Cached Versions', vers
|
||
|
if vers is None:
|
||
|
return
|
||
|
if len(vers) != 2:
|
||
|
return
|
||
|
vers = get_versions_between(vers[0], vers[1])
|
||
|
print 'BETWEEN VERSIONS', vers
|
||
|
vers = do_check_bisect(cmd, vers, True)
|
||
|
|
||
|
|
||
|
def multisect(cmd, vers):
|
||
|
i = 1
|
||
|
while i < len(vers):
|
||
|
print >> outfile, 'MULTISECT', vers[i]
|
||
|
print 'MULTISECT', vers[i]
|
||
|
if not ( make_ver(vers[i], vers[i-1])==0 and change_after(cmd, vers[i]) ) :
|
||
|
i = i + 1
|
||
|
else:
|
||
|
return two_level_bisect(cmd, vers[i], vers[0])
|
||
|
|
||
|
|
||
|
print 'BISECT_BEGIN'
|
||
|
print >> outfile, 'BISECT_BEGIN'
|
||
|
outfile.flush()
|
||
|
#final_vers = multisect('$TEST_COMMAND', ['30614', '27418', '23000'])
|
||
|
cmd = os.sys.argv
|
||
|
del cmd[0]
|
||
|
|
||
|
VERS = os.environ.get('MULTISECT_VERS')
|
||
|
if VERS is None:
|
||
|
VERS = ['30614', '27418', '23000']
|
||
|
else:
|
||
|
VERS = VERS.split()
|
||
|
|
||
|
final_vers = multisect(cmd, VERS)
|
||
|
#final_vers = two_level_bisect('true', "21107","23000")
|
||
|
#final_vers = do_bisect('true', get_versions_between("21107","23000"),True)
|
||
|
outfile.flush()
|
||
|
print
|
||
|
print >> outfile, 'BISECT_FINAL', final_vers
|
||
|
print 'BISECT_FINAL', final_vers
|
||
|
os.system('echo BISECT_BEGIN >> /tmp/adsfadsf.log')
|
||
|
os.system('echo BISECT_FINAL >> /tmp/adsfadsf.log')
|
||
|
|
||
|
clean_up()
|
||
|
os._exit(0)
|