#!@PYTHON@
from lilypython import *
import getopt
import pipes


mp_version = '2'

class Options:
    def __init__(self):
	self.to_version = lilydirs.version_tuple()
	self.from_version = prev_version(self.to_version)

options = Options()
	

def help():
    sys.stdout.write(
	'Generate a patch to go to this version.\n'
	'  --from=FROM, -f FROM    old is FROM\n'
	'  --to=TO, -t TO          to version TO\n'  
	
	)
    sys.exit();



def untar(fn):
    sys.stderr.write('untarring ' + fn)
    os.system ('tar xzf ' + fn)
    sys.stderr.write('\n')
    sys.stderr.flush()


header = 'Generated by make-patch, old = %s, new = %s\n\
\n\
usage \n\
\n\
	cd lilypond-source-dir; patch -E -p0 < %s\n\
\n\
Patches do not contain automatically generated files, \n\
i.e. you should rerun configure\n\n'

import fnmatch
import os

_debug = 0

_prune = ['(*)']


def my_find(patterns, dir = os.curdir):
        list = []
        names = os.listdir(dir)
        names.sort()
        for name in names:
                if name in (os.curdir, os.pardir):
                        continue
                fullname = os.path.join(dir, name)
		for pat in patterns:
		    if fnmatch.fnmatch(name, pat):
                        list.append(fullname)
                if os.path.isdir(fullname) and not os.path.islink(fullname):
                        for p in _prune:
                                if fnmatch.fnmatch(name, p):
                                        if _debug: print "skip", `fullname`
                                        break
                        else:
                                if _debug: print "descend into", `fullname`
				found = my_find(patterns, fullname)
				if found:
				    list = list + found
        return list

def multiple_find(pats, dirnames):
    from find import find
    l = []
    for d in dirnames:
	l = l + my_find(pats,  d)
    return l

pats = ['*.lsm', 'configure', '*.text', 'lilypond.spec']
def remove_automatic(dirnames):
    files = []
    files = files + multiple_find(pats, dirnames)

    for f in files:
	os.remove(f)

def makepatch(fv, tv, patfile_nm):
    import tempfile
    prev_cwd = os.getcwd();
    os.chdir ('/tmp')
    untar(released_tarball(fv))
    untar(released_tarball(tv))
    remove_automatic([dirname(fv), dirname(tv)])

    os.chdir(dirname(tv))
    
    if not patfile_nm:
	patfile_nm = '../patch-%s' % version_tuple_to_str(tv)

    f = open(patfile_nm, 'w')
    f.write(header %\
	    (version_tuple_to_str(fv), version_tuple_to_str(tv), \
	     os.path.basename(patfile_nm)))
    f.close()
	    
    sys.stderr.write('diffing to %s... ' % patfile_nm)
    os.system('diff -urN ../%s . >> %s' % (dirname(fv), patfile_nm))
    #os.system('gzip -9f %s' % patfile_nm)
    os.chdir('/tmp')

    sys.stderr.write('cleaning ... ')
    os.system('rm -fr %s %s' % (dirname(tv), dirname(fv)))
    sys.stderr.write('\n')
    os.chdir(prev_cwd)
    
def main():
    sys.stderr.write('This is make-patch version %s\n' % mp_version)
    (cl_options, files) = getopt.getopt(sys.argv[1:], 
					'hf:o:t:', ['output=', 'help', 'from=', 'to='])
    outfn = ''
    for opt in cl_options:
	o = opt[0]
	a = opt[1]
	if o == '--from' or o == '-f':
	     options.from_version = version_str_to_tuple(a)
	elif o == '--to' or o == '-t':
	    options.to_version = version_str_to_tuple(a)
	elif o== '--help' or o == '-h':
	    help()
	elif o == '--output' or o == '-o':
	    outfn = os.path.join(os.getcwd(), a)
	else:
	    raise getopt.error

    if not outfn:
	pn = 'patch-%s' % version_tuple_to_str(options.to_version)
	outfn =  os.path.join(os.getcwd(), pn)

    makepatch(options.from_version, options.to_version, outfn)

if __name__ == '__main__':
    main()
