[Lsb-messages] /var/www/bzr/lsb/devel/repogen r201: Add Package functions for comparing packages.
Jeff Licquia
licquia at linuxfoundation.org
Fri Jun 14 18:01:26 UTC 2013
------------------------------------------------------------
revno: 201
committer: Jeff Licquia <licquia at linuxfoundation.org>
branch nick: repogen
timestamp: Fri 2013-06-14 14:01:26 -0400
message:
Add Package functions for comparing packages.
modified:
Package.hs
-------------- next part --------------
=== modified file 'Package.hs'
--- a/Package.hs 2013-06-13 02:35:11 +0000
+++ b/Package.hs 2013-06-14 18:01:26 +0000
@@ -215,3 +215,87 @@
release=release p,
arch=arch p,
pkgtype=pkgtype p }
+
+-- Package comparison functions. Besides simple equality, we want
+-- to be able to compare package versions. The rules below are intended
+-- to mirror the rules as specified by RPM and in the Debian Policy
+-- Manual; any deviation from those rules is a bug.
+
+fragmentCollect :: [Char] -> (String, String) -> (String, String)
+fragmentCollect charset (xs, "") = (xs, "")
+fragmentCollect charset (xs, y:ys)
+ | y `elem` charset
+ = fragmentCollect charset (xs ++ [y], ys)
+ | otherwise
+ = (xs, y:ys)
+
+getSet :: Char -> Maybe [Char]
+getSet c = let sets = filter (elem c) [ ['0'..'9'], (['A'..'Z'] ++ ['a'..'z']),
+ ['~'] ]
+ in if null sets then Nothing
+ else Just $ head sets
+
+splitVersion :: String -> [String]
+splitVersion "" = []
+splitVersion (x:xs)
+ | isJust charset
+ = let (chunk, rest) = fragmentCollect (fromJust charset) ([x], xs)
+ in [chunk] ++ splitVersion rest
+ | otherwise
+ = splitVersion xs
+ where charset = getSet x
+
+compareVersionChunks :: String -> String -> Ordering
+compareVersionChunks "" "" = EQ
+compareVersionChunks "" (y:ys)
+ | y == '~' = GT
+ | otherwise = LT
+compareVersionChunks (x:xs) ""
+ | x == '~' = LT
+ | otherwise = GT
+compareVersionChunks (x:xs) (y:ys)
+ | x == '~' && y /= '~' = LT
+ | x /= '~' && y == '~' = GT
+ | x `elem` numbers && y `notElem` numbers = GT
+ | x `notElem` numbers && y `elem` numbers = LT
+ | x `elem` numbers && y `elem` numbers
+ = (read (x:xs) :: Int) `compare` (read (y:ys) :: Int)
+ | otherwise
+ = (x:xs) `compare` (y:ys)
+ where numbers = ['0'..'9']
+
+compareVersionChunkLists :: [String] -> [String] -> Ordering
+compareVersionChunkLists [] [] = EQ
+compareVersionChunkLists [] (y:ys)
+ | head y == '~' = GT
+ | otherwise = LT
+compareVersionChunkLists (x:xs) []
+ | head x == '~' = LT
+ | otherwise = GT
+compareVersionChunkLists (x:xs) (y:ys)
+ = case chunkComparison of
+ EQ -> compareVersionChunkLists xs ys
+ otherwise -> chunkComparison
+ where chunkComparison = compareVersionChunks x y
+
+comparePackageVersions :: Package -> Package -> Ordering
+comparePackageVersions x y
+ = compareVersionChunkLists [epoch x, version x, release x]
+ [epoch y, version y, release y]
+
+compareVersionStrings :: String -> String -> Ordering
+compareVersionStrings x y
+ = compareVersionChunkLists (splitVersion x) (splitVersion y)
+
+-- Package equivalence: is one package a correct upgrade of another?
+-- This version is fairly naive; it doesn't allow for concepts like
+-- Provides or Replaces. But it should work for now, and allow for
+-- future enhancement.
+
+equivalent :: Package -> Package -> Bool
+equivalent x y = (pkgtype x == pkgtype y) && (name x == name y)
+
+comparePackages :: Package -> Package -> Maybe Ordering
+comparePackages x y
+ | equivalent x y = Just $ comparePackageVersions x y
+ | otherwise = Nothing
More information about the lsb-messages
mailing list