--- /dev/null
+#
+# Gnucomo repository report.
+#
+# Create a 'rpm -qa' - like report from a directory of (rpm)
+# packages. Select the latest version of each package if there
+# are multiple files of the same package available.
+#
+import glob
+import os
+import sys
+
+#
+# Tokenize a string into parts of consequetive letters or digits.
+#
+
+def tokenize(version):
+ tokens = []
+ word = ""
+ state = 0 # 0: No alphanumeric, 1: digits, 2: letters
+ for letter in version:
+ if state == 0:
+ if letter.isdigit():
+ word = word + letter
+ state = 1
+ if letter.isalpha():
+ word = word + letter
+ state = 2
+ elif state == 1:
+ if letter.isdigit():
+ word = word + letter
+ else:
+ tokens.append(word)
+ if letter.isalpha():
+ word = letter
+ state = 2
+ else:
+ word = ""
+ state = 0
+ elif state == 2:
+ if letter.isalpha():
+ word = word + letter
+ else:
+ tokens.append(word)
+ if letter.isdigit():
+ word = letter
+ state = 1
+ else:
+ word = ""
+ state = 0
+
+ if word != "":
+ tokens.append(word)
+
+ return tokens
+
+# compare alpha and numeric segments of two versions
+# return 1: a is newer than b
+# 0: a and b are the same version
+# -1: b is newer than a
+
+def compare_versions(a, b):
+ rc = 0
+ version1 = tokenize(a)
+ version2 = tokenize(b)
+ for v1, v2 in zip(version1, version2):
+ if rc == 0 and v1 != v2:
+ if v1.isdigit() and v2.isdigit():
+ v1 = int(v1)
+ v2 = int(v2)
+ if v1 > v2:
+ rc = 1
+ else:
+ rc = -1
+
+ if rc == 0 and len(version1) != len(version2):
+ if len(version1) > len(version2):
+ rc = 1
+ else:
+ rc = -1
+
+ return rc
+
+#
+# The string method rsplit() is available in python version 2.4 and later.
+# This is a limited implementation for older python versions.
+#
+
+def rsplit2(src, sep):
+ result = []
+ words = src.split(sep)
+
+ result.append(sep.join(words[0:-2]))
+ if len(words) > 2:
+ result.append(words[-2])
+ result.append(words[-1])
+
+ return result
+
+# Make sure we have the repository directory as argument.
+
+if len(sys.argv) != 2:
+ print "Usage: ", sys.argv[0], " <directory>"
+ sys.exit(1)
+
+packages = []
+for name in glob.glob(os.path.join(sys.argv[1],"*.rpm")):
+ pack = rsplit2(os.path.basename(name),".")
+ if pack[0] != "":
+ packages.append(pack[0])
+
+packages.sort()
+
+latest_packages = []
+previous = ""
+
+# Select the latest package in case of duplicates.
+
+for name in packages:
+ p1 = rsplit2(previous,"-")
+ p2 = rsplit2(name,"-")
+ if p1[0] == p2[0]:
+ if compare_versions(p1[1], p2[1]) < 0:
+ #print "Skipping old package ", previous
+ previous = name
+ elif compare_versions(p1[1], p2[1]) == 0 and compare_versions(p1[2], p2[2]) < 0:
+ #print "Skipping old package ", previous
+ previous = name
+ else:
+ if previous != "":
+ latest_packages.append(previous)
+ previous = name
+
+latest_packages.append(previous)
+
+for p in latest_packages:
+ print p