utils.py 3.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. # Copyright 2014 The Distro Tracker Developers
  2. # See the COPYRIGHT file at the top-level directory of this distribution and
  3. # at http://deb.li/DTAuthors
  4. #
  5. # This file is part of Distro Tracker. It is subject to the license terms
  6. # in the LICENSE file found in the top-level directory of this
  7. # distribution and at http://deb.li/DTLicense. No part of Distro Tracker,
  8. # including this file, may be copied, modified, propagated, or distributed
  9. # except according to the terms contained in the LICENSE file.
  10. import collections
  11. from debian.debian_support import version_compare, BaseVersion
  12. CATEGORIES_VERSION_COMPARISON = {
  13. 'missing_pkg': 'Packages missing in the derivative',
  14. 'older_version': 'Packages with older upstream version',
  15. 'older_revision': 'Packages with older Debian revision',
  16. 'new_pkg': 'Packages specific to the derivative',
  17. 'newer_version': 'Packages with newer upstream version',
  18. 'newer_revision': 'Packages with newer Debian revision'
  19. }
  20. CATEGORIES_PRIORITY = {
  21. 'older_version': 1,
  22. 'older_revision': 2,
  23. 'missing_pkg': 3,
  24. 'new_pkg': 4,
  25. 'newer_version': 5,
  26. 'newer_revision': 6
  27. }
  28. def categorize_version_comparison(a, b):
  29. """Returns an identifier that categorizes the difference
  30. between a and b. The identifier can be looked up in
  31. CATEGORIES_VERSION_COMPARISON to have a long description."""
  32. if a == b:
  33. return 'equal'
  34. if a is None:
  35. return 'missing_pkg'
  36. if b is None:
  37. return 'new_pkg'
  38. deriv_epoch, deriv_upstream, deriv_revision = split_version(a)
  39. parent_epoch, parent_upstream, parent_revision = split_version(b)
  40. if deriv_epoch == parent_epoch:
  41. if deriv_upstream == parent_upstream:
  42. if version_compare(deriv_revision, parent_revision) < 0:
  43. return 'older_revision'
  44. else:
  45. return 'newer_revision'
  46. elif version_compare(deriv_upstream, parent_upstream) < 0:
  47. return 'older_version'
  48. else:
  49. return 'newer_version'
  50. elif version_compare(deriv_epoch, parent_epoch) < 0:
  51. return 'older_version'
  52. else:
  53. return 'newer_version'
  54. def compare_repositories(deriv_repository, parent_repository):
  55. # create a dict with all source packages and versions
  56. all_pkgs = collections.defaultdict(lambda: {})
  57. for name, version in deriv_repository.source_entries.values_list(
  58. 'source_package__source_package_name__name',
  59. 'source_package__version'):
  60. all_pkgs[name]['deriv_version'] = version
  61. for name, version in parent_repository.source_entries.values_list(
  62. 'source_package__source_package_name__name',
  63. 'source_package__version'):
  64. all_pkgs[name]['parent_version'] = version
  65. for pkg in all_pkgs:
  66. all_pkgs[pkg]['name'] = pkg
  67. all_pkgs[pkg]['category'] = categorize_version_comparison(
  68. all_pkgs[pkg].get('deriv_version'),
  69. all_pkgs[pkg].get('parent_version'))
  70. pkglist = [v for v in all_pkgs.values() if v['category'] != 'equal']
  71. # Sort by category first, and then by name
  72. pkglist.sort(key=lambda x: (CATEGORIES_PRIORITY[x['category']], x['name']))
  73. return pkglist
  74. def split_version(version):
  75. baseversion = BaseVersion(version)
  76. return (baseversion.epoch or '~', baseversion.upstream_version or '~',
  77. baseversion.debian_revision or '~')