1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

# Copyright 2014 The Distro Tracker Developers 

# See the COPYRIGHT file at the top-level directory of this distribution and 

# at https://deb.li/DTAuthors 

# 

# This file is part of Distro Tracker. It is subject to the license terms 

# in the LICENSE file found in the top-level directory of this 

# distribution and at https://deb.li/DTLicense. No part of Distro Tracker, 

# including this file, may be copied, modified, propagated, or distributed 

# except according to the terms contained in the LICENSE file. 

"""Helper functions for distro_tracker.derivative.""" 

 

import collections 

 

from debian.debian_support import BaseVersion, version_compare 

 

CATEGORIES_VERSION_COMPARISON = { 

'missing_pkg': 'Packages missing in the derivative', 

'older_version': 'Packages with older upstream version', 

'older_revision': 'Packages with older Debian revision', 

'new_pkg': 'Packages specific to the derivative', 

'newer_version': 'Packages with newer upstream version', 

'newer_revision': 'Packages with newer Debian revision' 

} 

 

CATEGORIES_PRIORITY = { 

'older_version': 1, 

'older_revision': 2, 

'missing_pkg': 3, 

'new_pkg': 4, 

'newer_version': 5, 

'newer_revision': 6 

} 

 

 

def categorize_version_comparison(a, b): 

"""Returns an identifier that categorizes the difference 

between a and b. The identifier can be looked up in 

CATEGORIES_VERSION_COMPARISON to have a long description.""" 

if a == b: 

return 'equal' 

if a is None: 

return 'missing_pkg' 

if b is None: 

return 'new_pkg' 

 

deriv_epoch, deriv_upstream, deriv_revision = split_version(a) 

parent_epoch, parent_upstream, parent_revision = split_version(b) 

 

if deriv_epoch == parent_epoch: 

if deriv_upstream == parent_upstream: 

if version_compare(deriv_revision, parent_revision) < 0: 

return 'older_revision' 

else: 

return 'newer_revision' 

elif version_compare(deriv_upstream, parent_upstream) < 0: 

return 'older_version' 

else: 

return 'newer_version' 

59 ↛ 62line 59 didn't jump to line 62, because the condition on line 59 was never false elif version_compare(deriv_epoch, parent_epoch) < 0: 

return 'older_version' 

else: 

return 'newer_version' 

 

 

def compare_repositories(deriv_repository, parent_repository): 

"""Build a list with results of comparisons for each package.""" 

# create a dict with all source packages and versions 

all_pkgs = collections.defaultdict(lambda: {}) 

for name, version in deriv_repository.source_entries.values_list( 

'source_package__source_package_name__name', 

'source_package__version'): 

all_pkgs[name]['deriv_version'] = version 

for name, version in parent_repository.source_entries.values_list( 

'source_package__source_package_name__name', 

'source_package__version'): 

all_pkgs[name]['parent_version'] = version 

 

for pkg in all_pkgs: 

all_pkgs[pkg]['name'] = pkg 

all_pkgs[pkg]['category'] = categorize_version_comparison( 

all_pkgs[pkg].get('deriv_version'), 

all_pkgs[pkg].get('parent_version')) 

 

pkglist = [v for v in all_pkgs.values() if v['category'] != 'equal'] 

 

# Sort by category first, and then by name 

pkglist.sort(key=lambda x: (CATEGORIES_PRIORITY[x['category']], x['name'])) 

 

return pkglist 

 

 

def split_version(version): 

"""Split the version in its 3 components (epoch, version, revision).""" 

baseversion = BaseVersion(version) 

return (baseversion.epoch or '~', baseversion.upstream_version or '~', 

baseversion.debian_revision or '~')