00001 from __future__ import with_statement
00002
00003 import sys
00004 import gme
00005 import gc
00006 import os
00007
00008
00009 def compare (file1, file2):
00010 with gme.Project.open(file1) as project1:
00011 with gme.Project.open(file2) as project2:
00012 return compare2(project1, project2)
00013
00014
00015 def iter_parents(fco):
00016 while fco:
00017 yield fco
00018 if fco.ObjType == 6:
00019 fco = fco.ParentFolder
00020 else:
00021 if fco.ParentFolder:
00022 fco = fco.ParentFolder
00023 else:
00024 fco = fco.ParentModel
00025
00026 def fco_path(fco):
00027 parents = list(iter_parents(fco))
00028 parents.reverse()
00029 return "/".join(map(lambda x: x.Name, parents))
00030
00031 def _get_Meta(object):
00032 if object.ObjType == 6:
00033 return object.MetaFolder
00034 return object.Meta
00035
00036 def _get_children(object):
00037 if object.ObjType == 6:
00038 return list(object.ChildFolders) + list(object.ChildFCOs)
00039 return list(object.ChildFCOs)
00040
00041 def compare2(project1, project2):
00042 toProcess1=[]
00043 toProcess2=[]
00044
00045 current1=None
00046 current2=None
00047
00048 project1Root=project1.project.RootFolder
00049 toProcess1.append(project1Root)
00050 project2Root=project2.project.RootFolder
00051 toProcess2.append(project2Root)
00052
00053 current1=toProcess1.pop()
00054
00055 while current1!=None:
00056 current1 = current1
00057 if len(toProcess2)==0:
00058 print "Print nothing to process for " + current2.Name
00059 return False
00060
00061 for index in range(len(toProcess2)):
00062 current2 = toProcess2[index]
00063 namesEqual = current1.Name == current2.Name
00064 kindsEqual = _get_Meta(current1).Name == _get_Meta(current2).Name
00065 connectionEndpointsEqual = True
00066 if current1.ObjType == 4 and current2.ObjType == 4:
00067 def mapConnpoints(conn):
00068 ret = map(lambda point: (point.ConnRole, [fco_path(point.Target), map(fco_path, point.References)]), conn.ConnPoints)
00069 return dict(ret)
00070 connectionEndpointsEqual = mapConnpoints(current1) == mapConnpoints(current2)
00071
00072
00073
00074 if namesEqual and kindsEqual and connectionEndpointsEqual:
00075 toProcess2.remove(current2)
00076 break
00077 else:
00078 print "Found nothing corresponding to " + fco_path(current1) +" of kind \"" + current1.MetaBase.Name +"\""
00079 return False
00080
00081 if current1.AbsPath!=current2.AbsPath and current1.Name !=current2.Name :
00082
00083 print current1.AbsPath," != ",current2.AbsPath
00084 return False
00085
00086 if current1.ObjType != current2.ObjType:
00087 print "'%s' has differing object types" % current1.AbsPath
00088 return False
00089
00090 if _get_Meta(current1).Name != _get_Meta(current2).Name:
00091 print "'%s' has differing kinds" % current1.AbsPath
00092 return False
00093
00094
00095 if current1.ObjType != 6:
00096 if not compareAttrib(current1, current2):
00097 return False
00098
00099
00100 if current1.ObjType == current2.ObjType and current2.ObjType ==2 :
00101 if compareAssoc(current1.PartOfConns,current2.PartOfConns):
00102 try:
00103 current1=toProcess1.pop(0)
00104 except IndexError:
00105 if len(toProcess2) == 0:
00106 return True
00107 else:
00108 print "Atoms:: Wrong"
00109 return False
00110 current2=None
00111 continue
00112 else:
00113 return False
00114
00115
00116
00117 if current1.ObjType == 3 and current2.ObjType == 3 :
00118 if compareReference(current1,current2) and compareAssoc(current1.PartOfConns,current2.PartOfConns):
00119 try:
00120 current1=toProcess1.pop(0)
00121 except IndexError:
00122 if len(toProcess2) == 0:
00123 return True
00124 else:
00125 print "Reference has something"
00126 return False
00127 current2=None
00128 continue
00129 else:
00130 print "compareReference FAILED for "+current1.Name+" "+current2.Name
00131 return False
00132
00133
00134
00135 if current1.ObjType == 5 and current2.ObjType == 5:
00136 if compareSet(current1,current2)and compareAssoc(current1.PartOfConns,current2.PartOfConns):
00137 try:
00138 current1=toProcess1.pop(0)
00139 except IndexError:
00140 if len(toProcess2) == 0:
00141 return True
00142 else:
00143 print "Set 2 has something"
00144 return False
00145 current2=None
00146 continue
00147 else:
00148 print "compareSet FAILED for "+current1.Name+" "+current2.Name
00149 return False
00150
00151 if current1.ObjType == 1 and current2.ObjType == 1:
00152 if not compareAssoc(current1.PartOfConns,current2.PartOfConns):
00153 return False
00154
00155
00156 if current1.ObjType == 4 and current2.ObjType == 4:
00157 try:
00158 current1=toProcess1.pop(0)
00159 except IndexError:
00160 if len(toProcess2) == 0:
00161 return True
00162 else:
00163 print "CONNECTION:: Proc 2 has something"
00164 return False
00165 current2=None
00166 continue
00167
00168
00169 childrenSet1 = _get_children(current1)
00170 childrenSet2 = _get_children(current2)
00171 toProcess1.extend(childrenSet1)
00172 toProcess2.extend(childrenSet2)
00173
00174 if len(childrenSet1)!= len(childrenSet2):
00175 print "LENGTH of childrenSet FAILED for " + fco_path(current1)
00176 print "\t" + "File 1: " + ", ".join([child.Name for child in _get_children(current1)])
00177 print "\t" + "File 2: " + ", ".join([child.Name for child in _get_children(current2)])
00178 return False
00179
00180 if current1.ObjType == 6 and current2.ObjType == 6:
00181 toProcess1.extend(current1.ChildFolders)
00182 toProcess2.extend(current2.ChildFolders)
00183
00184 try:
00185 current1=toProcess1.pop(0)
00186 except IndexError:
00187 if len(toProcess2) == 0:
00188 return True
00189 else:
00190 print "END Proc 2 has something"
00191 return False
00192 continue
00193
00194 def compareSet(*setFCOs):
00195 array=[]
00196 for index in range(len(setFCOs)):
00197 array.append(dict())
00198 array[index][setFCOs[index].Name]=setFCOs[index].AbsPath
00199
00200 for index in range(len(setFCOs)-1):
00201 if(array[index] != array[index+1]):
00202 print "Returning False from "+sys._getframe().f_code.co_name
00203 return False
00204 return True
00205
00206 def compareReference(*referenceFCOs):
00207 array=[]
00208 for index in range(len(referenceFCOs)):
00209 array.append(dict())
00210 array[index][referenceFCOs[index].Name]=referenceFCOs[index].AbsPath
00211
00212 for index in range(len(referenceFCOs)-1):
00213 if(array[index] != array[index+1]):
00214 print "Returning False from "+sys._getframe().f_code.co_name
00215 return False
00216 return True
00217
00218 def compareAssoc(*current):
00219 array=[]
00220 for index in range(len(current)):
00221 array.append(dict())
00222 for point in current[index]:
00223 array[index][point.ConnRole]="%s %s" % (point.Target.Name,point.Target.AbsPath)
00224
00225 for index in range(len(current)-1):
00226 if(array[index] != array[index+1]):
00227 print "Returning False from "+sys._getframe().f_code.co_name
00228 return False
00229 return True
00230
00231 def compareAttrib(fco1, fco2):
00232 def mapAttribs(fco):
00233 ret = map(lambda attr: (attr.Meta.Name, attr.Value), fco.Attributes)
00234 return dict(ret)
00235 fco1Attribs = mapAttribs(fco1)
00236 fco2Attribs = mapAttribs(fco2)
00237 if fco1Attribs != fco2Attribs:
00238 print "'%s' has differing attributes:" % fco1.AbsPath
00239 unequalkeys = filter(lambda key: fco1Attribs.get(key) != fco2Attribs.get(key), fco1Attribs.keys())
00240 print "\n".join(map(lambda key: "Name: %s: '%s' != '%s' " % (key, fco1Attribs.get(key), fco2Attribs.get(key)), unequalkeys))
00241 return False
00242 return True
00243
00244 if __name__ == "__main__":
00245
00246 if(len(sys.argv)==3):
00247 file1=sys.argv[1]
00248 file2=sys.argv[2]
00249 if not os.path.isfile(file1):
00250 print False
00251 os.path.isfile(file2)
00252 if(compare(file1,file2)):
00253 print "'%s','%s' are the same" % (file1, file2)
00254 else:
00255 print "'%s','%s' are not the same" % (file1, file2)
00256 gc.collect()
00257 else:
00258 print "Need exactly two arguments"