compare_packages.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. #!/bin/env python
  2. from __future__ import print_function
  3. from collections import OrderedDict
  4. import argparse
  5. import os
  6. import glob
  7. import subprocess
  8. from datetime import datetime
  9. def list_rpms(directory):
  10. rpms = OrderedDict()
  11. for filepath in sorted(glob.glob(os.path.join(directory, '*.rpm'))):
  12. info = subprocess.check_output(['rpm', '-qp', filepath, '--qf',
  13. "%{name},,%{license},,%{vendor},,%{buildhost},,"
  14. "%{buildtime},,%{evr},,%{sourcerpm},,%{summary}"])
  15. info = info.split(',,')
  16. rpms[info[0]] = {
  17. 'filepath': filepath,
  18. 'filename': os.path.basename(filepath),
  19. 'license': info[1],
  20. 'vendor': info[2],
  21. 'buildhost': info[3],
  22. 'buildtime': datetime.fromtimestamp(float(info[4])),
  23. 'evr': info[5],
  24. 'sourcerpm': info[6],
  25. 'summary': info[7]
  26. }
  27. return rpms
  28. def main():
  29. parser = argparse.ArgumentParser(description='Compares two sets of RPM packages')
  30. parser.add_argument('dir1', help='first directory')
  31. parser.add_argument('dir2', help='second directory')
  32. args = parser.parse_args()
  33. DEVNULL = open(os.devnull, 'w')
  34. dir1 = os.path.abspath(args.dir1)
  35. dir2 = os.path.abspath(args.dir2)
  36. # list RPMs
  37. rpms1 = list_rpms(dir1)
  38. rpms2 = list_rpms(dir2)
  39. for name, info in rpms1.iteritems():
  40. if name not in rpms2:
  41. info['removed'] = True
  42. rpms2[name] = info
  43. rpms2 = OrderedDict(sorted(rpms2.iteritems(), key=lambda t: t[0]))
  44. vendors = set([info['vendor'] for info in rpms1.itervalues()])
  45. vendors |= set([info['vendor'] for info in rpms2.itervalues()])
  46. for vendor in sorted(list(vendors)):
  47. print("\n\n-------------------- Vendor: %s ------------------------\n" % vendor)
  48. for name, info in rpms2.iteritems():
  49. if info['vendor'] != vendor:
  50. continue
  51. if name not in rpms1:
  52. print("*** %s added" % info['filename'])
  53. print("Summary: %s" % info['summary'])
  54. print("License: %s" % info['license'])
  55. elif info.get('removed', False):
  56. status = "%s removed" % info['filename']
  57. else:
  58. previous = rpms1[name]['filename']
  59. if info['evr'] == rpms1[name]['evr']:
  60. # version unchanged, check diff
  61. ret = subprocess.call(['diff', '-q', rpms1[name]['filepath'], info['filepath']],
  62. stdout=DEVNULL, stderr=subprocess.STDOUT)
  63. if (ret != 0):
  64. status = "%s EVR unchanged, new file differs" % previous
  65. else:
  66. status = "%s EVR unchanged, new file identical" % previous
  67. print("*** %s" % status)
  68. else:
  69. status = "%s => %s" % (previous, info['filename'])
  70. print("*** %s" % status)
  71. if info['summary'] != rpms1[name]['summary']:
  72. print("Summary (previous): %s" % rpms1[name]['summary'])
  73. print("Summary: %s" % info['summary'])
  74. if info['license'] != rpms1[name]['license']:
  75. print("License (previous): %s" % rpms1[name]['license'])
  76. print("License: %s" % info['license'])
  77. print(subprocess.check_output("rpmdiff -iT %s %s 2>&1 || echo" % (rpms1[name]['filepath'], info['filepath']),
  78. shell=True),
  79. end='')
  80. if __name__ == "__main__":
  81. main()