{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE RankNTypes #-}
module Distribution.Simple.Program.Db
(
ProgramDb (..)
, emptyProgramDb
, defaultProgramDb
, restoreProgramDb
, addKnownProgram
, addKnownPrograms
, prependProgramSearchPath
, prependProgramSearchPathNoLogging
, lookupKnownProgram
, knownPrograms
, getProgramSearchPath
, setProgramSearchPath
, modifyProgramSearchPath
, userSpecifyPath
, userSpecifyPaths
, userMaybeSpecifyPath
, userSpecifyArgs
, userSpecifyArgss
, userSpecifiedArgs
, lookupProgram
, lookupProgramByName
, updateProgram
, configuredPrograms
, configureProgram
, configureUnconfiguredProgram
, configureAllKnownPrograms
, unconfigureProgram
, lookupProgramVersion
, reconfigurePrograms
, requireProgram
, requireProgramVersion
, needProgram
, UnconfiguredProgs
, ConfiguredProgs
, updateUnconfiguredProgs
, updateConfiguredProgs
) where
import Distribution.Compat.Prelude
import Prelude ()
import Distribution.Simple.Program.Builtin
import Distribution.Simple.Program.Find
import Distribution.Simple.Program.Types
import Distribution.Simple.Utils
import Distribution.Utils.Structured (Structure (..), Structured (..))
import Distribution.Verbosity
import Distribution.Version
import Data.Tuple (swap)
import qualified Data.Map as Map
import Distribution.Simple.Errors
data ProgramDb = ProgramDb
{ ProgramDb -> UnconfiguredProgs
unconfiguredProgs :: UnconfiguredProgs
, ProgramDb -> ProgramSearchPath
progSearchPath :: ProgramSearchPath
, ProgramDb -> [([Char], Maybe [Char])]
progOverrideEnv :: [(String, Maybe String)]
, ProgramDb -> ConfiguredProgs
configuredProgs :: ConfiguredProgs
}
type UnconfiguredProgram = (Program, Maybe FilePath, [ProgArg])
type UnconfiguredProgs = Map.Map String UnconfiguredProgram
type ConfiguredProgs = Map.Map String ConfiguredProgram
emptyProgramDb :: ProgramDb
emptyProgramDb :: ProgramDb
emptyProgramDb = UnconfiguredProgs
-> ProgramSearchPath
-> [([Char], Maybe [Char])]
-> ConfiguredProgs
-> ProgramDb
ProgramDb UnconfiguredProgs
forall k a. Map k a
Map.empty ProgramSearchPath
defaultProgramSearchPath [] ConfiguredProgs
forall k a. Map k a
Map.empty
defaultProgramDb :: ProgramDb
defaultProgramDb :: ProgramDb
defaultProgramDb = [Program] -> ProgramDb -> ProgramDb
restoreProgramDb [Program]
builtinPrograms ProgramDb
emptyProgramDb
updateUnconfiguredProgs
:: (UnconfiguredProgs -> UnconfiguredProgs)
-> ProgramDb
-> ProgramDb
updateUnconfiguredProgs :: (UnconfiguredProgs -> UnconfiguredProgs) -> ProgramDb -> ProgramDb
updateUnconfiguredProgs UnconfiguredProgs -> UnconfiguredProgs
update ProgramDb
progdb =
ProgramDb
progdb{unconfiguredProgs = update (unconfiguredProgs progdb)}
updateConfiguredProgs
:: (ConfiguredProgs -> ConfiguredProgs)
-> ProgramDb
-> ProgramDb
updateConfiguredProgs :: (ConfiguredProgs -> ConfiguredProgs) -> ProgramDb -> ProgramDb
updateConfiguredProgs ConfiguredProgs -> ConfiguredProgs
update ProgramDb
progdb =
ProgramDb
progdb{configuredProgs = update (configuredProgs progdb)}
instance Show ProgramDb where
show :: ProgramDb -> [Char]
show = [([Char], ConfiguredProgram)] -> [Char]
forall a. Show a => a -> [Char]
show ([([Char], ConfiguredProgram)] -> [Char])
-> (ProgramDb -> [([Char], ConfiguredProgram)])
-> ProgramDb
-> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ConfiguredProgs -> [([Char], ConfiguredProgram)]
forall k a. Map k a -> [(k, a)]
Map.toAscList (ConfiguredProgs -> [([Char], ConfiguredProgram)])
-> (ProgramDb -> ConfiguredProgs)
-> ProgramDb
-> [([Char], ConfiguredProgram)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ProgramDb -> ConfiguredProgs
configuredProgs
instance Read ProgramDb where
readsPrec :: Int -> ReadS ProgramDb
readsPrec Int
p [Char]
s =
[ (ProgramDb
emptyProgramDb{configuredProgs = Map.fromList s'}, [Char]
r)
| ([([Char], ConfiguredProgram)]
s', [Char]
r) <- Int -> ReadS [([Char], ConfiguredProgram)]
forall a. Read a => Int -> ReadS a
readsPrec Int
p [Char]
s
]
instance Binary ProgramDb where
put :: ProgramDb -> Put
put ProgramDb
db = do
ProgramSearchPath -> Put
forall t. Binary t => t -> Put
put (ProgramDb -> ProgramSearchPath
progSearchPath ProgramDb
db)
[([Char], Maybe [Char])] -> Put
forall t. Binary t => t -> Put
put (ProgramDb -> [([Char], Maybe [Char])]
progOverrideEnv ProgramDb
db)
ConfiguredProgs -> Put
forall t. Binary t => t -> Put
put (ProgramDb -> ConfiguredProgs
configuredProgs ProgramDb
db)
get :: Get ProgramDb
get = do
searchpath <- Get ProgramSearchPath
forall t. Binary t => Get t
get
overrides <- get
progs <- get
return $!
emptyProgramDb
{ progSearchPath = searchpath
, progOverrideEnv = overrides
, configuredProgs = progs
}
instance Structured ProgramDb where
structure :: Proxy ProgramDb -> Structure
structure Proxy ProgramDb
p =
TypeRep -> Word32 -> [Char] -> [Structure] -> Structure
Nominal
(Proxy ProgramDb -> TypeRep
forall {k} (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> TypeRep
typeRep Proxy ProgramDb
p)
Word32
0
[Char]
"ProgramDb"
[ Proxy ProgramSearchPath -> Structure
forall a. Structured a => Proxy a -> Structure
structure (Proxy ProgramSearchPath
forall {k} (t :: k). Proxy t
Proxy :: Proxy ProgramSearchPath)
, Proxy [([Char], Maybe [Char])] -> Structure
forall a. Structured a => Proxy a -> Structure
structure (Proxy [([Char], Maybe [Char])]
forall {k} (t :: k). Proxy t
Proxy :: Proxy [(String, Maybe String)])
, Proxy ConfiguredProgs -> Structure
forall a. Structured a => Proxy a -> Structure
structure (Proxy ConfiguredProgs
forall {k} (t :: k). Proxy t
Proxy :: Proxy ConfiguredProgs)
]
restoreProgramDb :: [Program] -> ProgramDb -> ProgramDb
restoreProgramDb :: [Program] -> ProgramDb -> ProgramDb
restoreProgramDb = [Program] -> ProgramDb -> ProgramDb
addKnownPrograms
addKnownProgram :: Program -> ProgramDb -> ProgramDb
addKnownProgram :: Program -> ProgramDb -> ProgramDb
addKnownProgram Program
prog =
(UnconfiguredProgs -> UnconfiguredProgs) -> ProgramDb -> ProgramDb
updateUnconfiguredProgs ((UnconfiguredProgs -> UnconfiguredProgs)
-> ProgramDb -> ProgramDb)
-> (UnconfiguredProgs -> UnconfiguredProgs)
-> ProgramDb
-> ProgramDb
forall a b. (a -> b) -> a -> b
$
(UnconfiguredProgram -> UnconfiguredProgram -> UnconfiguredProgram)
-> [Char]
-> UnconfiguredProgram
-> UnconfiguredProgs
-> UnconfiguredProgs
forall k a. Ord k => (a -> a -> a) -> k -> a -> Map k a -> Map k a
Map.insertWith UnconfiguredProgram -> UnconfiguredProgram -> UnconfiguredProgram
forall {p} {a} {b} {c}. p -> (a, b, c) -> (Program, b, c)
combine (Program -> [Char]
programName Program
prog) (Program
prog, Maybe [Char]
forall a. Maybe a
Nothing, [])
where
combine :: p -> (a, b, c) -> (Program, b, c)
combine p
_ (a
_, b
path, c
args) = (Program
prog, b
path, c
args)
addKnownPrograms :: [Program] -> ProgramDb -> ProgramDb
addKnownPrograms :: [Program] -> ProgramDb -> ProgramDb
addKnownPrograms [Program]
progs ProgramDb
progdb = (ProgramDb -> Program -> ProgramDb)
-> ProgramDb -> [Program] -> ProgramDb
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' ((Program -> ProgramDb -> ProgramDb)
-> ProgramDb -> Program -> ProgramDb
forall a b c. (a -> b -> c) -> b -> a -> c
flip Program -> ProgramDb -> ProgramDb
addKnownProgram) ProgramDb
progdb [Program]
progs
lookupKnownProgram :: String -> ProgramDb -> Maybe Program
lookupKnownProgram :: [Char] -> ProgramDb -> Maybe Program
lookupKnownProgram [Char]
name =
(UnconfiguredProgram -> Program)
-> Maybe UnconfiguredProgram -> Maybe Program
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\(Program
p, Maybe [Char]
_, [[Char]]
_) -> Program
p) (Maybe UnconfiguredProgram -> Maybe Program)
-> (ProgramDb -> Maybe UnconfiguredProgram)
-> ProgramDb
-> Maybe Program
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Char] -> UnconfiguredProgs -> Maybe UnconfiguredProgram
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup [Char]
name (UnconfiguredProgs -> Maybe UnconfiguredProgram)
-> (ProgramDb -> UnconfiguredProgs)
-> ProgramDb
-> Maybe UnconfiguredProgram
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ProgramDb -> UnconfiguredProgs
unconfiguredProgs
knownPrograms :: ProgramDb -> [(Program, Maybe ConfiguredProgram)]
knownPrograms :: ProgramDb -> [(Program, Maybe ConfiguredProgram)]
knownPrograms ProgramDb
progdb =
[ (Program
p, Maybe ConfiguredProgram
p') | (Program
p, Maybe [Char]
_, [[Char]]
_) <- UnconfiguredProgs -> [UnconfiguredProgram]
forall k a. Map k a -> [a]
Map.elems (ProgramDb -> UnconfiguredProgs
unconfiguredProgs ProgramDb
progdb), let p' :: Maybe ConfiguredProgram
p' = [Char] -> ConfiguredProgs -> Maybe ConfiguredProgram
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup (Program -> [Char]
programName Program
p) (ProgramDb -> ConfiguredProgs
configuredProgs ProgramDb
progdb)
]
getProgramSearchPath :: ProgramDb -> ProgramSearchPath
getProgramSearchPath :: ProgramDb -> ProgramSearchPath
getProgramSearchPath = ProgramDb -> ProgramSearchPath
progSearchPath
setProgramSearchPath :: ProgramSearchPath -> ProgramDb -> ProgramDb
setProgramSearchPath :: ProgramSearchPath -> ProgramDb -> ProgramDb
setProgramSearchPath ProgramSearchPath
searchpath ProgramDb
db = ProgramDb
db{progSearchPath = searchpath}
modifyProgramSearchPath
:: (ProgramSearchPath -> ProgramSearchPath)
-> ProgramDb
-> ProgramDb
modifyProgramSearchPath :: (ProgramSearchPath -> ProgramSearchPath) -> ProgramDb -> ProgramDb
modifyProgramSearchPath ProgramSearchPath -> ProgramSearchPath
f ProgramDb
db =
ProgramSearchPath -> ProgramDb -> ProgramDb
setProgramSearchPath (ProgramSearchPath -> ProgramSearchPath
f (ProgramSearchPath -> ProgramSearchPath)
-> ProgramSearchPath -> ProgramSearchPath
forall a b. (a -> b) -> a -> b
$ ProgramDb -> ProgramSearchPath
getProgramSearchPath ProgramDb
db) ProgramDb
db
prependProgramSearchPath
:: Verbosity
-> [FilePath]
-> [(String, Maybe FilePath)]
-> ProgramDb
-> IO ProgramDb
prependProgramSearchPath :: Verbosity
-> [[Char]]
-> [([Char], Maybe [Char])]
-> ProgramDb
-> IO ProgramDb
prependProgramSearchPath Verbosity
verbosity [[Char]]
extraPaths [([Char], Maybe [Char])]
extraEnv ProgramDb
db = do
Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless ([[Char]] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [[Char]]
extraPaths) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$
Verbosity -> [[Char]] -> IO ()
logExtraProgramSearchPath Verbosity
verbosity [[Char]]
extraPaths
Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless ([([Char], Maybe [Char])] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [([Char], Maybe [Char])]
extraEnv) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$
Verbosity -> [([Char], Maybe [Char])] -> IO ()
logExtraProgramOverrideEnv Verbosity
verbosity [([Char], Maybe [Char])]
extraEnv
ProgramDb -> IO ProgramDb
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (ProgramDb -> IO ProgramDb) -> ProgramDb -> IO ProgramDb
forall a b. (a -> b) -> a -> b
$ [[Char]] -> [([Char], Maybe [Char])] -> ProgramDb -> ProgramDb
prependProgramSearchPathNoLogging [[Char]]
extraPaths [([Char], Maybe [Char])]
extraEnv ProgramDb
db
prependProgramSearchPathNoLogging
:: [FilePath]
-> [(String, Maybe String)]
-> ProgramDb
-> ProgramDb
prependProgramSearchPathNoLogging :: [[Char]] -> [([Char], Maybe [Char])] -> ProgramDb -> ProgramDb
prependProgramSearchPathNoLogging [[Char]]
extraPaths [([Char], Maybe [Char])]
extraEnv ProgramDb
db =
let db' :: ProgramDb
db' = (ProgramSearchPath -> ProgramSearchPath) -> ProgramDb -> ProgramDb
modifyProgramSearchPath (ProgramSearchPath -> ProgramSearchPath
forall a. Eq a => [a] -> [a]
nub (ProgramSearchPath -> ProgramSearchPath)
-> (ProgramSearchPath -> ProgramSearchPath)
-> ProgramSearchPath
-> ProgramSearchPath
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (([Char] -> ProgramSearchPathEntry) -> [[Char]] -> ProgramSearchPath
forall a b. (a -> b) -> [a] -> [b]
map [Char] -> ProgramSearchPathEntry
ProgramSearchPathDir [[Char]]
extraPaths ProgramSearchPath -> ProgramSearchPath -> ProgramSearchPath
forall a. [a] -> [a] -> [a]
++)) ProgramDb
db
db'' :: ProgramDb
db'' = ProgramDb
db'{progOverrideEnv = extraEnv ++ progOverrideEnv db'}
in ProgramDb
db''
userSpecifyPath
:: String
-> FilePath
-> ProgramDb
-> ProgramDb
userSpecifyPath :: [Char] -> [Char] -> ProgramDb -> ProgramDb
userSpecifyPath [Char]
name [Char]
path = (UnconfiguredProgs -> UnconfiguredProgs) -> ProgramDb -> ProgramDb
updateUnconfiguredProgs ((UnconfiguredProgs -> UnconfiguredProgs)
-> ProgramDb -> ProgramDb)
-> (UnconfiguredProgs -> UnconfiguredProgs)
-> ProgramDb
-> ProgramDb
forall a b. (a -> b) -> a -> b
$
((UnconfiguredProgram -> Maybe UnconfiguredProgram)
-> [Char] -> UnconfiguredProgs -> UnconfiguredProgs)
-> [Char]
-> (UnconfiguredProgram -> Maybe UnconfiguredProgram)
-> UnconfiguredProgs
-> UnconfiguredProgs
forall a b c. (a -> b -> c) -> b -> a -> c
flip (UnconfiguredProgram -> Maybe UnconfiguredProgram)
-> [Char] -> UnconfiguredProgs -> UnconfiguredProgs
forall k a. Ord k => (a -> Maybe a) -> k -> Map k a -> Map k a
Map.update [Char]
name ((UnconfiguredProgram -> Maybe UnconfiguredProgram)
-> UnconfiguredProgs -> UnconfiguredProgs)
-> (UnconfiguredProgram -> Maybe UnconfiguredProgram)
-> UnconfiguredProgs
-> UnconfiguredProgs
forall a b. (a -> b) -> a -> b
$
\(Program
prog, Maybe [Char]
_, [[Char]]
args) -> UnconfiguredProgram -> Maybe UnconfiguredProgram
forall a. a -> Maybe a
Just (Program
prog, [Char] -> Maybe [Char]
forall a. a -> Maybe a
Just [Char]
path, [[Char]]
args)
userMaybeSpecifyPath
:: String
-> Maybe FilePath
-> ProgramDb
-> ProgramDb
userMaybeSpecifyPath :: [Char] -> Maybe [Char] -> ProgramDb -> ProgramDb
userMaybeSpecifyPath [Char]
_ Maybe [Char]
Nothing ProgramDb
progdb = ProgramDb
progdb
userMaybeSpecifyPath [Char]
name (Just [Char]
path) ProgramDb
progdb = [Char] -> [Char] -> ProgramDb -> ProgramDb
userSpecifyPath [Char]
name [Char]
path ProgramDb
progdb
userSpecifyArgs
:: String
-> [ProgArg]
-> ProgramDb
-> ProgramDb
userSpecifyArgs :: [Char] -> [[Char]] -> ProgramDb -> ProgramDb
userSpecifyArgs [Char]
name [[Char]]
args' =
(UnconfiguredProgs -> UnconfiguredProgs) -> ProgramDb -> ProgramDb
updateUnconfiguredProgs
( ((UnconfiguredProgram -> Maybe UnconfiguredProgram)
-> [Char] -> UnconfiguredProgs -> UnconfiguredProgs)
-> [Char]
-> (UnconfiguredProgram -> Maybe UnconfiguredProgram)
-> UnconfiguredProgs
-> UnconfiguredProgs
forall a b c. (a -> b -> c) -> b -> a -> c
flip (UnconfiguredProgram -> Maybe UnconfiguredProgram)
-> [Char] -> UnconfiguredProgs -> UnconfiguredProgs
forall k a. Ord k => (a -> Maybe a) -> k -> Map k a -> Map k a
Map.update [Char]
name ((UnconfiguredProgram -> Maybe UnconfiguredProgram)
-> UnconfiguredProgs -> UnconfiguredProgs)
-> (UnconfiguredProgram -> Maybe UnconfiguredProgram)
-> UnconfiguredProgs
-> UnconfiguredProgs
forall a b. (a -> b) -> a -> b
$
\(Program
prog, Maybe [Char]
path, [[Char]]
args) -> UnconfiguredProgram -> Maybe UnconfiguredProgram
forall a. a -> Maybe a
Just (Program
prog, Maybe [Char]
path, [[Char]]
args [[Char]] -> [[Char]] -> [[Char]]
forall a. [a] -> [a] -> [a]
++ [[Char]]
args')
)
(ProgramDb -> ProgramDb)
-> (ProgramDb -> ProgramDb) -> ProgramDb -> ProgramDb
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ConfiguredProgs -> ConfiguredProgs) -> ProgramDb -> ProgramDb
updateConfiguredProgs
( ((ConfiguredProgram -> Maybe ConfiguredProgram)
-> [Char] -> ConfiguredProgs -> ConfiguredProgs)
-> [Char]
-> (ConfiguredProgram -> Maybe ConfiguredProgram)
-> ConfiguredProgs
-> ConfiguredProgs
forall a b c. (a -> b -> c) -> b -> a -> c
flip (ConfiguredProgram -> Maybe ConfiguredProgram)
-> [Char] -> ConfiguredProgs -> ConfiguredProgs
forall k a. Ord k => (a -> Maybe a) -> k -> Map k a -> Map k a
Map.update [Char]
name ((ConfiguredProgram -> Maybe ConfiguredProgram)
-> ConfiguredProgs -> ConfiguredProgs)
-> (ConfiguredProgram -> Maybe ConfiguredProgram)
-> ConfiguredProgs
-> ConfiguredProgs
forall a b. (a -> b) -> a -> b
$
\ConfiguredProgram
prog ->
ConfiguredProgram -> Maybe ConfiguredProgram
forall a. a -> Maybe a
Just
ConfiguredProgram
prog
{ programOverrideArgs =
programOverrideArgs prog
++ args'
}
)
userSpecifyPaths
:: [(String, FilePath)]
-> ProgramDb
-> ProgramDb
userSpecifyPaths :: [([Char], [Char])] -> ProgramDb -> ProgramDb
userSpecifyPaths [([Char], [Char])]
paths ProgramDb
progdb =
(ProgramDb -> ([Char], [Char]) -> ProgramDb)
-> ProgramDb -> [([Char], [Char])] -> ProgramDb
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (\ProgramDb
progdb' ([Char]
prog, [Char]
path) -> [Char] -> [Char] -> ProgramDb -> ProgramDb
userSpecifyPath [Char]
prog [Char]
path ProgramDb
progdb') ProgramDb
progdb [([Char], [Char])]
paths
userSpecifyArgss
:: [(String, [ProgArg])]
-> ProgramDb
-> ProgramDb
userSpecifyArgss :: [([Char], [[Char]])] -> ProgramDb -> ProgramDb
userSpecifyArgss [([Char], [[Char]])]
argss ProgramDb
progdb =
(ProgramDb -> ([Char], [[Char]]) -> ProgramDb)
-> ProgramDb -> [([Char], [[Char]])] -> ProgramDb
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (\ProgramDb
progdb' ([Char]
prog, [[Char]]
args) -> [Char] -> [[Char]] -> ProgramDb -> ProgramDb
userSpecifyArgs [Char]
prog [[Char]]
args ProgramDb
progdb') ProgramDb
progdb [([Char], [[Char]])]
argss
userSpecifiedPath :: Program -> ProgramDb -> Maybe FilePath
userSpecifiedPath :: Program -> ProgramDb -> Maybe [Char]
userSpecifiedPath Program
prog =
Maybe (Maybe [Char]) -> Maybe [Char]
forall (m :: * -> *) a. Monad m => m (m a) -> m a
join (Maybe (Maybe [Char]) -> Maybe [Char])
-> (ProgramDb -> Maybe (Maybe [Char])) -> ProgramDb -> Maybe [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (UnconfiguredProgram -> Maybe [Char])
-> Maybe UnconfiguredProgram -> Maybe (Maybe [Char])
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\(Program
_, Maybe [Char]
p, [[Char]]
_) -> Maybe [Char]
p) (Maybe UnconfiguredProgram -> Maybe (Maybe [Char]))
-> (ProgramDb -> Maybe UnconfiguredProgram)
-> ProgramDb
-> Maybe (Maybe [Char])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Char] -> UnconfiguredProgs -> Maybe UnconfiguredProgram
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup (Program -> [Char]
programName Program
prog) (UnconfiguredProgs -> Maybe UnconfiguredProgram)
-> (ProgramDb -> UnconfiguredProgs)
-> ProgramDb
-> Maybe UnconfiguredProgram
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ProgramDb -> UnconfiguredProgs
unconfiguredProgs
userSpecifiedArgs :: Program -> ProgramDb -> [ProgArg]
userSpecifiedArgs :: Program -> ProgramDb -> [[Char]]
userSpecifiedArgs Program
prog =
[[Char]]
-> (UnconfiguredProgram -> [[Char]])
-> Maybe UnconfiguredProgram
-> [[Char]]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] (\(Program
_, Maybe [Char]
_, [[Char]]
as) -> [[Char]]
as) (Maybe UnconfiguredProgram -> [[Char]])
-> (ProgramDb -> Maybe UnconfiguredProgram)
-> ProgramDb
-> [[Char]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Char] -> UnconfiguredProgs -> Maybe UnconfiguredProgram
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup (Program -> [Char]
programName Program
prog) (UnconfiguredProgs -> Maybe UnconfiguredProgram)
-> (ProgramDb -> UnconfiguredProgs)
-> ProgramDb
-> Maybe UnconfiguredProgram
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ProgramDb -> UnconfiguredProgs
unconfiguredProgs
lookupProgram :: Program -> ProgramDb -> Maybe ConfiguredProgram
lookupProgram :: Program -> ProgramDb -> Maybe ConfiguredProgram
lookupProgram = [Char] -> ProgramDb -> Maybe ConfiguredProgram
lookupProgramByName ([Char] -> ProgramDb -> Maybe ConfiguredProgram)
-> (Program -> [Char])
-> Program
-> ProgramDb
-> Maybe ConfiguredProgram
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Program -> [Char]
programName
lookupProgramByName :: String -> ProgramDb -> Maybe ConfiguredProgram
lookupProgramByName :: [Char] -> ProgramDb -> Maybe ConfiguredProgram
lookupProgramByName [Char]
name = [Char] -> ConfiguredProgs -> Maybe ConfiguredProgram
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup [Char]
name (ConfiguredProgs -> Maybe ConfiguredProgram)
-> (ProgramDb -> ConfiguredProgs)
-> ProgramDb
-> Maybe ConfiguredProgram
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ProgramDb -> ConfiguredProgs
configuredProgs
updateProgram
:: ConfiguredProgram
-> ProgramDb
-> ProgramDb
updateProgram :: ConfiguredProgram -> ProgramDb -> ProgramDb
updateProgram ConfiguredProgram
prog =
(ConfiguredProgs -> ConfiguredProgs) -> ProgramDb -> ProgramDb
updateConfiguredProgs ((ConfiguredProgs -> ConfiguredProgs) -> ProgramDb -> ProgramDb)
-> (ConfiguredProgs -> ConfiguredProgs) -> ProgramDb -> ProgramDb
forall a b. (a -> b) -> a -> b
$
[Char] -> ConfiguredProgram -> ConfiguredProgs -> ConfiguredProgs
forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert (ConfiguredProgram -> [Char]
programId ConfiguredProgram
prog) ConfiguredProgram
prog
configuredPrograms :: ProgramDb -> [ConfiguredProgram]
configuredPrograms :: ProgramDb -> [ConfiguredProgram]
configuredPrograms = ConfiguredProgs -> [ConfiguredProgram]
forall k a. Map k a -> [a]
Map.elems (ConfiguredProgs -> [ConfiguredProgram])
-> (ProgramDb -> ConfiguredProgs)
-> ProgramDb
-> [ConfiguredProgram]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ProgramDb -> ConfiguredProgs
configuredProgs
configureProgram
:: Verbosity
-> Program
-> ProgramDb
-> IO ProgramDb
configureProgram :: Verbosity -> Program -> ProgramDb -> IO ProgramDb
configureProgram Verbosity
verbosity Program
prog ProgramDb
progdb = do
mbConfiguredProg <- Verbosity -> Program -> ProgramDb -> IO (Maybe ConfiguredProgram)
configureUnconfiguredProgram Verbosity
verbosity Program
prog ProgramDb
progdb
case mbConfiguredProg of
Maybe ConfiguredProgram
Nothing -> ProgramDb -> IO ProgramDb
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ProgramDb
progdb
Just ConfiguredProgram
configuredProg -> do
let progdb' :: ProgramDb
progdb' =
(ConfiguredProgs -> ConfiguredProgs) -> ProgramDb -> ProgramDb
updateConfiguredProgs
([Char] -> ConfiguredProgram -> ConfiguredProgs -> ConfiguredProgs
forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert (Program -> [Char]
programName Program
prog) ConfiguredProgram
configuredProg)
ProgramDb
progdb
ProgramDb -> IO ProgramDb
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ProgramDb
progdb'
configureUnconfiguredProgram
:: Verbosity
-> Program
-> ProgramDb
-> IO (Maybe ConfiguredProgram)
configureUnconfiguredProgram :: Verbosity -> Program -> ProgramDb -> IO (Maybe ConfiguredProgram)
configureUnconfiguredProgram Verbosity
verbosity Program
prog ProgramDb
progdb = do
let name :: [Char]
name = Program -> [Char]
programName Program
prog
maybeLocation <- case Program -> ProgramDb -> Maybe [Char]
userSpecifiedPath Program
prog ProgramDb
progdb of
Maybe [Char]
Nothing ->
Program
-> Verbosity -> ProgramSearchPath -> IO (Maybe ([Char], [[Char]]))
programFindLocation Program
prog Verbosity
verbosity (ProgramDb -> ProgramSearchPath
progSearchPath ProgramDb
progdb)
IO (Maybe ([Char], [[Char]]))
-> (Maybe ([Char], [[Char]])
-> IO (Maybe (ProgramLocation, [[Char]])))
-> IO (Maybe (ProgramLocation, [[Char]]))
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Maybe (ProgramLocation, [[Char]])
-> IO (Maybe (ProgramLocation, [[Char]]))
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe (ProgramLocation, [[Char]])
-> IO (Maybe (ProgramLocation, [[Char]])))
-> (Maybe ([Char], [[Char]]) -> Maybe (ProgramLocation, [[Char]]))
-> Maybe ([Char], [[Char]])
-> IO (Maybe (ProgramLocation, [[Char]]))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (([Char], [[Char]]) -> (ProgramLocation, [[Char]]))
-> Maybe ([Char], [[Char]]) -> Maybe (ProgramLocation, [[Char]])
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (([[Char]], ProgramLocation) -> (ProgramLocation, [[Char]])
forall a b. (a, b) -> (b, a)
swap (([[Char]], ProgramLocation) -> (ProgramLocation, [[Char]]))
-> (([Char], [[Char]]) -> ([[Char]], ProgramLocation))
-> ([Char], [[Char]])
-> (ProgramLocation, [[Char]])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Char] -> ProgramLocation)
-> ([[Char]], [Char]) -> ([[Char]], ProgramLocation)
forall a b. (a -> b) -> ([[Char]], a) -> ([[Char]], b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [Char] -> ProgramLocation
FoundOnSystem (([[Char]], [Char]) -> ([[Char]], ProgramLocation))
-> (([Char], [[Char]]) -> ([[Char]], [Char]))
-> ([Char], [[Char]])
-> ([[Char]], ProgramLocation)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Char], [[Char]]) -> ([[Char]], [Char])
forall a b. (a, b) -> (b, a)
swap)
Just [Char]
path -> do
absolute <- [Char] -> IO Bool
doesExecutableExist [Char]
path
if absolute
then return (Just (UserSpecified path, []))
else
findProgramOnSearchPath verbosity (progSearchPath progdb) path
>>= maybe
(dieWithException verbosity $ ConfigureProgram name path)
(return . Just . swap . fmap UserSpecified . swap)
case maybeLocation of
Maybe (ProgramLocation, [[Char]])
Nothing -> Maybe ConfiguredProgram -> IO (Maybe ConfiguredProgram)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe ConfiguredProgram
forall a. Maybe a
Nothing
Just (ProgramLocation
location, [[Char]]
triedLocations) -> do
version <- Program -> Verbosity -> [Char] -> IO (Maybe Version)
programFindVersion Program
prog Verbosity
verbosity (ProgramLocation -> [Char]
locationPath ProgramLocation
location)
newPath <- programSearchPathAsPATHVar (progSearchPath progdb)
let configuredProg =
ConfiguredProgram
{ programId :: [Char]
programId = [Char]
name
, programVersion :: Maybe Version
programVersion = Maybe Version
version
, programDefaultArgs :: [[Char]]
programDefaultArgs = []
, programOverrideArgs :: [[Char]]
programOverrideArgs = Program -> ProgramDb -> [[Char]]
userSpecifiedArgs Program
prog ProgramDb
progdb
, programOverrideEnv :: [([Char], Maybe [Char])]
programOverrideEnv = [([Char]
"PATH", [Char] -> Maybe [Char]
forall a. a -> Maybe a
Just [Char]
newPath)] [([Char], Maybe [Char])]
-> [([Char], Maybe [Char])] -> [([Char], Maybe [Char])]
forall a. [a] -> [a] -> [a]
++ ProgramDb -> [([Char], Maybe [Char])]
progOverrideEnv ProgramDb
progdb
, programProperties :: Map [Char] [Char]
programProperties = Map [Char] [Char]
forall k a. Map k a
Map.empty
, programLocation :: ProgramLocation
programLocation = ProgramLocation
location
, programMonitorFiles :: [[Char]]
programMonitorFiles = [[Char]]
triedLocations
}
configuredProg' <- programPostConf prog verbosity configuredProg
return $ Just configuredProg'
configurePrograms
:: Verbosity
-> [Program]
-> ProgramDb
-> IO ProgramDb
configurePrograms :: Verbosity -> [Program] -> ProgramDb -> IO ProgramDb
configurePrograms Verbosity
verbosity [Program]
progs ProgramDb
progdb =
(ProgramDb -> Program -> IO ProgramDb)
-> ProgramDb -> [Program] -> IO ProgramDb
forall (t :: * -> *) (m :: * -> *) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m b
foldM ((Program -> ProgramDb -> IO ProgramDb)
-> ProgramDb -> Program -> IO ProgramDb
forall a b c. (a -> b -> c) -> b -> a -> c
flip (Verbosity -> Program -> ProgramDb -> IO ProgramDb
configureProgram Verbosity
verbosity)) ProgramDb
progdb [Program]
progs
unconfigureProgram :: String -> ProgramDb -> ProgramDb
unconfigureProgram :: [Char] -> ProgramDb -> ProgramDb
unconfigureProgram [Char]
progname =
(ConfiguredProgs -> ConfiguredProgs) -> ProgramDb -> ProgramDb
updateConfiguredProgs ((ConfiguredProgs -> ConfiguredProgs) -> ProgramDb -> ProgramDb)
-> (ConfiguredProgs -> ConfiguredProgs) -> ProgramDb -> ProgramDb
forall a b. (a -> b) -> a -> b
$ [Char] -> ConfiguredProgs -> ConfiguredProgs
forall k a. Ord k => k -> Map k a -> Map k a
Map.delete [Char]
progname
configureAllKnownPrograms
:: Verbosity
-> ProgramDb
-> IO ProgramDb
configureAllKnownPrograms :: Verbosity -> ProgramDb -> IO ProgramDb
configureAllKnownPrograms Verbosity
verbosity ProgramDb
progdb =
Verbosity -> [Program] -> ProgramDb -> IO ProgramDb
configurePrograms
Verbosity
verbosity
[Program
prog | (Program
prog, Maybe [Char]
_, [[Char]]
_) <- UnconfiguredProgs -> [UnconfiguredProgram]
forall k a. Map k a -> [a]
Map.elems UnconfiguredProgs
notYetConfigured]
ProgramDb
progdb
where
notYetConfigured :: UnconfiguredProgs
notYetConfigured =
ProgramDb -> UnconfiguredProgs
unconfiguredProgs ProgramDb
progdb
UnconfiguredProgs -> ConfiguredProgs -> UnconfiguredProgs
forall k a b. Ord k => Map k a -> Map k b -> Map k a
`Map.difference` ProgramDb -> ConfiguredProgs
configuredProgs ProgramDb
progdb
reconfigurePrograms
:: Verbosity
-> [(String, FilePath)]
-> [(String, [ProgArg])]
-> ProgramDb
-> IO ProgramDb
reconfigurePrograms :: Verbosity
-> [([Char], [Char])]
-> [([Char], [[Char]])]
-> ProgramDb
-> IO ProgramDb
reconfigurePrograms Verbosity
verbosity [([Char], [Char])]
paths [([Char], [[Char]])]
argss ProgramDb
progdb = do
Verbosity -> [Program] -> ProgramDb -> IO ProgramDb
configurePrograms Verbosity
verbosity [Program]
progs
(ProgramDb -> IO ProgramDb)
-> (ProgramDb -> ProgramDb) -> ProgramDb -> IO ProgramDb
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [([Char], [Char])] -> ProgramDb -> ProgramDb
userSpecifyPaths [([Char], [Char])]
paths
(ProgramDb -> ProgramDb)
-> (ProgramDb -> ProgramDb) -> ProgramDb -> ProgramDb
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [([Char], [[Char]])] -> ProgramDb -> ProgramDb
userSpecifyArgss [([Char], [[Char]])]
argss
(ProgramDb -> IO ProgramDb) -> ProgramDb -> IO ProgramDb
forall a b. (a -> b) -> a -> b
$ ProgramDb
progdb
where
progs :: [Program]
progs = [Maybe Program] -> [Program]
forall a. [Maybe a] -> [a]
catMaybes [[Char] -> ProgramDb -> Maybe Program
lookupKnownProgram [Char]
name ProgramDb
progdb | ([Char]
name, [Char]
_) <- [([Char], [Char])]
paths]
requireProgram
:: Verbosity
-> Program
-> ProgramDb
-> IO (ConfiguredProgram, ProgramDb)
requireProgram :: Verbosity
-> Program -> ProgramDb -> IO (ConfiguredProgram, ProgramDb)
requireProgram Verbosity
verbosity Program
prog ProgramDb
progdb = do
mres <- Verbosity
-> Program
-> ProgramDb
-> IO (Maybe (ConfiguredProgram, ProgramDb))
needProgram Verbosity
verbosity Program
prog ProgramDb
progdb
case mres of
Maybe (ConfiguredProgram, ProgramDb)
Nothing -> Verbosity -> CabalException -> IO (ConfiguredProgram, ProgramDb)
forall a1 a.
(HasCallStack, Show a1, Typeable a1,
Exception (VerboseException a1)) =>
Verbosity -> a1 -> IO a
dieWithException Verbosity
verbosity (CabalException -> IO (ConfiguredProgram, ProgramDb))
-> CabalException -> IO (ConfiguredProgram, ProgramDb)
forall a b. (a -> b) -> a -> b
$ [Char] -> CabalException
RequireProgram (Program -> [Char]
programName Program
prog)
Just (ConfiguredProgram, ProgramDb)
res -> (ConfiguredProgram, ProgramDb) -> IO (ConfiguredProgram, ProgramDb)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (ConfiguredProgram, ProgramDb)
res
needProgram
:: Verbosity
-> Program
-> ProgramDb
-> IO (Maybe (ConfiguredProgram, ProgramDb))
needProgram :: Verbosity
-> Program
-> ProgramDb
-> IO (Maybe (ConfiguredProgram, ProgramDb))
needProgram Verbosity
verbosity Program
prog ProgramDb
progdb = do
progdb' <- case Program -> ProgramDb -> Maybe ConfiguredProgram
lookupProgram Program
prog ProgramDb
progdb of
Maybe ConfiguredProgram
Nothing -> Verbosity -> Program -> ProgramDb -> IO ProgramDb
configureProgram Verbosity
verbosity Program
prog ProgramDb
progdb
Just ConfiguredProgram
_ -> ProgramDb -> IO ProgramDb
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ProgramDb
progdb
case lookupProgram prog progdb' of
Maybe ConfiguredProgram
Nothing -> Maybe (ConfiguredProgram, ProgramDb)
-> IO (Maybe (ConfiguredProgram, ProgramDb))
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (ConfiguredProgram, ProgramDb)
forall a. Maybe a
Nothing
Just ConfiguredProgram
configuredProg -> Maybe (ConfiguredProgram, ProgramDb)
-> IO (Maybe (ConfiguredProgram, ProgramDb))
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ((ConfiguredProgram, ProgramDb)
-> Maybe (ConfiguredProgram, ProgramDb)
forall a. a -> Maybe a
Just (ConfiguredProgram
configuredProg, ProgramDb
progdb'))
lookupProgramVersion
:: Verbosity
-> Program
-> VersionRange
-> ProgramDb
-> IO (Either CabalException (ConfiguredProgram, Version, ProgramDb))
lookupProgramVersion :: Verbosity
-> Program
-> VersionRange
-> ProgramDb
-> IO
(Either CabalException (ConfiguredProgram, Version, ProgramDb))
lookupProgramVersion Verbosity
verbosity Program
prog VersionRange
range ProgramDb
programDb = do
programDb' <- case Program -> ProgramDb -> Maybe ConfiguredProgram
lookupProgram Program
prog ProgramDb
programDb of
Maybe ConfiguredProgram
Nothing -> Verbosity -> Program -> ProgramDb -> IO ProgramDb
configureProgram Verbosity
verbosity Program
prog ProgramDb
programDb
Just ConfiguredProgram
_ -> ProgramDb -> IO ProgramDb
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ProgramDb
programDb
case lookupProgram prog programDb' of
Maybe ConfiguredProgram
Nothing -> Either CabalException (ConfiguredProgram, Version, ProgramDb)
-> IO
(Either CabalException (ConfiguredProgram, Version, ProgramDb))
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Either CabalException (ConfiguredProgram, Version, ProgramDb)
-> IO
(Either CabalException (ConfiguredProgram, Version, ProgramDb)))
-> Either CabalException (ConfiguredProgram, Version, ProgramDb)
-> IO
(Either CabalException (ConfiguredProgram, Version, ProgramDb))
forall a b. (a -> b) -> a -> b
$! CabalException
-> Either CabalException (ConfiguredProgram, Version, ProgramDb)
forall a b. a -> Either a b
Left (CabalException
-> Either CabalException (ConfiguredProgram, Version, ProgramDb))
-> CabalException
-> Either CabalException (ConfiguredProgram, Version, ProgramDb)
forall a b. (a -> b) -> a -> b
$ [Char] -> VersionRange -> CabalException
NoProgramFound (Program -> [Char]
programName Program
prog) VersionRange
range
Just configuredProg :: ConfiguredProgram
configuredProg@ConfiguredProgram{programLocation :: ConfiguredProgram -> ProgramLocation
programLocation = ProgramLocation
location} ->
case ConfiguredProgram -> Maybe Version
programVersion ConfiguredProgram
configuredProg of
Just Version
version
| Version -> VersionRange -> Bool
withinRange Version
version VersionRange
range ->
Either CabalException (ConfiguredProgram, Version, ProgramDb)
-> IO
(Either CabalException (ConfiguredProgram, Version, ProgramDb))
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Either CabalException (ConfiguredProgram, Version, ProgramDb)
-> IO
(Either CabalException (ConfiguredProgram, Version, ProgramDb)))
-> Either CabalException (ConfiguredProgram, Version, ProgramDb)
-> IO
(Either CabalException (ConfiguredProgram, Version, ProgramDb))
forall a b. (a -> b) -> a -> b
$! (ConfiguredProgram, Version, ProgramDb)
-> Either CabalException (ConfiguredProgram, Version, ProgramDb)
forall a b. b -> Either a b
Right (ConfiguredProgram
configuredProg, Version
version, ProgramDb
programDb')
| Bool
otherwise ->
Either CabalException (ConfiguredProgram, Version, ProgramDb)
-> IO
(Either CabalException (ConfiguredProgram, Version, ProgramDb))
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Either CabalException (ConfiguredProgram, Version, ProgramDb)
-> IO
(Either CabalException (ConfiguredProgram, Version, ProgramDb)))
-> Either CabalException (ConfiguredProgram, Version, ProgramDb)
-> IO
(Either CabalException (ConfiguredProgram, Version, ProgramDb))
forall a b. (a -> b) -> a -> b
$! CabalException
-> Either CabalException (ConfiguredProgram, Version, ProgramDb)
forall a b. a -> Either a b
Left (CabalException
-> Either CabalException (ConfiguredProgram, Version, ProgramDb))
-> CabalException
-> Either CabalException (ConfiguredProgram, Version, ProgramDb)
forall a b. (a -> b) -> a -> b
$ [Char] -> Version -> VersionRange -> [Char] -> CabalException
BadVersionDb (Program -> [Char]
programName Program
prog) Version
version VersionRange
range (ProgramLocation -> [Char]
locationPath ProgramLocation
location)
Maybe Version
Nothing ->
Either CabalException (ConfiguredProgram, Version, ProgramDb)
-> IO
(Either CabalException (ConfiguredProgram, Version, ProgramDb))
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Either CabalException (ConfiguredProgram, Version, ProgramDb)
-> IO
(Either CabalException (ConfiguredProgram, Version, ProgramDb)))
-> Either CabalException (ConfiguredProgram, Version, ProgramDb)
-> IO
(Either CabalException (ConfiguredProgram, Version, ProgramDb))
forall a b. (a -> b) -> a -> b
$! CabalException
-> Either CabalException (ConfiguredProgram, Version, ProgramDb)
forall a b. a -> Either a b
Left (CabalException
-> Either CabalException (ConfiguredProgram, Version, ProgramDb))
-> CabalException
-> Either CabalException (ConfiguredProgram, Version, ProgramDb)
forall a b. (a -> b) -> a -> b
$ [Char] -> VersionRange -> [Char] -> CabalException
UnknownVersionDb (Program -> [Char]
programName Program
prog) VersionRange
range (ProgramLocation -> [Char]
locationPath ProgramLocation
location)
requireProgramVersion
:: Verbosity
-> Program
-> VersionRange
-> ProgramDb
-> IO (ConfiguredProgram, Version, ProgramDb)
requireProgramVersion :: Verbosity
-> Program
-> VersionRange
-> ProgramDb
-> IO (ConfiguredProgram, Version, ProgramDb)
requireProgramVersion Verbosity
verbosity Program
prog VersionRange
range ProgramDb
programDb =
IO (IO (ConfiguredProgram, Version, ProgramDb))
-> IO (ConfiguredProgram, Version, ProgramDb)
forall (m :: * -> *) a. Monad m => m (m a) -> m a
join (IO (IO (ConfiguredProgram, Version, ProgramDb))
-> IO (ConfiguredProgram, Version, ProgramDb))
-> IO (IO (ConfiguredProgram, Version, ProgramDb))
-> IO (ConfiguredProgram, Version, ProgramDb)
forall a b. (a -> b) -> a -> b
$
(CabalException -> IO (ConfiguredProgram, Version, ProgramDb))
-> ((ConfiguredProgram, Version, ProgramDb)
-> IO (ConfiguredProgram, Version, ProgramDb))
-> Either CabalException (ConfiguredProgram, Version, ProgramDb)
-> IO (ConfiguredProgram, Version, ProgramDb)
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (Verbosity
-> CabalException -> IO (ConfiguredProgram, Version, ProgramDb)
forall a1 a.
(HasCallStack, Show a1, Typeable a1,
Exception (VerboseException a1)) =>
Verbosity -> a1 -> IO a
dieWithException Verbosity
verbosity) (ConfiguredProgram, Version, ProgramDb)
-> IO (ConfiguredProgram, Version, ProgramDb)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return
(Either CabalException (ConfiguredProgram, Version, ProgramDb)
-> IO (ConfiguredProgram, Version, ProgramDb))
-> IO
(Either CabalException (ConfiguredProgram, Version, ProgramDb))
-> IO (IO (ConfiguredProgram, Version, ProgramDb))
forall a b. (a -> b) -> IO a -> IO b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` Verbosity
-> Program
-> VersionRange
-> ProgramDb
-> IO
(Either CabalException (ConfiguredProgram, Version, ProgramDb))
lookupProgramVersion Verbosity
verbosity Program
prog VersionRange
range ProgramDb
programDb