dbrtools/dbr/dbrenv.py
changeset 203 e274d29c8bc9
child 208 01c2b1268053
equal deleted inserted replaced
202:f6ae410bd493 203:e274d29c8bc9
       
     1 # Copyright (c) 2010 Symbian Foundation Ltd
       
     2 # This component and the accompanying materials are made available
       
     3 # under the terms of the License "Eclipse Public License v1.0"
       
     4 # which accompanies this distribution, and is available
       
     5 # at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     6 #
       
     7 # Initial Contributors:
       
     8 # Symbian Foundation Ltd - initial contribution.
       
     9 #
       
    10 # Contributors:
       
    11 # mattd <mattd@symbian.org>
       
    12 #
       
    13 # Description:
       
    14 # DBREnv - OO rewrite of the Environments  
       
    15 
       
    16 #I'm using the existing stuff as helpers until things get relocated...
       
    17 import os.path
       
    18 import glob
       
    19 
       
    20 import dbrutils
       
    21 import dbrbaseline
       
    22 import dbrpatch
       
    23 
       
    24 
       
    25 def CreateDB(location): #virtual constructor
       
    26   print location
       
    27 #  print dbrutils.patch_path_internal()
       
    28   if(os.path.exists(os.path.join(location,dbrutils.defaultdb()))):
       
    29 #    print 'loading baseline environment'
       
    30 #    return DBRBaselineEnv(location)
       
    31     print 'loading patched baseline environment'
       
    32     return DBRPatchedBaselineEnv(location)
       
    33   if(os.path.exists(os.path.join(location,'build_md5.zip'))):
       
    34     print 'loading zipped environment'
       
    35     return DBRZippedEnv(location)
       
    36   if(os.path.exists(os.path.join(location,dbrutils.patch_path_internal()))): #should do something more fun with creating a basleine if we have MD5s
       
    37     print 'loading new env...warning: this is only here for compatibility'
       
    38     return DBRNewLocalEnv(location)
       
    39   if(os.path.exists(os.path.join(location,'epoc32'))): 
       
    40     print 'loading localenv'
       
    41     return DBRLocalEnv(location)
       
    42 
       
    43   return DBREnv(location)
       
    44 
       
    45 
       
    46 
       
    47 class DBREnv:
       
    48   db = dict()
       
    49   location = ''
       
    50   name = ''
       
    51   def __init__(self, location):
       
    52     self.location = location
       
    53 
       
    54   def compare(self, other):
       
    55     db1files = set(self.db.keys())
       
    56     db2files = set(other.db.keys())
       
    57 
       
    58     removed = db1files - db2files
       
    59     added = db2files - db1files
       
    60     common = db1files & db2files
       
    61 
       
    62     touched = set()
       
    63     for file in common:
       
    64       if(int(self.db[file]['time']) != int(other.db[file]['time'])):
       
    65         touched.add(file)
       
    66 
       
    67     sizechanged = set()
       
    68     for file in common:
       
    69       if(int(self.db[file]['size']) != int(other.db[file]['size'])):
       
    70         sizechanged.add(file)
       
    71 #can be funny with some zip files...suggest we don't use sizechanged...        
       
    72 #    changed = sizechanged 
       
    73     changed = set()    
       
    74     touched = touched - changed
       
    75     unknown = set()
       
    76     for file in touched:
       
    77       if((self.db[file]['md5'] == "xxx") or (other.db[file]['md5'] == "xxx")):
       
    78         unknown.add(file)
       
    79 #        if((self.db[file]['md5'] == "xxx")):
       
    80 #          print 'unknown left: %s' % file
       
    81 #        else:
       
    82 #          print 'unknown right: %s' % file
       
    83       else:
       
    84         if(self.db[file]['md5'] != other.db[file]['md5']):
       
    85 #          print '%s %s %s' % (file, self.db[file]['md5'], other.db[file]['md5'] )
       
    86           changed.add(file)
       
    87     touched = touched - unknown     
       
    88     touched = touched - changed     
       
    89           
       
    90     results = DBRCompResults(added, removed, touched, changed, unknown)   
       
    91     return results
       
    92     
       
    93   def verify(self, files):
       
    94     print 'this is a pure virtual...'
       
    95   def save(self):
       
    96     print 'this is a pure virtual...'
       
    97 
       
    98   def remove(self, files):
       
    99     for file in files:
       
   100       if(file in self.db):
       
   101         del self.db[file]
       
   102       else:
       
   103         print 'warning: del: %s isnt defined' % file  
       
   104 
       
   105   def add(self, other, files):
       
   106     for file in files:
       
   107       if(file in self.db):
       
   108         print 'warning: add: %s already defined' % file
       
   109       else:    
       
   110         if(other.db[file]['md5'] == 'xxx'): #don't update a null md5
       
   111           print 'warning: MD5: %s isnt defined' % file  
       
   112         else:
       
   113           self.db[file] = other.db[file]
       
   114               
       
   115   def update(self, other, files):
       
   116     for file in files:
       
   117       if(other.db[file]['md5'] != 'xxx'): #don't update a null md5 
       
   118         self.db[file]['md5'] = other.db[file]['md5']                           
       
   119       else:
       
   120         print 'warning: MD5: %s isnt defined' % file  
       
   121 
       
   122       self.db[file]['time'] = other.db[file]['time']              
       
   123       self.db[file]['size'] = other.db[file]['size']
       
   124 
       
   125 
       
   126 #Database plus local filesystem access
       
   127 class DBRLocalEnv (DBREnv):
       
   128   def __init__(self, location):
       
   129     DBREnv.__init__(self, location)
       
   130     #load up local files...        
       
   131     self.db = dbrutils.scanenv()
       
   132 
       
   133   def verify(self, files):
       
   134     #should assert that the files are in the local DB.
       
   135     localfiles = set(self.db.keys())
       
   136     if(localfiles.issuperset(files)):
       
   137       md5s = dbrutils.generateMD5s(files)
       
   138       for file in files:
       
   139         self.db[file]['md5'] = md5s[file]['md5']
       
   140 
       
   141 class DBRNewLocalEnv (DBRLocalEnv):
       
   142   def __init__(self, location):
       
   143     DBRLocalEnv.__init__(self, location)
       
   144     #load up local files...            
       
   145     hashes = glob.glob(os.path.join(dbrutils.patchpath(),'*.md5'))
       
   146     for file in hashes:
       
   147       print 'Reading: %s\n' % file
       
   148       dbrutils.gethashes(self.db, file, False)
       
   149 
       
   150   def save(self):
       
   151     filename = os.path.join(self.location,dbrutils.defaultdb())
       
   152     print 'Saving %s' % filename 
       
   153     dbrbaseline.writedb(self.db,filename)
       
   154 
       
   155         
       
   156 
       
   157     
       
   158 #zipped files, contains MD5s.   
       
   159 class DBRZippedEnv (DBREnv):
       
   160   def __init__(self, location):
       
   161     DBREnv.__init__(self, location)
       
   162     #load up zip MD5 and stuff
       
   163     self.db = dbrutils.getzippedDB(self.location)        
       
   164       
       
   165 #Database, but no filesystem access
       
   166 class DBRBaselineEnv (DBREnv):
       
   167   def __init__(self, location):
       
   168     DBREnv.__init__(self, location)
       
   169     #load up database...        
       
   170     filename = os.path.join(self.location,dbrutils.defaultdb())
       
   171     print 'Loading %s' % filename 
       
   172     self.db = dbrbaseline.readdb(filename)
       
   173 
       
   174   def save(self):
       
   175     filename = os.path.join(self.location,dbrutils.defaultdb())
       
   176     print 'Saving %s' % filename 
       
   177     dbrbaseline.writedb(self.db,filename)
       
   178 
       
   179 class DBRPatchedBaselineEnv (DBRBaselineEnv):
       
   180   patches = []
       
   181   baseline = []
       
   182   def __init__(self, location):
       
   183     DBRBaselineEnv.__init__(self, location)
       
   184     #load up patches...        
       
   185     if(len(self.db) > 0):
       
   186       self.baseline = self.db      
       
   187       self.patches = dbrpatch.loadpatches(os.path.join(self.location,dbrutils.patchpath()))
       
   188       self.db = dbrpatch.createpatchedbaseline(self.baseline,self.patches)
       
   189 
       
   190   def save(self):
       
   191       self.baseline = dbrpatch.updatebaseline(self.baseline, self.db)
       
   192       self.patches = dbrpatch.updatepatches(self.patches, self.db)
       
   193       dbrpatch.savepatches(self.patches)
       
   194       self.db = self.baseline
       
   195       DBRBaselineEnv.save(self)
       
   196       
       
   197           
       
   198 class CBREnv (DBREnv): # placeholder for handling CBR components...
       
   199   def __init__(self, location):
       
   200     DBREnv.__init__(self, location)
       
   201 
       
   202 
       
   203 #comparison results...
       
   204 class DBRCompResults:
       
   205   added = set()
       
   206   removed = set()
       
   207   touched = set()
       
   208   changed = set()
       
   209   unknown = set()
       
   210   def __init__(self, added, removed, touched, changed, unknown):
       
   211     #Should probably assert that these are disjoint.
       
   212     self.added = added
       
   213     self.removed = removed
       
   214     self.touched = touched
       
   215     self.changed = changed
       
   216     self.unknown = unknown
       
   217      
       
   218   def printdetail(self):
       
   219     for file in sorted(self.added):
       
   220       print 'added:', file
       
   221     for file in sorted(self.removed):
       
   222       print 'removed:', file
       
   223     for file in sorted(self.changed):
       
   224       print 'changed:', file
       
   225     for file in sorted(self.unknown):
       
   226       print 'unknown:', file
       
   227     
       
   228   def printsummary(self):
       
   229     if(len(self.added | self.removed | self.changed | self.unknown)):
       
   230       print 'status: dirty'
       
   231     else:
       
   232       print 'status: clean' 
       
   233