|
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 |