module Debian.Report where
import Debian.Apt.Index (Fetcher, Compression(..), update, controlFromIndex')
import Debian.Control.ByteString
import Debian.Sources
import Debian.Version
import Data.Maybe
import qualified Data.Map as M
import qualified Data.ByteString.Char8 as B
import Text.XML.HaXml
import Text.XML.HaXml.Posn
makePackageMap :: (Paragraph -> a) -> (a -> a -> a) -> [(FilePath, Compression)] -> IO (M.Map B.ByteString a)
makePackageMap _ _ [] = return M.empty
makePackageMap extractValue resolveConflict ((path, compression):is) =
do r <- controlFromIndex' compression path
case r of
(Left e) -> error (show e)
(Right c) ->
do let pm = packageMap extractValue resolveConflict c
pms <- makePackageMap extractValue resolveConflict is
return $ M.unionWith resolveConflict pm pms
packageMap :: (Paragraph -> a) -> (a -> a -> a) -> Control -> M.Map B.ByteString a
packageMap extractValue resolveConflict control =
M.fromListWith resolveConflict (map packageTuple (unControl control))
where
packageTuple paragraph = (fromJust $ fieldValue "Package" paragraph, extractValue paragraph)
extractVersion :: Paragraph -> Maybe DebianVersion
extractVersion paragraph = fmap (parseDebianVersion . B.unpack) $ fieldValue "Version" paragraph
trumped :: Fetcher
-> FilePath
-> String
-> [DebSource]
-> [DebSource]
-> IO (M.Map B.ByteString (DebianVersion, DebianVersion))
trumped fetcher cacheDir arch sourcesA sourcesB =
do indexesA <- update fetcher cacheDir arch (filter isDebSrc sourcesA)
pmA <- makePackageMap (fromJust . extractVersion) max (map fromJust indexesA)
indexesB <- update fetcher cacheDir arch (filter isDebSrc sourcesB)
pmB <- makePackageMap (fromJust . extractVersion) max (map fromJust indexesB)
return (trumpedMap pmA pmB)
where
isDebSrc ds = sourceType ds == DebSrc
trumpedMap :: M.Map B.ByteString DebianVersion
-> M.Map B.ByteString DebianVersion
-> M.Map B.ByteString (DebianVersion, DebianVersion)
trumpedMap pmA pmB =
M.foldWithKey (checkTrumped pmB) M.empty pmA
where
checkTrumped pm package aVersion trumpedPM =
case M.lookup package pm of
(Just bVersion)
| bVersion > aVersion -> M.insert package (aVersion, bVersion) trumpedPM
_ -> trumpedPM
trumpedXML :: M.Map B.ByteString (DebianVersion, DebianVersion) -> CFilter Posn
trumpedXML trumpedMap' =
mkElem "trumped" (map mkTrumpedPackage (M.toAscList trumpedMap' ))
where
mkTrumpedPackage (package, (oldVersion, newVersion)) =
mkElem "trumpedPackage"
[ mkElem "package" [ cdata (B.unpack package) ]
, mkElem "oldVersion" [ cdata (show (prettyDebianVersion oldVersion)) ]
, mkElem "newVersion" [ cdata (show (prettyDebianVersion newVersion)) ]
]