module Main where import qualified Distribution.Hackage.DB.Parsed as DB import qualified Distribution.PackageDescription as Pkg import Distribution.PackageDescription (GenericPackageDescription) import Distribution.Text (display) import System.Environment (getArgs) import Text.Printf (printf) import qualified Data.Foldable as Fold import qualified Data.List as List import qualified Data.Map as Map import Data.Char (toLower) hasContributor :: String -> GenericPackageDescription -> Bool hasContributor person = let personLC = map toLower person contains = List.isInfixOf personLC . map toLower in \gpkg -> let pkg = Pkg.packageDescription gpkg in contains (Pkg.author pkg) || contains (Pkg.maintainer pkg) main :: IO () main = do [person] <- getArgs db <- DB.readHackage {- | For lazy processing it is important not to flatten the Map with Map.mapMaybe. -} let scanned = Map.map (fmap fst . Map.maxViewWithKey . Map.filter (hasContributor person)) db Fold.sequence_ $ flip Map.mapWithKey scanned $ \pkgName maybeMatching -> Fold.forM_ maybeMatching $ \(version, pkg) -> printf "%s & %s & %s \\\\\n" pkgName (display version) (Pkg.synopsis (Pkg.packageDescription pkg))