compare_packages.py 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. #!/usr/bin/env python3
  2. from collections import OrderedDict
  3. import argparse
  4. import os
  5. import glob
  6. import subprocess
  7. from datetime import datetime
  8. def list_rpms(directory):
  9. rpms = OrderedDict()
  10. for filepath in sorted(glob.glob(os.path.join(directory, '*.rpm'))):
  11. info = subprocess.check_output(['rpm', '-qp', filepath, '--qf',
  12. "%{name},,%{license},,%{vendor},,%{buildhost},,"
  13. "%{buildtime},,%{evr},,%{sourcerpm},,%{summary}"])
  14. info = info.decode('utf-8')
  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.items():
  40. if name not in rpms2:
  41. info['removed'] = True
  42. rpms2[name] = info
  43. rpms2 = OrderedDict(sorted(rpms2.items(), key=lambda t: t[0]))
  44. vendors = set([info['vendor'] for info in rpms1.values()])
  45. vendors |= set([info['vendor'] for info in rpms2.values()])
  46. for vendor in sorted(list(vendors)):
  47. print("\n\n-------------------- Vendor: %s ------------------------\n" % vendor)
  48. for name, info in rpms2.items():
  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("SRPM: %s" % info['sourcerpm'])
  55. print("License: %s" % info['license'])
  56. print(subprocess.check_output(['rpm', '-qlp', info['filepath']]).decode('utf-8'))
  57. elif info.get('removed', False):
  58. print("*** %s removed" % info['filename'])
  59. if info['vendor'] not in ['CentOS', 'Fedora Project']:
  60. print("Summary: %s" % info['summary'])
  61. print("SRPM: %s" % info['sourcerpm'])
  62. print("License: %s" % info['license'])
  63. print(subprocess.check_output(['rpm', '-qlp', info['filepath']]).decode('utf-8'))
  64. else:
  65. previous = rpms1[name]['filename']
  66. if info['evr'] == rpms1[name]['evr']:
  67. # version unchanged, check diff
  68. ret = subprocess.call(['diff', '-q', rpms1[name]['filepath'], info['filepath']],
  69. stdout=DEVNULL, stderr=subprocess.STDOUT)
  70. if (ret != 0):
  71. status = "%s EVR unchanged, new file differs" % previous
  72. else:
  73. status = "%s EVR unchanged, new file identical" % previous
  74. print("*** %s" % status)
  75. else:
  76. status = "%s => %s" % (previous, info['filename'])
  77. print("*** %s" % status)
  78. if info['summary'] != rpms1[name]['summary']:
  79. print("Summary (previous): %s" % rpms1[name]['summary'])
  80. print("Summary: %s" % info['summary'])
  81. if info['license'] != rpms1[name]['license']:
  82. print("License (previous): %s" % rpms1[name]['license'])
  83. print("SRPM: %s" % info['sourcerpm'])
  84. print("License: %s" % info['license'])
  85. print(subprocess.check_output("rpmdiff -iT %s %s 2>&1 || echo" % (rpms1[name]['filepath'], info['filepath']),
  86. shell=True).decode('utf-8'),
  87. end='')
  88. if __name__ == "__main__":
  89. main()