############################################################################### # # Diff two licenses.xml files. Splits the result in three sets: # 1) Removed # Packages present in the old file, but not in the new. # # 2) Added # Packages present in the new file, but not in the old. # # 3) Changed # Packages present in both files, but with different versions. # # Note that packages with the unchanged version is not listed. # # The output is presented as XML code printed to stdout. # ############################################################################### import sys import subprocess import xml.etree.ElementTree as ET def get_pkgs(file_spec): if file_spec.find(":") >= 0: cmd = ("git", "show", file_spec) root = ET.fromstring(subprocess.check_output(cmd)) else: root = ET.parse(file_spec) for node in root.iter("section"): if "id" in node.attrib: if node.attrib["id"] == "licenses_packages": break else: return None for node in node: if node.tag == "informaltable": break else: return None tab = node[0][-1] plist = dict() for row in tab: pname = row[0].text pver = row[1].text if not pname in plist: plist[pname] = set() plist[pname].add(pver) return set(plist), plist #---------------------------------------- if len(sys.argv) != 3: sys.stderr.write("Usage:\n") sys.stderr.write(" %s " % sys.argv[0]) sys.stderr.write(" \n") sys.stderr.write("\n") sys.stderr.write(" E.g.:\n") sys.stderr.write(" %s " % sys.argv[0]) sys.stderr.write("licenses-5.0-ppc.xml licenses.xml\n") exit() new_file, old_file = sys.argv[1:3] sys.stderr.write("New license file : %s\n" % new_file) sys.stderr.write("Prev license file : %s\n" % old_file) old_pset, old_pdict = get_pkgs(old_file) new_pset, new_pdict = get_pkgs(new_file) added = new_pset - old_pset # Set subtraction removed = old_pset - new_pset # Set subtraction common = old_pset & new_pset changed = [ p for p in common if old_pdict[p] != new_pdict[p] ] print '' print '' print '
' print ' Changes in the Set of Provided Package' print ' ' print ' This section describes changes in the provided packages.' print ' ' print '
' print ' Added Packages' print ' ' print ' ' print ' ' print ' ' print ' Package' print ' Version(s)' print ' ' print ' ' print ' ' for p in sorted(list(added)): print ' ' print ' %s' % p print ' %s' % ", ".join(sorted(new_pdict[p])) print ' ' print ' ' print ' ' print ' ' print '
' print '
' print ' Removed Packages' print ' ' print ' ' print ' ' print ' ' print ' Package' print ' Version(s)' print ' ' print ' ' print ' ' for p in sorted(list(removed)): print ' ' print ' %s' % p print ' %s' % ", ".join(sorted(old_pdict[p])) print ' ' print ' ' print ' ' print ' ' print '
' print '
' print ' Changed Package Versions' print ' ' print ' ' print ' ' print ' ' print ' Package' print ' Previous Version(s)' print ' New Version(s)' print ' ' print ' ' print ' ' for p in sorted(list(changed)): print ' ' print ' %s' % p print ' %s' % ", ".join(sorted(old_pdict[p])) print ' %s' % ", ".join(sorted(new_pdict[p])) print ' ' print ' ' print ' ' print ' ' print '
' print '
' sys.stderr.write("Package Summary:\n") sys.stderr.write(" Prev file : %3d\n" % len(old_pset)) sys.stderr.write(" New file : %3d\n" % len(new_pset)) sys.stderr.write(" Added : %3d\n" % len(added)) sys.stderr.write(" Removed : %3d\n" % len(removed)) sys.stderr.write(" Changed : %3d\n" % len(changed)) sys.stderr.write(" Unchanged : %3d\n" % (len(common) - len(changed))) sys.stderr.write("Done\n")