module Scion.Hoogle.Util
( findHoogleBinPath
) where
import Data.List (find)
import Distribution.InstalledPackageInfo
import Distribution.Package
import Scion.Packages
import System.FilePath
import System.Directory (doesFileExist)
#ifdef mingw32_HOST_OS
import System.Directory (getAppUserDataDirectory)
#endif
findHoogleBinPath :: IO (Maybe String)
findHoogleBinPath = findPathsAndCheck placesToSearch
where placesToSearch = [ findHoogleBinInLibrary getHoogleBinPath1
, findHoogleBinInLibrary getHoogleBinPath2
#ifdef mingw32_HOST_OS
, getHoogleBinPath3
#endif
]
findPathsAndCheck :: [IO (Maybe String)] -> IO (Maybe String)
findPathsAndCheck [] = return Nothing
findPathsAndCheck (f:fs) = do r <- findPathAndCheck f
case r of
Nothing -> findPathsAndCheck fs
_ -> return r
findPathAndCheck :: IO (Maybe String) -> IO (Maybe String)
findPathAndCheck f = do p <- f
case p of
Nothing -> return Nothing
Just path -> do exists <- doesFileExist path
if exists
then return (Just path)
else return Nothing
findHoogleBinInLibrary :: (String -> String) -> IO (Maybe String)
findHoogleBinInLibrary f = do minfo <- findHoogleInfo
case minfo of
Nothing -> return Nothing
Just info -> let [libDir] = libraryDirs info
in return $ Just (f libDir)
findHoogleInfo :: IO (Maybe InstalledPackageInfo)
findHoogleInfo = do infos' <- getPkgInfos
let infos = removeSmallVersions $ concat $ map snd infos'
return $ find (\m -> (pkgName (sourcePackageId m)) == PackageName "hoogle") infos
removeSmallVersions :: [InstalledPackageInfo] -> [InstalledPackageInfo]
removeSmallVersions pids = filter
(not . (\InstalledPackageInfo { sourcePackageId = (PackageIdentifier name version) } ->
any (\InstalledPackageInfo { sourcePackageId = (PackageIdentifier name' version') } ->
name' == name && version' > version)
pids))
pids
getHoogleBinPath1 :: String -> String
getHoogleBinPath1 path = let (_:(_:(_:rest))) = reverse $ splitDirectories path
in (joinPath $ reverse ("bin":rest)) </> "hoogle" <.> exeExtension
getHoogleBinPath2 :: String -> String
getHoogleBinPath2 path = let (_:(_:rest)) = reverse $ splitDirectories path
in (joinPath $ reverse ("bin":rest)) </> "hoogle" <.> exeExtension
#ifdef mingw32_HOST_OS
getHoogleBinPath3 :: IO (Maybe String)
getHoogleBinPath3 = do cabalDir <- getAppUserDataDirectory "cabal"
return $ Just (cabalDir </> "bin" </> "hoogle" <.> exeExtension)
#endif
exeExtension :: String
#ifdef mingw32_HOST_OS
exeExtension = "exe"
#else
exeExtension = ""
#endif