packages feed

hackage-processing-0.0.0.1: src/Main.hs

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))