1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980 |
- {-# LANGUAGE OverloadedStrings, RecordWildCards #-}
- module Cabal (initializeGHC, getDirs, fromCabal) where
- import CabalApi (cabalParseFile, cabalBuildInfo, cabalDependPackages)
- import Control.Applicative
- import Control.Exception
- import Control.Monad
- import CoreMonad
- import Data.List
- import Distribution.PackageDescription (BuildInfo(..), usedExtensions)
- import Distribution.Text (display)
- import ErrMsg
- import GHC
- import GHCApi
- import GHCChoice
- import System.Directory
- import System.FilePath
- import Types
- ----------------------------------------------------------------
- importDirs :: [String]
- importDirs = [".","..","../..","../../..","../../../..","../../../../.."]
- initializeGHC :: Options -> FilePath -> [String] -> Bool -> Ghc (FilePath,LogReader)
- initializeGHC opt fileName ghcOptions logging = withCabal ||> withoutCabal
- where
- withoutCabal = do
- logReader <- initSession opt ghcOptions importDirs Nothing logging
- return (fileName,logReader)
- withCabal = do
- (gopts,idirs,depPkgs) <- liftIO $ fromCabal ghcOptions
- logReader <- initSession opt gopts idirs (Just depPkgs) logging
- return (fileName,logReader)
- fromCabal :: [String] -> IO ([String], [FilePath], [String])
- fromCabal ghcOptions = do
- (owdir,cdir,cfile) <- getDirs
- cabal <- cabalParseFile cfile
- binfo@BuildInfo{..} <- cabalBuildInfo cabal
- let exts = map (("-X" ++) . display) $ usedExtensions binfo
- lang = maybe "-XHaskell98" (("-X" ++) . display) defaultLanguage
- libs = map ("-l" ++) extraLibs
- libDirs = map ("-L" ++) extraLibDirs
- gopts = ghcOptions ++ exts ++ [lang] ++ libs ++ libDirs
- idirs = case hsSourceDirs of
- [] -> [cdir,owdir]
- dirs -> map (cdir </>) dirs ++ [owdir]
- depPkgs <- removeMe cfile <$> cabalDependPackages cabal
- return (gopts,idirs,depPkgs)
- removeMe :: FilePath -> [String] -> [String]
- removeMe cabalfile depPkgs = filter (/= me) depPkgs
- where
- me = dropExtension $ takeFileName cabalfile
- ----------------------------------------------------------------
- -- CurrentWorkingDir, CabalDir, CabalFile
- getDirs :: IO (FilePath,FilePath,FilePath)
- getDirs = do
- wdir <- getCurrentDirectory
- (cdir,cfile) <- cabalDir wdir
- return (wdir,cdir,cfile)
- -- Causes error, catched in the upper function.
- -- CabalDir, CabalFile
- cabalDir :: FilePath -> IO (FilePath,FilePath)
- cabalDir dir = do
- cnts <- (filter isCabal <$> getDirectoryContents dir)
- >>= filterM (\file -> doesFileExist (dir </> file))
- let dir' = takeDirectory dir
- case cnts of
- [] | dir' == dir -> throwIO $ userError "No cabal file"
- | otherwise -> cabalDir dir'
- cfile:_ -> return (dir,dir </> cfile)
- where
- isCabal name = ".cabal" `isSuffixOf` name && length name > 6
|