----------------------------------------------------------------------------- -- | -- Module : Hackage.Install -- Copyright : (c) David Himmelstrup 2005 -- License : BSD-like -- -- Maintainer : lemmih@gmail.com -- Stability : provisional -- Portability : portable -- -- High level interface to package installation. ----------------------------------------------------------------------------- module Hackage.List ( list -- :: ConfigFlags -> [UnresolvedDependency] -> IO () ) where import Data.List (nubBy, sortBy, groupBy, intersperse, isPrefixOf, tails) import Data.Char as Char (toLower) import Distribution.Package import Distribution.PackageDescription import Distribution.Version (showVersion) import Hackage.Index (getKnownPackages) import Hackage.Types (PkgInfo(..), ConfigFlags(..), {- UnresolvedDependency(..)-} ) -- |Show information about packages list :: ConfigFlags -> [String] -> IO () list cfg pats = do pkgs <- getKnownPackages cfg let pkgs' | null pats = pkgs | otherwise = nubBy samePackage (concatMap (findInPkgs pkgs) pats') pats' = map lcase pats putStrLn . unlines . map (showPkgVersions . map (packageDescription . pkgDesc)) . groupBy sameName . sortBy (comparing nameAndVersion) $ pkgs' where findInPkgs :: [PkgInfo] -> String -> [PkgInfo] findInPkgs pkgs pat = filter (isInfixOf pat . lcase . pkgName . pkgInfoId) pkgs lcase = map Char.toLower nameAndVersion p = (lcase name, name, version) where name = pkgName (pkgInfoId p) version = pkgVersion (pkgInfoId p) samePackage a b = nameAndVersion a == nameAndVersion b sameName a b = pkgName (pkgInfoId a) == pkgName (pkgInfoId b) showPkgVersions :: [PackageDescription] -> String showPkgVersions pkgs = padTo 35 (pkgName (package pkg) ++ " [" ++ concat (intersperse ", " versions) ++ "] ") ++ synopsis pkg where pkg = last pkgs versions = map (showVersion . pkgVersion . package) pkgs padTo n s = s ++ (replicate (n - length s) ' ') comparing :: (Ord a) => (b -> a) -> b -> b -> Ordering comparing p x y = compare (p x) (p y) isInfixOf :: String -> String -> Bool isInfixOf needle haystack = any (isPrefixOf needle) (tails haystack)