#!/usr/bin/python -tt # # Simple script to help ferret out multilib conflicts. # # Can be used in two different modes. The first is comparing two # packages given on the command line and showing any conflicts. # multilib-cmp.py # Can also be used to find multilib conflicts in a tree # multilib-cmp.py # # Copyright, 2006 Red Hat, Inc. # Jeremy Katz # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; version 2 only # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Library General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. import os,sys import glob import rpm import rpmUtils.arch import rpmUtils.miscutils _ts = None def comparePackages(one, two): fi1 = one.fiFromHeader() fi2 = two.fiFromHeader() num = 0 for file1 in fi1: name = fi1.FN() for file2 in fi2: if fi2.FN() == name: break if fi2.FN() != name: continue # if they're different colors, rpm is fine with it if fi1.FColor() != fi2.FColor(): continue # else, they're the same color and same path. ensure they don't # conflict if fi1.MD5() != fi2.MD5(): print "File conflict for %s in %s-%s-%s" %(fi1.FN(), one['name'], one['version'], one['release']) num += 1 return num def packageCompare(one, two): global _ts if _ts is None: _ts = rpm.TransactionSet() _ts.setVSFlags(-1) if not os.access(one, os.R_OK) or not os.access(two, os.R_OK): print one, two print "need packages!" sys.exit(1) fd = os.open(one, os.O_RDONLY) h1 = _ts.hdrFromFdno(fd) os.close(fd) fd = os.open(two, os.O_RDONLY) h2 = _ts.hdrFromFdno(fd) os.close(fd) return comparePackages(h1, h2) def multilibTreeCompare(tree): if not os.path.isdir(tree): print "Not a tree!" sys.exit(1) checked = [] for f in os.listdir(tree): (n, v, r, e, a) = rpmUtils.miscutils.splitFilename(f) if not rpmUtils.arch.isMultiLibArch(a): continue files = glob.glob("%s/%s-%s-%s.*.rpm" %(tree, n, v, r)) if len(files) == 1: continue for f2 in files: f2 = os.path.basename(f2) (n2, v2, r2, e2, a2) = rpmUtils.miscutils.splitFilename(f2) if (n, a) == (n2, a2): continue if a2 not in rpmUtils.arch.getArchList(a): continue packageCompare("%s/%s" %(tree, f), "%s/%s" %(tree, f2)) pass def main(): if len(sys.argv) == 2: multilibTreeCompare(sys.argv[1]) elif len(sys.argv) == 3: num = packageCompare(sys.argv[1], sys.argv[2]) if num == 0: print "No conflicts" else: print "Invalid usage!" sys.exit(1) if __name__ == "__main__": main()