diff --git a/Language/Haskell/GhcMod/CabalHelper.hs b/Language/Haskell/GhcMod/CabalHelper.hs index ef6f501..f01a769 100644 --- a/Language/Haskell/GhcMod/CabalHelper.hs +++ b/Language/Haskell/GhcMod/CabalHelper.hs @@ -20,6 +20,7 @@ module Language.Haskell.GhcMod.CabalHelper ( getComponents , getGhcMergedPkgOptions , getCabalPackageDbStack + , getStackPackageDbStack , getCustomPkgDbStack , prepareCabalHelper ) @@ -43,6 +44,7 @@ import Language.Haskell.GhcMod.PathsAndFiles import Language.Haskell.GhcMod.Logging import Language.Haskell.GhcMod.Output import System.FilePath +import System.Directory (findExecutable) import Prelude hiding ((.)) import Paths_ghc_mod as GhcMod @@ -132,6 +134,16 @@ getCustomPkgDbStack = do mCusPkgDbFile <- liftIO . (traverse readFile <=< findCustomPackageDbFile) . cradleRootDir =<< cradle return $ parseCustomPackageDb <$> mCusPkgDbFile +getStackPackageDbStack :: IOish m => m [GhcPkgDb] +getStackPackageDbStack = do + mstack <- liftIO $ findExecutable "stack" + case mstack of + Nothing -> return [] + Just stack -> do + snapshotDb <- liftIO $ readProcess stack ["path", "--snapshot-pkg-db"] "" + localDb <- liftIO $ readProcess stack ["path", "--local-pkg-db"] "" + return $ map (PackageDb . takeWhile (/='\n')) [snapshotDb, localDb] + withCabal :: (IOish m, GmEnv m, GmLog m) => m a -> m a withCabal action = do crdl <- cradle diff --git a/Language/Haskell/GhcMod/Cradle.hs b/Language/Haskell/GhcMod/Cradle.hs index 78e041d..19f17c9 100644 --- a/Language/Haskell/GhcMod/Cradle.hs +++ b/Language/Haskell/GhcMod/Cradle.hs @@ -29,7 +29,7 @@ findCradle = findCradle' =<< getCurrentDirectory findCradle' :: FilePath -> IO Cradle findCradle' dir = run $ do - (cabalCradle dir `mplus` sandboxCradle dir `mplus` plainCradle dir) + (stackCradle dir `mplus` cabalCradle dir `mplus` sandboxCradle dir `mplus` plainCradle dir) where run a = fillTempDir =<< (fromJust <$> runMaybeT a) findSpecCradle :: FilePath -> IO Cradle @@ -67,6 +67,22 @@ cabalCradle wdir = do , cradleCabalFile = Just cabalFile } +stackCradle :: FilePath -> MaybeT IO Cradle +stackCradle wdir = do + cabalFile <- MaybeT $ findCabalFile wdir + + let cabalDir = takeDirectory cabalFile + + stackConfigFile <- MaybeT $ findStackConfigFile cabalDir + + return Cradle { + cradleProjectType = StackProject + , cradleCurrentDir = wdir + , cradleRootDir = cabalDir + , cradleTempDir = error "tmpDir" + , cradleCabalFile = Just cabalFile + } + sandboxCradle :: FilePath -> MaybeT IO Cradle sandboxCradle wdir = do sbDir <- MaybeT $ findCabalSandboxDir wdir diff --git a/Language/Haskell/GhcMod/GhcPkg.hs b/Language/Haskell/GhcMod/GhcPkg.hs index f6c281b..86255fc 100644 --- a/Language/Haskell/GhcMod/GhcPkg.hs +++ b/Language/Haskell/GhcMod/GhcPkg.hs @@ -71,6 +71,8 @@ getPackageDbStack = do return $ [GlobalDb, db] CabalProject -> getCabalPackageDbStack + StackProject -> + getStackPackageDbStack return $ fromMaybe stack mCusPkgStack getPackageCachePaths :: IOish m => FilePath -> GhcModT m [FilePath] diff --git a/Language/Haskell/GhcMod/PathsAndFiles.hs b/Language/Haskell/GhcMod/PathsAndFiles.hs index 085cf52..7f9249d 100644 --- a/Language/Haskell/GhcMod/PathsAndFiles.hs +++ b/Language/Haskell/GhcMod/PathsAndFiles.hs @@ -71,6 +71,9 @@ findCabalFile dir = do appendDir :: DirPath -> [FileName] -> [FilePath] appendDir d fs = (d ) `map` fs +findStackConfigFile :: FilePath -> IO (Maybe FilePath) +findStackConfigFile dir = mightExist (dir "stack.yaml") + -- | Get path to sandbox config file getSandboxDb :: FilePath -- ^ Path to the cabal package root directory (containing the diff --git a/Language/Haskell/GhcMod/Target.hs b/Language/Haskell/GhcMod/Target.hs index 3429818..eb92204 100644 --- a/Language/Haskell/GhcMod/Target.hs +++ b/Language/Haskell/GhcMod/Target.hs @@ -149,6 +149,7 @@ targetGhcOptions crdl sefnmn = do case cradleProjectType crdl of CabalProject -> cabalOpts crdl + StackProject -> stackOpts crdl _ -> sandboxOpts crdl where zipMap f l = l `zip` (f `map` l) @@ -264,8 +265,17 @@ packageGhcOptions = do crdl <- cradle case cradleProjectType crdl of CabalProject -> getGhcMergedPkgOptions + StackProject -> stackOpts crdl _ -> sandboxOpts crdl +stackOpts :: MonadIO m => Cradle -> m [String] +stackOpts crdl = do + pkgDbStack <- liftIO getStackPackageDbStack + let pkgOpts = ghcDbStackOpts pkgDbStack + return $ ["-i" ++ d | d <- [wdir,rdir]] ++ pkgOpts ++ ["-Wall"] + where + (wdir, rdir) = (cradleCurrentDir crdl, cradleRootDir crdl) + -- also works for plain projects! sandboxOpts :: MonadIO m => Cradle -> m [String] sandboxOpts crdl = do diff --git a/Language/Haskell/GhcMod/Types.hs b/Language/Haskell/GhcMod/Types.hs index b632b2a..b3c99ea 100644 --- a/Language/Haskell/GhcMod/Types.hs +++ b/Language/Haskell/GhcMod/Types.hs @@ -121,7 +121,7 @@ defaultOptions = Options { ---------------------------------------------------------------- -data ProjectType = CabalProject | SandboxProject | PlainProject +data ProjectType = CabalProject | SandboxProject | PlainProject | StackProject deriving (Eq, Show) -- | The environment where this library is used.