cabal-dev-0.7.4.1: src/Distribution/Dev/InvokeCabal.hs
{-# LANGUAGE CPP #-}
module Distribution.Dev.InvokeCabal
( actions
, setup
, extraArgs
, cabalArgs
)
where
import Distribution.Verbosity ( Verbosity, showForCabal )
import Distribution.Simple.Program ( Program( programFindLocation )
, ConfiguredProgram
, emptyProgramConfiguration
, locationPath
, programLocation
, requireProgram
, runProgram
, simpleProgram
)
import Distribution.Simple.Utils ( withUTF8FileContents, writeUTF8File
, debug, cabalVersion )
import Distribution.Version ( Version(..) )
import System.Console.GetOpt ( OptDescr )
import Distribution.Dev.Command ( CommandActions(..)
, CommandResult(..)
)
import Distribution.Dev.Flags ( Config, getCabalConfig
, getVerbosity
)
import Distribution.Dev.InitPkgDb ( initPkgDb )
import qualified Distribution.Dev.RewriteCabalConfig as R
import qualified Distribution.Dev.CabalInstall as CI
import Distribution.Dev.Sandbox ( resolveSandbox
, cabalConf
, Sandbox
, KnownVersion
, PackageDbType(..)
, getVersion
, pkgConf
, sandbox
)
import Distribution.Dev.Utilities ( ensureAbsolute )
actions :: String -> CommandActions
actions act = CommandActions
{ cmdDesc = "Invoke cabal-install with the development configuration"
, cmdRun = \flgs _ args -> invokeCabal flgs (act:args)
, cmdOpts = [] :: [OptDescr ()]
, cmdPassFlags = True
}
invokeCabal :: Config -> [String] -> IO CommandResult
invokeCabal flgs args = do
let v = getVerbosity flgs
s <- initPkgDb v =<< resolveSandbox flgs
cabal <- CI.findOnPath v
res <- setup s cabal flgs
case res of
Left err -> return $ CommandError err
Right args' -> do
runProgram v cabal $ args' ++ args
return CommandOk
cabalArgs :: ConfiguredProgram -> Config -> IO (Either String [String])
cabalArgs cabal flgs = do
let v = getVerbosity flgs
s <- initPkgDb v =<< resolveSandbox flgs
setup s cabal flgs
setup :: Sandbox KnownVersion -> ConfiguredProgram -> Config ->
IO (Either String [String])
setup s cabal flgs = do
let v = getVerbosity flgs
cfgIn <- getCabalConfig flgs
cVer <- CI.getFeatures v cabal
let cfgOut = cabalConf s
case cVer of
Left err -> return $ Left err
Right features -> do
cabalHome <- CI.configDir features
let rew = R.Rewrite cabalHome (sandbox s) (pkgConf s) (CI.needsQuotes features)
withUTF8FileContents cfgIn $ \cIn ->
do cfgRes <- R.rewriteCabalConfig rew cIn
case cfgRes of
Left err -> return $ Left $
"Error processing cabal config file " ++ cfgIn ++ ": " ++ err
Right cOut -> do
writeUTF8File cfgOut cOut
args <- extraArgs v cfgOut (getVersion s)
return $ Right args
extraArgs :: Verbosity -> FilePath -> PackageDbType -> IO [String]
extraArgs v cfg pdb =
do pdbArgs <- getPdbArgs
return $ [cfgFileArg, verbosityArg] ++ pdbArgs
where
longArg s = showString "--" . showString s . ('=':)
cfgFileArg = longArg "config-file" cfg
verbosityArg = longArg "verbose" $ showForCabal v
withGhcPkg = longArg "with-ghc-pkg"
getPdbArgs =
case pdb of
(GHC_6_8_Db loc) | needsGHC68Compat -> do
-- Make Cabal call the wrapper that removes the
-- bad argument to ghc-pkg 6.8
debug v $ "Using GHC 6.8 compatibility wrapper for Cabal shortcoming"
(ghcPkgCompat, _) <-
requireProgram v ghcPkgCompatProgram emptyProgramConfiguration
return $ [ longArg "ghc-pkg-options" $ withGhcPkg loc
, withGhcPkg $ locationPath $
programLocation ghcPkgCompat
]
_ -> return []
-- XXX: this is very imprecise. Right now, we require a specific
-- version of Cabal, so this is ok (and is equivalent to True). Note
-- that this is the version of Cabal that THIS PROGRAM is being built
-- against, rather than the version that CABAL-INSTALL was built
-- against.
needsGHC68Compat :: Bool
needsGHC68Compat = cabalVersion < Version [1, 9] []
ghcPkgCompatProgram :: Program
ghcPkgCompatProgram = p { programFindLocation =
\v -> do
res <- programFindLocation p v
case res of
Nothing -> return Nothing
Just loc -> Just `fmap` ensureAbsolute loc
}
where
p = simpleProgram "ghc-pkg-6_8-compat"