module Debian.Report where
import Data.Maybe
import qualified Data.Map as M
import Data.Text as Text (Text, unpack)
import Debian.Apt.Index (Fetcher, Compression(..), update, controlFromIndex')
import Debian.Control.Text
import Debian.Sources
import Debian.Version
import Text.XML.HaXml (CFilter, mkElem, cdata)
import Text.XML.HaXml.Posn
import Text.PrettyPrint (render)
makePackageMap :: (Paragraph -> a) -> (a -> a -> a) -> [(FilePath, Compression)] -> IO (M.Map Text 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' Text -> M.Map Text 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' . unpack) $ fieldValue "Version" paragraph
trumped :: Fetcher
-> FilePath
-> String
-> [DebSource]
-> [DebSource]
-> IO (M.Map Text (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 Text DebianVersion
-> M.Map Text DebianVersion
-> M.Map Text (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 Text (DebianVersion, DebianVersion) -> CFilter Posn
trumpedXML trumpedMap' =
mkElem "trumped" (map mkTrumpedPackage (M.toAscList trumpedMap' ))
where
mkTrumpedPackage (package, (oldVersion, newVersion)) =
mkElem "trumpedPackage"
[ mkElem "package" [ cdata (unpack package) ]
, mkElem "oldVersion" [ cdata (render . prettyDebianVersion $ oldVersion) ]
, mkElem "newVersion" [ cdata (render . prettyDebianVersion $ newVersion) ]
]