extract Extensions: and Default-Language: from a Cabal file.

This commit is contained in:
Kazu Yamamoto 2012-02-14 18:25:21 +09:00
parent 1f4f7d768a
commit 13013445e3
2 changed files with 51 additions and 41 deletions

View File

@ -3,15 +3,18 @@
module Cabal (initializeGHC) where module Cabal (initializeGHC) where
import Control.Applicative import Control.Applicative
import Control.Exception
import Control.Monad import Control.Monad
import CoreMonad import CoreMonad
import Data.List import Data.List
import Data.Maybe
import Distribution.PackageDescription import Distribution.PackageDescription
import Distribution.PackageDescription.Parse (readPackageDescription) import Distribution.PackageDescription.Parse (readPackageDescription)
import Distribution.Verbosity (silent) import Distribution.Verbosity (silent)
import ErrMsg import ErrMsg
import GHC import GHC
import GHCApi import GHCApi
import Language.Haskell.Extension
import System.Directory import System.Directory
import System.FilePath import System.FilePath
import Types import Types
@ -22,38 +25,47 @@ importDirs :: [String]
importDirs = [".","..","../..","../../..","../../../..","../../../../.."] importDirs = [".","..","../..","../../..","../../../..","../../../../.."]
initializeGHC :: Options -> FilePath -> [String] -> Bool -> Ghc (FilePath,LogReader) initializeGHC :: Options -> FilePath -> [String] -> Bool -> Ghc (FilePath,LogReader)
initializeGHC opt fileName ghcOptions logging = do initializeGHC opt fileName ghcOptions logging =
(owdir,mdirfile) <- liftIO getDirs withCabal `gcatch` withoutCabal
case mdirfile of where
Nothing -> do withoutCabal :: SomeException -> Ghc (FilePath,LogReader)
withoutCabal _ = do
logReader <- initSession opt ghcOptions importDirs logging logReader <- initSession opt ghcOptions importDirs logging
return (fileName,logReader) return (fileName,logReader)
Just (cdir,cfile) -> do withCabal = do
midirs <- parseCabalFile cfile (owdir,cdir,cfile) <- liftIO getDirs
binfo <- parseCabalFile cfile
let (idirs',exts',mlang) = extractBuildInfo binfo
exts = map addX exts'
lang = maybe "-XHaskell98" addX mlang
gopts = ghcOptions ++ exts ++ [lang]
changeToCabalDirectory cdir changeToCabalDirectory cdir
let idirs = case midirs of let idirs = case idirs' of
[] -> [cdir,owdir] [] -> [cdir,owdir]
dirs -> dirs ++ [owdir] dirs -> dirs ++ [owdir]
file = ajustFileName fileName owdir cdir file = ajustFileName fileName owdir cdir
logReader <- initSession opt ghcOptions idirs logging logReader <- initSession opt gopts idirs logging
return (file,logReader) return (file,logReader)
addX x = "-X" ++ show x
---------------------------------------------------------------- ----------------------------------------------------------------
parseCabalFile :: FilePath -> Ghc [String] -- Causes error, catched in the upper function.
parseCabalFile :: FilePath -> Ghc BuildInfo
parseCabalFile file = do parseCabalFile file = do
cabal <- liftIO $ readPackageDescription silent file cabal <- liftIO $ readPackageDescription silent file
return $ fromLibrary cabal ||| fromExecutable cabal return . fromJust $ fromLibrary cabal >> fromExecutable cabal
where where
[] ||| y = y fromLibrary c = libBuildInfo . condTreeData <$> condLibrary c
x ||| _ = x fromExecutable c = buildInfo . condTreeData . snd <$> toMaybe (condExecutables c)
fromLibrary c = case condLibrary c of toMaybe [] = Nothing
Nothing -> [] toMaybe (x:_) = Just x
Just lib -> libHsSourceDir lib
libHsSourceDir = hsSourceDirs . libBuildInfo . condTreeData -- SourceDirs, Extensions, and Language
fromExecutable = execHsSrouceDir . condExecutables extractBuildInfo :: BuildInfo -> ([String],[Extension],Maybe Language)
execHsSrouceDir [] = [] extractBuildInfo binfo = (hsSourceDirs binfo
execHsSrouceDir (x:_) = hsSourceDirs . buildInfo . condTreeData . snd $ x ,oldExtensions binfo
,defaultLanguage binfo)
---------------------------------------------------------------- ----------------------------------------------------------------
@ -70,25 +82,23 @@ changeToCabalDirectory dir = do
liftIO $ setCurrentDirectory dir liftIO $ setCurrentDirectory dir
workingDirectoryChanged workingDirectoryChanged
getDirs :: IO (FilePath, Maybe (FilePath,FilePath)) -- CurrentWorkingDir, CabalDir, CabalFile
getDirs :: IO (FilePath,FilePath,FilePath)
getDirs = do getDirs = do
wdir <- getCurrentDirectory wdir <- getCurrentDirectory
mcabdir <- cabalDir wdir (cdir,cfile) <- cabalDir wdir
case mcabdir of return (wdir,cdir,cfile)
Nothing -> return (wdir,Nothing)
jdf -> return (wdir,jdf)
cabalDir :: FilePath -> IO (Maybe (FilePath,FilePath)) -- Causes error, catched in the upper function.
-- CabalDir, CabalFile
cabalDir :: FilePath -> IO (FilePath,FilePath)
cabalDir dir = do cabalDir dir = do
cnts <- (filter isCabal <$> getDirectoryContents dir) cnts <- (filter isCabal <$> getDirectoryContents dir)
>>= filterM (\file -> doesFileExist (dir </> file)) >>= filterM (\file -> doesFileExist (dir </> file))
case cnts of
[] -> do
let dir' = takeDirectory dir let dir' = takeDirectory dir
if dir' == dir case cnts of
then return Nothing [] | dir' == dir -> throwIO $ userError "No cabal file"
else cabalDir dir' | otherwise -> cabalDir dir'
cfile:_ -> return (Just (dir,dir </> cfile)) cfile:_ -> return (dir,dir </> cfile)
where where
isCabal name = ".cabal" `isSuffixOf` name isCabal name = ".cabal" `isSuffixOf` name && length name > 6
&& length name > 6

View File

@ -25,4 +25,4 @@ check opt fileName = withGHC $ checkIt `gcatch` handleErrMsg
setTargetFile file setTargetFile file
load LoadAllTargets load LoadAllTargets
liftIO readLog liftIO readLog
options = ["-Wall","-fno-warn-unused-do-bind", "-XHaskell98"] ++ ghcOpts opt options = ["-Wall","-fno-warn-unused-do-bind"] ++ ghcOpts opt