{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE DeriveGeneric #-}
module Neovim.BuildTool
where
import Neovim
import Data.List (isSuffixOf)
import Control.Monad.IO.Class
import GHC.Generics
import Data.Yaml
import System.Directory
import System.FilePath (takeDirectory, (</>))
data BuildTool
= Stack
| Cabal CabalType
| Shake
| Make
| Cmake
| Ninja
| Scons
| Custom
deriving (Int -> BuildTool -> ShowS
[BuildTool] -> ShowS
BuildTool -> String
(Int -> BuildTool -> ShowS)
-> (BuildTool -> String)
-> ([BuildTool] -> ShowS)
-> Show BuildTool
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [BuildTool] -> ShowS
$cshowList :: [BuildTool] -> ShowS
show :: BuildTool -> String
$cshow :: BuildTool -> String
showsPrec :: Int -> BuildTool -> ShowS
$cshowsPrec :: Int -> BuildTool -> ShowS
Show, ReadPrec [BuildTool]
ReadPrec BuildTool
Int -> ReadS BuildTool
ReadS [BuildTool]
(Int -> ReadS BuildTool)
-> ReadS [BuildTool]
-> ReadPrec BuildTool
-> ReadPrec [BuildTool]
-> Read BuildTool
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [BuildTool]
$creadListPrec :: ReadPrec [BuildTool]
readPrec :: ReadPrec BuildTool
$creadPrec :: ReadPrec BuildTool
readList :: ReadS [BuildTool]
$creadList :: ReadS [BuildTool]
readsPrec :: Int -> ReadS BuildTool
$creadsPrec :: Int -> ReadS BuildTool
Read, BuildTool -> BuildTool -> Bool
(BuildTool -> BuildTool -> Bool)
-> (BuildTool -> BuildTool -> Bool) -> Eq BuildTool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: BuildTool -> BuildTool -> Bool
$c/= :: BuildTool -> BuildTool -> Bool
== :: BuildTool -> BuildTool -> Bool
$c== :: BuildTool -> BuildTool -> Bool
Eq, Eq BuildTool
Eq BuildTool
-> (BuildTool -> BuildTool -> Ordering)
-> (BuildTool -> BuildTool -> Bool)
-> (BuildTool -> BuildTool -> Bool)
-> (BuildTool -> BuildTool -> Bool)
-> (BuildTool -> BuildTool -> Bool)
-> (BuildTool -> BuildTool -> BuildTool)
-> (BuildTool -> BuildTool -> BuildTool)
-> Ord BuildTool
BuildTool -> BuildTool -> Bool
BuildTool -> BuildTool -> Ordering
BuildTool -> BuildTool -> BuildTool
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: BuildTool -> BuildTool -> BuildTool
$cmin :: BuildTool -> BuildTool -> BuildTool
max :: BuildTool -> BuildTool -> BuildTool
$cmax :: BuildTool -> BuildTool -> BuildTool
>= :: BuildTool -> BuildTool -> Bool
$c>= :: BuildTool -> BuildTool -> Bool
> :: BuildTool -> BuildTool -> Bool
$c> :: BuildTool -> BuildTool -> Bool
<= :: BuildTool -> BuildTool -> Bool
$c<= :: BuildTool -> BuildTool -> Bool
< :: BuildTool -> BuildTool -> Bool
$c< :: BuildTool -> BuildTool -> Bool
compare :: BuildTool -> BuildTool -> Ordering
$ccompare :: BuildTool -> BuildTool -> Ordering
$cp1Ord :: Eq BuildTool
Ord, (forall x. BuildTool -> Rep BuildTool x)
-> (forall x. Rep BuildTool x -> BuildTool) -> Generic BuildTool
forall x. Rep BuildTool x -> BuildTool
forall x. BuildTool -> Rep BuildTool x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep BuildTool x -> BuildTool
$cfrom :: forall x. BuildTool -> Rep BuildTool x
Generic)
instance ToJSON BuildTool
instance FromJSON BuildTool
data CabalType
= Plain
| Sandbox
| NewBuild
deriving (Int -> CabalType -> ShowS
[CabalType] -> ShowS
CabalType -> String
(Int -> CabalType -> ShowS)
-> (CabalType -> String)
-> ([CabalType] -> ShowS)
-> Show CabalType
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [CabalType] -> ShowS
$cshowList :: [CabalType] -> ShowS
show :: CabalType -> String
$cshow :: CabalType -> String
showsPrec :: Int -> CabalType -> ShowS
$cshowsPrec :: Int -> CabalType -> ShowS
Show, ReadPrec [CabalType]
ReadPrec CabalType
Int -> ReadS CabalType
ReadS [CabalType]
(Int -> ReadS CabalType)
-> ReadS [CabalType]
-> ReadPrec CabalType
-> ReadPrec [CabalType]
-> Read CabalType
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [CabalType]
$creadListPrec :: ReadPrec [CabalType]
readPrec :: ReadPrec CabalType
$creadPrec :: ReadPrec CabalType
readList :: ReadS [CabalType]
$creadList :: ReadS [CabalType]
readsPrec :: Int -> ReadS CabalType
$creadsPrec :: Int -> ReadS CabalType
Read, CabalType -> CabalType -> Bool
(CabalType -> CabalType -> Bool)
-> (CabalType -> CabalType -> Bool) -> Eq CabalType
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: CabalType -> CabalType -> Bool
$c/= :: CabalType -> CabalType -> Bool
== :: CabalType -> CabalType -> Bool
$c== :: CabalType -> CabalType -> Bool
Eq, Eq CabalType
Eq CabalType
-> (CabalType -> CabalType -> Ordering)
-> (CabalType -> CabalType -> Bool)
-> (CabalType -> CabalType -> Bool)
-> (CabalType -> CabalType -> Bool)
-> (CabalType -> CabalType -> Bool)
-> (CabalType -> CabalType -> CabalType)
-> (CabalType -> CabalType -> CabalType)
-> Ord CabalType
CabalType -> CabalType -> Bool
CabalType -> CabalType -> Ordering
CabalType -> CabalType -> CabalType
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: CabalType -> CabalType -> CabalType
$cmin :: CabalType -> CabalType -> CabalType
max :: CabalType -> CabalType -> CabalType
$cmax :: CabalType -> CabalType -> CabalType
>= :: CabalType -> CabalType -> Bool
$c>= :: CabalType -> CabalType -> Bool
> :: CabalType -> CabalType -> Bool
$c> :: CabalType -> CabalType -> Bool
<= :: CabalType -> CabalType -> Bool
$c<= :: CabalType -> CabalType -> Bool
< :: CabalType -> CabalType -> Bool
$c< :: CabalType -> CabalType -> Bool
compare :: CabalType -> CabalType -> Ordering
$ccompare :: CabalType -> CabalType -> Ordering
$cp1Ord :: Eq CabalType
Ord, Int -> CabalType
CabalType -> Int
CabalType -> [CabalType]
CabalType -> CabalType
CabalType -> CabalType -> [CabalType]
CabalType -> CabalType -> CabalType -> [CabalType]
(CabalType -> CabalType)
-> (CabalType -> CabalType)
-> (Int -> CabalType)
-> (CabalType -> Int)
-> (CabalType -> [CabalType])
-> (CabalType -> CabalType -> [CabalType])
-> (CabalType -> CabalType -> [CabalType])
-> (CabalType -> CabalType -> CabalType -> [CabalType])
-> Enum CabalType
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: CabalType -> CabalType -> CabalType -> [CabalType]
$cenumFromThenTo :: CabalType -> CabalType -> CabalType -> [CabalType]
enumFromTo :: CabalType -> CabalType -> [CabalType]
$cenumFromTo :: CabalType -> CabalType -> [CabalType]
enumFromThen :: CabalType -> CabalType -> [CabalType]
$cenumFromThen :: CabalType -> CabalType -> [CabalType]
enumFrom :: CabalType -> [CabalType]
$cenumFrom :: CabalType -> [CabalType]
fromEnum :: CabalType -> Int
$cfromEnum :: CabalType -> Int
toEnum :: Int -> CabalType
$ctoEnum :: Int -> CabalType
pred :: CabalType -> CabalType
$cpred :: CabalType -> CabalType
succ :: CabalType -> CabalType
$csucc :: CabalType -> CabalType
Enum, (forall x. CabalType -> Rep CabalType x)
-> (forall x. Rep CabalType x -> CabalType) -> Generic CabalType
forall x. Rep CabalType x -> CabalType
forall x. CabalType -> Rep CabalType x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep CabalType x -> CabalType
$cfrom :: forall x. CabalType -> Rep CabalType x
Generic)
instance ToJSON CabalType
instance FromJSON CabalType
newtype Directory = Directory { Directory -> String
getDirectory :: FilePath }
deriving (Int -> Directory -> ShowS
[Directory] -> ShowS
Directory -> String
(Int -> Directory -> ShowS)
-> (Directory -> String)
-> ([Directory] -> ShowS)
-> Show Directory
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Directory] -> ShowS
$cshowList :: [Directory] -> ShowS
show :: Directory -> String
$cshow :: Directory -> String
showsPrec :: Int -> Directory -> ShowS
$cshowsPrec :: Int -> Directory -> ShowS
Show, Directory -> Directory -> Bool
(Directory -> Directory -> Bool)
-> (Directory -> Directory -> Bool) -> Eq Directory
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Directory -> Directory -> Bool
$c/= :: Directory -> Directory -> Bool
== :: Directory -> Directory -> Bool
$c== :: Directory -> Directory -> Bool
Eq, Eq Directory
Eq Directory
-> (Directory -> Directory -> Ordering)
-> (Directory -> Directory -> Bool)
-> (Directory -> Directory -> Bool)
-> (Directory -> Directory -> Bool)
-> (Directory -> Directory -> Bool)
-> (Directory -> Directory -> Directory)
-> (Directory -> Directory -> Directory)
-> Ord Directory
Directory -> Directory -> Bool
Directory -> Directory -> Ordering
Directory -> Directory -> Directory
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Directory -> Directory -> Directory
$cmin :: Directory -> Directory -> Directory
max :: Directory -> Directory -> Directory
$cmax :: Directory -> Directory -> Directory
>= :: Directory -> Directory -> Bool
$c>= :: Directory -> Directory -> Bool
> :: Directory -> Directory -> Bool
$c> :: Directory -> Directory -> Bool
<= :: Directory -> Directory -> Bool
$c<= :: Directory -> Directory -> Bool
< :: Directory -> Directory -> Bool
$c< :: Directory -> Directory -> Bool
compare :: Directory -> Directory -> Ordering
$ccompare :: Directory -> Directory -> Ordering
$cp1Ord :: Eq Directory
Ord)
partialM :: Monad m => (a -> m Bool) -> a -> m (Maybe a)
partialM :: (a -> m Bool) -> a -> m (Maybe a)
partialM a -> m Bool
fp a
a = a -> m Bool
fp a
a m Bool -> (Bool -> m (Maybe a)) -> m (Maybe a)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Bool
True -> Maybe a -> m (Maybe a)
forall (m :: * -> *) a. Monad m => a -> m a
return (a -> Maybe a
forall a. a -> Maybe a
Just a
a)
Bool
False -> Maybe a -> m (Maybe a)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe a
forall a. Maybe a
Nothing
mkDirectory :: MonadIO io => FilePath -> io (Maybe Directory)
mkDirectory :: String -> io (Maybe Directory)
mkDirectory String
mdir =
(String -> Directory) -> Maybe String -> Maybe Directory
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap String -> Directory
Directory (Maybe String -> Maybe Directory)
-> io (Maybe String) -> io (Maybe Directory)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (String -> io Bool) -> String -> io (Maybe String)
forall (m :: * -> *) a.
Monad m =>
(a -> m Bool) -> a -> m (Maybe a)
partialM (IO Bool -> io Bool
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Bool -> io Bool) -> (String -> IO Bool) -> String -> io Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> IO Bool
doesDirectoryExist) String
mdir
newtype File = File { File -> String
getFile :: FilePath }
deriving (Int -> File -> ShowS
[File] -> ShowS
File -> String
(Int -> File -> ShowS)
-> (File -> String) -> ([File] -> ShowS) -> Show File
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [File] -> ShowS
$cshowList :: [File] -> ShowS
show :: File -> String
$cshow :: File -> String
showsPrec :: Int -> File -> ShowS
$cshowsPrec :: Int -> File -> ShowS
Show, File -> File -> Bool
(File -> File -> Bool) -> (File -> File -> Bool) -> Eq File
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: File -> File -> Bool
$c/= :: File -> File -> Bool
== :: File -> File -> Bool
$c== :: File -> File -> Bool
Eq, Eq File
Eq File
-> (File -> File -> Ordering)
-> (File -> File -> Bool)
-> (File -> File -> Bool)
-> (File -> File -> Bool)
-> (File -> File -> Bool)
-> (File -> File -> File)
-> (File -> File -> File)
-> Ord File
File -> File -> Bool
File -> File -> Ordering
File -> File -> File
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: File -> File -> File
$cmin :: File -> File -> File
max :: File -> File -> File
$cmax :: File -> File -> File
>= :: File -> File -> Bool
$c>= :: File -> File -> Bool
> :: File -> File -> Bool
$c> :: File -> File -> Bool
<= :: File -> File -> Bool
$c<= :: File -> File -> Bool
< :: File -> File -> Bool
$c< :: File -> File -> Bool
compare :: File -> File -> Ordering
$ccompare :: File -> File -> Ordering
$cp1Ord :: Eq File
Ord)
mkFile :: MonadIO io => Maybe Directory -> FilePath -> io (Maybe File)
mkFile :: Maybe Directory -> String -> io (Maybe File)
mkFile Maybe Directory
mdir String
mfile =
let f :: String
f = String -> (Directory -> String) -> Maybe Directory -> String
forall b a. b -> (a -> b) -> Maybe a -> b
maybe String
mfile (\Directory
d -> Directory -> String
getDirectory Directory
d String -> ShowS
</> String
mfile) Maybe Directory
mdir
in (String -> File) -> Maybe String -> Maybe File
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap String -> File
File (Maybe String -> Maybe File)
-> io (Maybe String) -> io (Maybe File)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (String -> io Bool) -> String -> io (Maybe String)
forall (m :: * -> *) a.
Monad m =>
(a -> m Bool) -> a -> m (Maybe a)
partialM (IO Bool -> io Bool
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Bool -> io Bool) -> (String -> IO Bool) -> String -> io Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> IO Bool
doesFileExist) String
f
thisAndParentDirectories :: Directory -> [Directory]
thisAndParentDirectories :: Directory -> [Directory]
thisAndParentDirectories Directory
dir
| Directory
parentDir Directory -> Directory -> Bool
forall a. Eq a => a -> a -> Bool
== Directory
dir = [Directory
dir]
| Bool
otherwise = Directory
dir Directory -> [Directory] -> [Directory]
forall a. a -> [a] -> [a]
: Directory -> [Directory]
thisAndParentDirectories Directory
parentDir
where
parentDir :: Directory
parentDir = String -> Directory
Directory (String -> Directory) -> ShowS -> String -> Directory
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ShowS
takeDirectory (String -> Directory) -> String -> Directory
forall a b. (a -> b) -> a -> b
$ Directory -> String
getDirectory Directory
dir
determineProjectSettings
:: MonadIO io
=> [Directory -> io (Maybe BuildTool)]
-> [Directory]
-> io (Maybe (BuildTool, Directory))
determineProjectSettings :: [Directory -> io (Maybe BuildTool)]
-> [Directory] -> io (Maybe (BuildTool, Directory))
determineProjectSettings [Directory -> io (Maybe BuildTool)]
identifiers = [Directory -> io (Maybe BuildTool)]
-> [Directory] -> io (Maybe (BuildTool, Directory))
go [Directory -> io (Maybe BuildTool)]
identifiers
where
go :: [Directory -> io (Maybe BuildTool)]
-> [Directory] -> io (Maybe (BuildTool, Directory))
go [Directory -> io (Maybe BuildTool)]
_ [] = Maybe (BuildTool, Directory) -> io (Maybe (BuildTool, Directory))
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (BuildTool, Directory)
forall a. Maybe a
Nothing
go [] (Directory
_:[Directory]
ps) = [Directory -> io (Maybe BuildTool)]
-> [Directory] -> io (Maybe (BuildTool, Directory))
go [Directory -> io (Maybe BuildTool)]
identifiers [Directory]
ps
go (Directory -> io (Maybe BuildTool)
i:[Directory -> io (Maybe BuildTool)]
is) pps :: [Directory]
pps@(Directory
p:[Directory]
_) = Directory -> io (Maybe BuildTool)
i Directory
p io (Maybe BuildTool)
-> (Maybe BuildTool -> io (Maybe (BuildTool, Directory)))
-> io (Maybe (BuildTool, Directory))
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Just BuildTool
buildTool -> Maybe (BuildTool, Directory) -> io (Maybe (BuildTool, Directory))
forall (m :: * -> *) a. Monad m => a -> m a
return ((BuildTool, Directory) -> Maybe (BuildTool, Directory)
forall a. a -> Maybe a
Just (BuildTool
buildTool, Directory
p))
Maybe BuildTool
Nothing -> [Directory -> io (Maybe BuildTool)]
-> [Directory] -> io (Maybe (BuildTool, Directory))
go [Directory -> io (Maybe BuildTool)]
is [Directory]
pps
defaultProjectIdentifiers :: MonadIO io => [Directory -> io (Maybe BuildTool)]
defaultProjectIdentifiers :: [Directory -> io (Maybe BuildTool)]
defaultProjectIdentifiers =
[ Directory -> io (Maybe BuildTool)
forall (io :: * -> *).
MonadIO io =>
Directory -> io (Maybe BuildTool)
maybeCabalSandbox, Directory -> io (Maybe BuildTool)
forall (io :: * -> *).
MonadIO io =>
Directory -> io (Maybe BuildTool)
maybeStack, Directory -> io (Maybe BuildTool)
forall (io :: * -> *).
MonadIO io =>
Directory -> io (Maybe BuildTool)
maybeCabal ]
guessProjectSettings :: MonadIO io
=> [Directory]
-> io (Maybe (BuildTool, Directory))
guessProjectSettings :: [Directory] -> io (Maybe (BuildTool, Directory))
guessProjectSettings = [Directory -> io (Maybe BuildTool)]
-> [Directory] -> io (Maybe (BuildTool, Directory))
forall (io :: * -> *).
MonadIO io =>
[Directory -> io (Maybe BuildTool)]
-> [Directory] -> io (Maybe (BuildTool, Directory))
determineProjectSettings [Directory -> io (Maybe BuildTool)]
forall (io :: * -> *).
MonadIO io =>
[Directory -> io (Maybe BuildTool)]
defaultProjectIdentifiers
maybeStack :: MonadIO io => Directory -> io (Maybe BuildTool)
maybeStack :: Directory -> io (Maybe BuildTool)
maybeStack Directory
d = (File -> BuildTool) -> Maybe File -> Maybe BuildTool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (BuildTool -> File -> BuildTool
forall a b. a -> b -> a
const BuildTool
Stack) (Maybe File -> Maybe BuildTool)
-> io (Maybe File) -> io (Maybe BuildTool)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Directory -> String -> io (Maybe File)
forall (io :: * -> *).
MonadIO io =>
Maybe Directory -> String -> io (Maybe File)
mkFile (Directory -> Maybe Directory
forall a. a -> Maybe a
Just Directory
d) String
"stack.yaml"
maybeCabalSandbox :: MonadIO io => Directory -> io (Maybe BuildTool)
maybeCabalSandbox :: Directory -> io (Maybe BuildTool)
maybeCabalSandbox Directory
d = (File -> BuildTool) -> Maybe File -> Maybe BuildTool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (BuildTool -> File -> BuildTool
forall a b. a -> b -> a
const (CabalType -> BuildTool
Cabal CabalType
Sandbox))
(Maybe File -> Maybe BuildTool)
-> io (Maybe File) -> io (Maybe BuildTool)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Directory -> String -> io (Maybe File)
forall (io :: * -> *).
MonadIO io =>
Maybe Directory -> String -> io (Maybe File)
mkFile (Directory -> Maybe Directory
forall a. a -> Maybe a
Just Directory
d) String
"cabal.sandbox.config"
maybeCabal :: MonadIO io => Directory -> io (Maybe BuildTool)
maybeCabal :: Directory -> io (Maybe BuildTool)
maybeCabal Directory
d = do
[String]
ls <- IO [String] -> io [String]
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO [String] -> io [String])
-> (String -> IO [String]) -> String -> io [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> IO [String]
getDirectoryContents (String -> io [String]) -> String -> io [String]
forall a b. (a -> b) -> a -> b
$ Directory -> String
getDirectory Directory
d
[String] -> io (Maybe BuildTool)
forall (m :: * -> *). MonadIO m => [String] -> m (Maybe BuildTool)
go ([String] -> io (Maybe BuildTool))
-> [String] -> io (Maybe BuildTool)
forall a b. (a -> b) -> a -> b
$ (String -> Bool) -> [String] -> [String]
forall a. (a -> Bool) -> [a] -> [a]
filter (String
".cabal" String -> String -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`isSuffixOf`)[String]
ls
where
go :: [String] -> m (Maybe BuildTool)
go [] = Maybe BuildTool -> m (Maybe BuildTool)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe BuildTool
forall a. Maybe a
Nothing
go (String
f:[String]
fs) = Maybe Directory -> String -> m (Maybe File)
forall (io :: * -> *).
MonadIO io =>
Maybe Directory -> String -> io (Maybe File)
mkFile (Directory -> Maybe Directory
forall a. a -> Maybe a
Just Directory
d) String
f m (Maybe File)
-> (Maybe File -> m (Maybe BuildTool)) -> m (Maybe BuildTool)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Maybe File
Nothing -> [String] -> m (Maybe BuildTool)
go [String]
fs
Just File
_ ->
Maybe BuildTool -> m (Maybe BuildTool)
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe BuildTool -> m (Maybe BuildTool))
-> Maybe BuildTool -> m (Maybe BuildTool)
forall a b. (a -> b) -> a -> b
$ BuildTool -> Maybe BuildTool
forall a. a -> Maybe a
Just (CabalType -> BuildTool
Cabal CabalType
Plain)