2013-09-21 09:37:33 +00:00
|
|
|
module Language.Haskell.GhcMod.Cradle (
|
|
|
|
findCradle
|
2014-05-18 01:32:09 +00:00
|
|
|
, findCradle'
|
2015-03-03 20:12:43 +00:00
|
|
|
, findSpecCradle
|
2014-10-14 17:52:58 +00:00
|
|
|
, cleanupCradle
|
2013-09-21 09:37:33 +00:00
|
|
|
) where
|
2013-03-02 03:18:55 +00:00
|
|
|
|
2014-11-01 21:02:47 +00:00
|
|
|
import Language.Haskell.GhcMod.PathsAndFiles
|
2015-03-03 20:12:43 +00:00
|
|
|
import Language.Haskell.GhcMod.Monad.Types
|
2014-11-01 21:02:47 +00:00
|
|
|
import Language.Haskell.GhcMod.Types
|
2014-11-02 18:00:25 +00:00
|
|
|
import Language.Haskell.GhcMod.Utils
|
2014-04-15 03:13:10 +00:00
|
|
|
|
2015-03-03 20:12:43 +00:00
|
|
|
import Control.Applicative
|
|
|
|
import Control.Monad
|
|
|
|
import Control.Monad.Trans.Maybe
|
|
|
|
import Data.Maybe
|
|
|
|
import System.Directory
|
|
|
|
import System.FilePath
|
2013-03-02 03:18:55 +00:00
|
|
|
|
2013-09-05 07:38:17 +00:00
|
|
|
----------------------------------------------------------------
|
|
|
|
|
2013-05-20 05:28:56 +00:00
|
|
|
-- | Finding 'Cradle'.
|
2013-09-20 06:53:51 +00:00
|
|
|
-- Find a cabal file by tracing ancestor directories.
|
|
|
|
-- Find a sandbox according to a cabal sandbox config
|
|
|
|
-- in a cabal directory.
|
2013-09-20 06:48:50 +00:00
|
|
|
findCradle :: IO Cradle
|
2014-07-17 08:16:44 +00:00
|
|
|
findCradle = findCradle' =<< getCurrentDirectory
|
2014-05-18 01:32:09 +00:00
|
|
|
|
|
|
|
findCradle' :: FilePath -> IO Cradle
|
2015-03-03 20:12:43 +00:00
|
|
|
findCradle' dir = run $ do
|
2015-03-03 11:18:54 +00:00
|
|
|
(customCradle dir `mplus` cabalCradle dir `mplus` sandboxCradle dir `mplus` plainCradle dir)
|
2015-03-03 20:12:43 +00:00
|
|
|
where run a = fillTempDir =<< (fromJust <$> runMaybeT a)
|
|
|
|
|
|
|
|
findSpecCradle :: FilePath -> IO Cradle
|
|
|
|
findSpecCradle dir = do
|
|
|
|
let cfs = [cabalCradle, sandboxCradle]
|
|
|
|
cs <- catMaybes <$> mapM (runMaybeT . ($ dir)) cfs
|
|
|
|
gcs <- filterM isNotGmCradle cs
|
|
|
|
fillTempDir =<< case gcs of
|
|
|
|
[] -> fromJust <$> runMaybeT (plainCradle dir)
|
|
|
|
c:_ -> return c
|
|
|
|
where
|
|
|
|
isNotGmCradle :: Cradle -> IO Bool
|
|
|
|
isNotGmCradle crdl = do
|
|
|
|
not <$> doesFileExist (cradleRootDir crdl </> "ghc-mod.cabal")
|
2014-03-30 08:28:57 +00:00
|
|
|
|
2014-10-14 17:52:58 +00:00
|
|
|
cleanupCradle :: Cradle -> IO ()
|
|
|
|
cleanupCradle crdl = removeDirectoryRecursive $ cradleTempDir crdl
|
|
|
|
|
2015-03-03 20:12:43 +00:00
|
|
|
fillTempDir :: MonadIO m => Cradle -> m Cradle
|
|
|
|
fillTempDir crdl = do
|
|
|
|
tmpDir <- liftIO $ newTempDir (cradleRootDir crdl)
|
|
|
|
return crdl { cradleTempDir = tmpDir }
|
|
|
|
|
2015-03-03 11:18:54 +00:00
|
|
|
customCradle :: FilePath -> MaybeT IO Cradle
|
|
|
|
customCradle wdir = do
|
|
|
|
cabalFile <- MaybeT $ findCabalFile wdir
|
|
|
|
let cabalDir = takeDirectory cabalFile
|
|
|
|
cradleFile <- MaybeT $ findCradleFile cabalDir
|
|
|
|
pkgDbStack <- liftIO $ parseCradle cradleFile
|
|
|
|
return Cradle {
|
|
|
|
cradleCurrentDir = wdir
|
|
|
|
, cradleRootDir = cabalDir
|
2015-06-01 09:58:31 +00:00
|
|
|
, cradleTempDir = error "tmpDir"
|
2015-03-03 11:18:54 +00:00
|
|
|
, cradleCabalFile = Just cabalFile
|
|
|
|
, cradlePkgDbStack = pkgDbStack
|
|
|
|
}
|
|
|
|
|
2015-03-03 20:12:43 +00:00
|
|
|
cabalCradle :: FilePath -> MaybeT IO Cradle
|
2014-03-30 08:28:57 +00:00
|
|
|
cabalCradle wdir = do
|
2015-03-03 20:12:43 +00:00
|
|
|
cabalFile <- MaybeT $ findCabalFile wdir
|
|
|
|
|
2014-11-01 21:02:47 +00:00
|
|
|
let cabalDir = takeDirectory cabalFile
|
2015-03-03 20:12:43 +00:00
|
|
|
pkgDbStack <- liftIO $ getPackageDbStack cabalDir
|
|
|
|
|
2014-03-30 08:28:57 +00:00
|
|
|
return Cradle {
|
2014-03-28 03:05:11 +00:00
|
|
|
cradleCurrentDir = wdir
|
2014-11-01 21:02:47 +00:00
|
|
|
, cradleRootDir = cabalDir
|
2015-03-03 20:12:43 +00:00
|
|
|
, cradleTempDir = error "tmpDir"
|
2014-11-01 21:02:47 +00:00
|
|
|
, cradleCabalFile = Just cabalFile
|
2014-04-15 03:13:10 +00:00
|
|
|
, cradlePkgDbStack = pkgDbStack
|
2013-09-20 06:48:50 +00:00
|
|
|
}
|
|
|
|
|
2015-03-03 20:12:43 +00:00
|
|
|
sandboxCradle :: FilePath -> MaybeT IO Cradle
|
2014-03-30 08:28:57 +00:00
|
|
|
sandboxCradle wdir = do
|
2015-03-03 20:12:43 +00:00
|
|
|
sbDir <- MaybeT $ findCabalSandboxDir wdir
|
|
|
|
pkgDbStack <- liftIO $ getPackageDbStack sbDir
|
2013-09-20 06:48:50 +00:00
|
|
|
return Cradle {
|
2014-03-28 03:05:11 +00:00
|
|
|
cradleCurrentDir = wdir
|
2014-11-01 21:02:47 +00:00
|
|
|
, cradleRootDir = sbDir
|
2015-03-03 20:12:43 +00:00
|
|
|
, cradleTempDir = error "tmpDir"
|
2014-03-30 08:28:57 +00:00
|
|
|
, cradleCabalFile = Nothing
|
2014-04-15 03:13:10 +00:00
|
|
|
, cradlePkgDbStack = pkgDbStack
|
2013-09-20 06:48:50 +00:00
|
|
|
}
|
2013-03-02 03:18:55 +00:00
|
|
|
|
2015-03-03 20:12:43 +00:00
|
|
|
plainCradle :: FilePath -> MaybeT IO Cradle
|
2014-10-14 17:52:58 +00:00
|
|
|
plainCradle wdir = do
|
2015-03-03 20:12:43 +00:00
|
|
|
return $ Cradle {
|
2014-03-30 08:28:57 +00:00
|
|
|
cradleCurrentDir = wdir
|
|
|
|
, cradleRootDir = wdir
|
2015-03-03 20:12:43 +00:00
|
|
|
, cradleTempDir = error "tmpDir"
|
2014-03-30 08:28:57 +00:00
|
|
|
, cradleCabalFile = Nothing
|
2014-08-20 06:31:26 +00:00
|
|
|
, cradlePkgDbStack = [GlobalDb, UserDb]
|
2014-03-30 08:28:57 +00:00
|
|
|
}
|
|
|
|
|
2015-03-03 20:12:43 +00:00
|
|
|
getPackageDbStack :: FilePath -- ^ Project Directory (where the
|
|
|
|
-- cabal.sandbox.config file would be if it
|
|
|
|
-- exists)
|
|
|
|
-> IO [GhcPkgDb]
|
|
|
|
getPackageDbStack cdir =
|
|
|
|
([GlobalDb] ++) . maybe [UserDb] return <$> getSandboxDb cdir
|
2015-03-03 11:18:54 +00:00
|
|
|
|
|
|
|
parseCradle :: FilePath -> IO [GhcPkgDb]
|
|
|
|
parseCradle path = do
|
|
|
|
source <- readFile path
|
|
|
|
return $ parseCradle' source
|
|
|
|
where
|
|
|
|
parseCradle' source = map parsePkgDb $ filter (not . null) $ lines source
|
|
|
|
|
|
|
|
parsePkgDb "global" = GlobalDb
|
|
|
|
parsePkgDb "user" = UserDb
|
|
|
|
parsePkgDb s = PackageDb s
|