--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dbrtools/dbr/dbrpatch.py Wed Mar 03 17:22:06 2010 +0000
@@ -0,0 +1,331 @@
+# Copyright (c) 2009 Symbian Foundation Ltd
+# This component and the accompanying materials are made available
+# under the terms of the License "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Symbian Foundation Ltd - initial contribution.
+#
+# Contributors:
+# mattd <mattd@symbian.org>
+#
+# Description:
+# DBRpatch - module for handling patched baselines
+
+import re
+import os.path #used for 'listpatches'
+import string
+import glob
+import dbrutils
+import dbrbaseline
+
+def newcompare(db1, db2):
+ db1files = set(db1.keys())
+ db2files = set(db2.keys())
+
+ removed = db1files - db2files
+ added = db2files - db1files
+ common = db1files & db2files
+
+ touched = set()
+ for file in common:
+ if(db1[file]['time'] != db2[file]['time']):
+ touched.add(file)
+
+ sizechanged = set()
+ for file in common:
+ if(db1[file]['size'] != db2[file]['size']):
+ sizechanged.add(file)
+
+ changed = set()
+
+ genmd5 = 1 #I probably want to try to generate... add this as a third arg???
+
+ if(len(touched)):
+ if(genmd5):
+ md5testset = set()
+ for file in touched:
+ if((db1[file]['md5'] != 'xxx' ) and (db2[file]['md5'] == 'xxx')): #no point geenrating an MD5 if we've nothing to compare it to...
+# print 'testing %s' % file
+ md5testset.add(file)
+ md5s = dbrutils.generateMD5s(md5testset)
+ for file in md5testset:
+ db2[file]['md5'] = md5s[file]['md5']
+ for file in touched:
+ if(db1[file]['md5'] != db2[file]['md5']):
+ changed.add(file)
+ touched = touched - changed
+
+ untestable1 = set()
+ untestable2 = set()
+ for file in common:
+ if(db1[file]['md5'] == "xxx"):
+ untestable1.add(file)
+ if(db2[file]['md5'] == 'xxx'):
+ untestable2.add(file)
+
+ untestable = untestable1 & untestable2
+ changed = changed - untestable
+
+ #remove the ones we know are changed
+ touched = touched - changed
+ touched = touched - untestable
+
+ results = dict()
+ results['added'] = dict()
+ results['removed'] = dict()
+ results['touched'] = dict()
+ results['changed'] = dict()
+ results['untestable'] = dict()
+
+ for file in added:
+ results['added'][file] = db2[file]
+ for file in removed:
+ results['removed'][file] = 0
+ for file in touched:
+ results['touched'][file] = db2[file]
+ for file in changed:
+ results['changed'][file] = db2[file]
+ for file in untestable:
+ results['untestable'][file] = 0
+ return results
+
+def printresults(results):
+ for file in sorted (results['added']):
+ print 'added:', file
+ for file in sorted (results['removed']):
+ print 'removed:', file
+ for file in sorted (results['touched']):
+ print 'touched:', file
+ for file in sorted (results['changed']):
+ print 'changed:', file
+ for file in sorted (results['untestable']):
+ print 'untestable:', file
+ if(len(results['added']) + len(results['removed']) + len(results['changed']) + len(results['untestable']) == 0):
+ print '\nStatus:\tclean'
+ else:
+ print '\nStatus:\tdirty'
+
+def newupdatedb(baseline,env):
+ results = newcompare(baseline, env)
+ printresults(results)
+ for file in results['touched']:
+ baseline[file]['time'] = env[file]['time']
+ return results
+
+def newcreatepatch(name, db1, db2):
+ results = newcompare(db1, db2)
+ printresults(results)
+ for file in results['touched']:
+ db1[file]['time'] = db2[file]['time']
+
+ patch = dict();
+ patch['name'] = name
+ patch['time'] = 'now!!!'
+ patch['removed'] = results['removed']
+ added = results['added'].keys()
+ md5sAdded = dbrutils.generateMD5s(added)
+ for file in added:
+ results['added'][file]['md5'] = md5sAdded[file]['md5']
+ patch['added'] = results['added']
+ print "Need to add in the untestable stuff here also!!!"
+ patch['changed'] = results['changed']
+ patchname = "%spatch_%s" %(dbrutils.patchpath(), name)
+
+ createpatchzip(patch, patchname)
+
+ #update the ownership
+ for file in patch['changed']:
+ db1[file]['name'] = name
+
+ return db1
+
+def newcomparepatcheddbs(drive1, drive2):
+ envdbroot = dbrutils.defaultdb()
+ print "MattD: should move this function to a better location..."
+ print 'Comparing %s with %s' % (drive2,drive1)
+ print 'Loading %s' % drive1
+ baseline1 = dbrbaseline.readdb('%s%s' %(drive1,envdbroot))
+ patches1 = loadpatches('%s/%s' %(drive1,dbrutils.patchpath()))
+ db1 = createpatchedbaseline(baseline1,patches1)
+
+ print 'Loading %s' % drive2
+ baseline2 = dbrbaseline.readdb('%s%s' %(drive2,envdbroot))
+ patches2 = loadpatches('%s/%s' %(drive2,dbrutils.patchpath()))
+ db2 = createpatchedbaseline(baseline2,patches2)
+
+ results = newcompare(db1, db2)
+ printresults(results)
+
+
+
+def createpatchzip(patch, patchname):
+ patchtext = '%s.txt' % patchname
+ patchtext = os.path.join(dbrutils.patchpath(),patchtext)
+
+ writepatch(patch, patchtext)
+ files = set()
+ files.update(patch['added'])
+ files.update(patch['changed'])
+ files.add(re.sub('\\\\','',patchtext)) #remove leading slash - Nasty - need to fix the whole EPOCROOT thing.
+
+ zipname = '%s.zip' % patchname
+ dbrutils.createzip(files, zipname)
+
+
+def updatebaseline(baseline, db):
+ for file in (db.keys()):
+ origin = db[file]['name']
+ if(origin == 'baseline'):
+ if(baseline[file]['time'] != db[file]['time']):
+ baseline[file]['time'] = db[file]['time']
+ print 'Updating timestamp for %s in baseline' % file
+ return baseline
+
+def updatepatches(patches, db):
+ for file in (db.keys()):
+ origin = db[file]['name']
+ for patch in patches.keys():
+ if(patches[patch]['name'] == origin):
+ mod=0
+ if(file in patches[patch]['added']):
+ mod = 'added'
+ if(file in patches[patch]['changed']):
+ mod = 'changed'
+ if(mod):
+ if (patches[patch][mod][file]['time'] != db[file]['time']):
+ patches[patch][mod][file]['time'] = db[file]['time']
+ print 'Updating timestamp in %s for %s' %(patches[patch]['name'],file)
+ return patches
+
+
+def createpatchedbaseline(baseline,patches):
+ files = dict()
+ files = addtodb(files,baseline,'baseline')
+ for patch in sorted(patches.keys()):
+# print 'adding patch: %s' % patch
+ files = addtodb(files,patches[patch]['added'],patches[patch]['name'])
+ files = addtodb(files,patches[patch]['changed'],patches[patch]['name'])
+ files = removefromdb(files,patches[patch]['removed'],patches[patch]['name'])
+ return files
+
+def removefromdb(db,removed,name):
+ for file in removed:
+ if(file in db):
+# print '%s removing %s' %(name,file)
+ del db[file]
+ return db
+
+def addtodb(db,new,name):
+ for file in new:
+ if(file not in db):
+ db[file] = dict()
+# else:
+# print '%s overriding %s' % (name,file)
+ db[file]['time'] = new[file]['time']
+ db[file]['md5'] = new[file]['md5']
+ db[file]['size'] = new[file]['size']
+ db[file]['name'] = name
+ return db
+
+def listpatches():
+ path = dbrutils.patchpath()
+ patchfiles = glob.glob('%spatch*.txt' % path)
+ print 'Installed patches'
+ for file in patchfiles:
+ print '\t%s' % re.sub('.txt','',os.path.basename(file))
+
+def removepatch(patch):
+ path = dbrutils.patchpath()
+ file = '%s%s%s' %(path,patch,'.txt')
+ files = set()
+ files.add(file)
+ dbrutils.deletefiles(files)
+
+
+def loadpatches(path):
+ patches = dict()
+ patchfiles = glob.glob('%spatch*.txt' % path)
+
+ for file in patchfiles:
+ print 'Loading patch: %s' % re.sub('.txt','',os.path.basename(file))
+# print 'Reading: %s\n' % file
+# patchname = re.match('\S+patch(\S+)\.txt',file)
+# print 'patchname %s' % patchname.group(1);
+ patch = readpatch(file)
+# patches[patchname.group(1)] = patch
+# print 'Read %s from %s' % (patch['name'],file)
+ patches[file] = patch
+ return patches
+
+
+def savepatches(patches):
+ for patch in sorted(patches.keys()):
+ # print 'writing %s to %s' % (patches[patch]['name'],patch)
+ writepatch(patches[patch], patch)
+
+
+def writepatch(patch, filename):
+ file = open(filename,'w')
+# print 'saving patch to %s' %filename
+ file.write("name=%s\n" % patch['name']);
+ file.write("time=%s\n" % patch['time']);
+
+ removed = patch['removed']
+ for filename in sorted(removed):
+ str = "removed=%s\n" % filename
+ file.write(str)
+
+ added = patch['added']
+ for filename in sorted(added):
+ if (len(added[filename]) < 3):
+ added[filename].append('')
+ str = "added=%s:%s:%s:%s\n" %( added[filename]['time'],added[filename]['size'],added[filename]['md5'], filename)
+ file.write(str)
+
+ changed = patch['changed']
+ for filename in sorted(changed):
+ if (len(changed[filename]) < 3):
+ changed[filename].append('')
+ str = "changed=%s:%s:%s:%s\n" %( changed[filename]['time'],changed[filename]['size'],changed[filename]['md5'], filename)
+ file.write(str)
+ file.close()
+
+
+def readpatch(filename):
+ file = open(filename,'r')
+ #name=blah
+ #time=blah
+ #removed=file
+ #added=time:size:md5:file
+ #changed=time:size:md5:file
+ patch = dict()
+ removed = set()
+ added = dict()
+ changed = dict()
+ for line in file:
+ results = re.split('=|\n',line)
+ type = results[0]
+ if( type == 'name'):
+ patch['name'] = results[1]
+ elif( type == 'time'):
+ patch['time'] = results[1]
+ elif( type == 'removed'):
+ removed.add(results[1])
+ elif(( type == 'added') or (type == 'changed')):
+ results2 = re.split(':|\n',results[1])
+ entry = dict()
+ entry['time'] = results2[0]
+ entry['size'] = results2[1]
+ entry['md5'] = results2[2]
+ if(type == 'added'):
+ added[results2[3]] = entry
+ else:
+ changed[results2[3]] = entry
+ file.close()
+ patch['removed'] = removed
+ patch['added'] = added
+ patch['changed'] = changed
+ return patch
+