New script to report file systems
[gnucomo.git] / scripts / report_repository.py
1 #!/usr/bin/python3
2 #
3 # Gnucomo repository report.
4 #
5 # Create a 'rpm -qa' - like report from a directory of (rpm)
6 # packages. Select the latest version of each package if there
7 # are multiple files of the same package available.
8
9 import glob
10 import os
11 import sys
12
13 #
14 #  Tokenize a string into parts of consequetive letters or digits.
15 #
16
17 def tokenize(version):
18    tokens = []
19    word = ""
20    state = 0   #  0:  No alphanumeric, 1: digits, 2: letters
21    for letter in version:
22       if state == 0:
23          if letter.isdigit():
24             word = word + letter
25             state = 1
26          if letter.isalpha():
27             word = word + letter
28             state = 2
29       elif state == 1:
30          if letter.isdigit():
31             word = word + letter
32          else:
33             tokens.append(word)
34             if letter.isalpha():
35                word = letter
36                state = 2
37             else:
38                word = ""
39                state = 0
40       elif state == 2:
41          if letter.isalpha():
42             word = word + letter
43          else:
44             tokens.append(word)
45             if letter.isdigit():
46                word = letter
47                state = 1
48             else:
49                word = ""
50                state = 0
51
52    if word != "":
53       tokens.append(word)
54
55    return tokens
56
57 # compare alpha and numeric segments of two versions
58 # return 1: a is newer than b
59 #        0: a and b are the same version
60 #       -1: b is newer than a
61
62 def compare_versions(a, b):
63    rc = 0
64    version1 = tokenize(a)
65    version2 = tokenize(b)
66    for v1, v2 in zip(version1, version2):
67       if rc == 0 and v1 != v2:
68          if v1.isdigit() and v2.isdigit():
69             v1 = int(v1)
70             v2 = int(v2)
71          if v1 > v2:
72             rc = 1
73          else:
74             rc = -1
75
76    if rc == 0 and len(version1) != len(version2):
77       if len(version1) > len(version2):
78          rc = 1
79       else:
80          rc = -1
81
82    return rc
83
84 #
85 #  The string method rsplit() is available in python version 2.4 and later.
86 #  This is a limited implementation for older python versions.
87 #
88
89 def rsplit2(src, sep):
90    result = []
91    words = src.split(sep)
92
93    result.append(sep.join(words[0:-2]))
94    if len(words) > 2:
95       result.append(words[-2])
96       result.append(words[-1])
97
98    return result
99
100 # Make sure we have the repository directory as argument.
101
102 if len(sys.argv) != 2:
103    print ("Usage: ", sys.argv[0], " <directory>")
104    sys.exit(1)
105
106 packages = []
107 for name in glob.glob(os.path.join(sys.argv[1],"*.rpm")):
108    pack = os.path.basename(name).rsplit(".",2)
109    if pack[0] != "":
110       packages.append(pack[0])
111
112 packages.sort()
113
114 latest_packages = []
115 previous = ""
116
117 # Select the latest package in case of duplicates.
118
119 for name in packages:
120    p1 = previous.rsplit("-",2)
121    p2 = name.rsplit("-", 2)
122    if p1[0] == p2[0]:
123       if compare_versions(p1[1], p2[1]) < 0:
124          #print "Skipping old package ", previous
125          previous = name
126       elif compare_versions(p1[1], p2[1]) == 0 and compare_versions(p1[2], p2[2]) < 0:
127          #print "Skipping old package ", previous
128          previous = name
129    else:
130       if previous != "":
131          latest_packages.append(previous)
132       previous = name
133
134 latest_packages.append(previous)
135
136 for p in latest_packages:
137    print (p)