-----------------------------------------------------------------------------
-- |
-- Module : Hackage.Index
-- Copyright : (c) David Himmelstrup 2005, Bjorn Bringert 2007
-- License : BSD-like
--
-- Maintainer : lemmih@gmail.com
-- Stability : provisional
-- Portability : portable
--
-- Reading the local package index.
-----------------------------------------------------------------------------
module Hackage.Index (getKnownPackages) where
import Hackage.Config
import Hackage.Types
import Hackage.Tar
import Prelude hiding (catch)
import Control.Exception (catch, Exception(IOException))
import qualified Data.ByteString.Lazy.Char8 as BS
import Data.ByteString.Lazy.Char8 (ByteString)
import System.FilePath ((</>), takeExtension, splitDirectories, normalise)
import System.IO (hPutStrLn, stderr)
import System.IO.Error (isDoesNotExistError)
import Distribution.PackageDescription (parsePackageDescription, ParseResult(..))
import Distribution.Package (PackageIdentifier(..))
import Distribution.Version (readVersion)
getKnownPackages :: ConfigFlags -> IO [PkgInfo]
getKnownPackages cfg
= fmap concat $ mapM (readRepoIndex cfg) $ configRepos cfg
readRepoIndex :: ConfigFlags -> Repo -> IO [PkgInfo]
readRepoIndex cfg repo =
do let indexFile = repoCacheDir cfg repo </> "00-index.tar"
fmap (parseRepoIndex repo) (BS.readFile indexFile)
`catch` (\e -> do case e of
IOException ioe | isDoesNotExistError ioe ->
hPutStrLn stderr "The package list does not exist. Run 'cabal update' to download it."
_ -> hPutStrLn stderr ("Error: " ++ show e)
return [])
parseRepoIndex :: Repo -> ByteString -> [PkgInfo]
parseRepoIndex repo s =
do (hdr, content) <- readTarArchive s
if takeExtension (tarFileName hdr) == ".cabal"
then case splitDirectories (normalise (tarFileName hdr)) of
[pkgname,vers,_] ->
let descr = case parsePackageDescription (BS.unpack content) of
ParseOk _ d -> d
_ -> error $ "Couldn't read cabal file "
++ show (tarFileName hdr)
in case readVersion vers of
Just ver ->
return $ PkgInfo {
pkgInfoId = PackageIdentifier pkgname ver,
pkgRepo = repo,
pkgDesc = descr
}
_ -> []
_ -> []
else []