{-# LANGUAGE OverloadedStrings, TemplateHaskell, TypeApplications, LambdaCase #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}

module HsDev.Project.Types (
	BuildTool(..), Sandbox(..), sandboxType, sandbox,
	Project(..), projectName, projectPath, projectCabal, projectDescription, projectBuildTool, projectPackageDbStack, project,
	ProjectDescription(..), projectVersion, projectLibrary, projectExecutables, projectTests, infos, targetInfos,
	Target(..), TargetInfo(..), targetInfoName, targetBuildInfo, targetInfoMain, targetInfoModules, targetInfo,
	Library(..), libraryModules, libraryBuildInfo,
	Executable(..), executableName, executablePath, executableBuildInfo,
	Test(..), testName, testEnabled, testBuildInfo, testMain,
	Info(..), infoDepends, infoLanguage, infoExtensions, infoGHCOptions, infoSourceDirs, infoOtherModules,
	Extensions(..), extensions, ghcOptions, entity,
	) where

import Control.DeepSeq (NFData(..))
import Control.Lens hiding ((.=), (<.>))
import Data.Aeson
import Data.Maybe
import Data.Monoid hiding ((<>))
import Data.Ord
import Data.Semigroup (Semigroup(..))
import Data.Text (Text)
import qualified Data.Text as T
import qualified Distribution.Text as D (display)
import Language.Haskell.Extension
import System.FilePath
import Text.Format

import System.Directory.Paths
import HsDev.Display
import HsDev.PackageDb.Types
import HsDev.Util

-- | Project build tool
data BuildTool = CabalTool | StackTool deriving (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, 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, 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, Int -> BuildTool
BuildTool -> Int
BuildTool -> [BuildTool]
BuildTool -> BuildTool
BuildTool -> BuildTool -> [BuildTool]
BuildTool -> BuildTool -> BuildTool -> [BuildTool]
(BuildTool -> BuildTool)
-> (BuildTool -> BuildTool)
-> (Int -> BuildTool)
-> (BuildTool -> Int)
-> (BuildTool -> [BuildTool])
-> (BuildTool -> BuildTool -> [BuildTool])
-> (BuildTool -> BuildTool -> [BuildTool])
-> (BuildTool -> BuildTool -> BuildTool -> [BuildTool])
-> Enum BuildTool
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 :: BuildTool -> BuildTool -> BuildTool -> [BuildTool]
$cenumFromThenTo :: BuildTool -> BuildTool -> BuildTool -> [BuildTool]
enumFromTo :: BuildTool -> BuildTool -> [BuildTool]
$cenumFromTo :: BuildTool -> BuildTool -> [BuildTool]
enumFromThen :: BuildTool -> BuildTool -> [BuildTool]
$cenumFromThen :: BuildTool -> BuildTool -> [BuildTool]
enumFrom :: BuildTool -> [BuildTool]
$cenumFrom :: BuildTool -> [BuildTool]
fromEnum :: BuildTool -> Int
$cfromEnum :: BuildTool -> Int
toEnum :: Int -> BuildTool
$ctoEnum :: Int -> BuildTool
pred :: BuildTool -> BuildTool
$cpred :: BuildTool -> BuildTool
succ :: BuildTool -> BuildTool
$csucc :: BuildTool -> BuildTool
Enum, BuildTool
BuildTool -> BuildTool -> Bounded BuildTool
forall a. a -> a -> Bounded a
maxBound :: BuildTool
$cmaxBound :: BuildTool
minBound :: BuildTool
$cminBound :: BuildTool
Bounded)

instance NFData BuildTool where
	rnf :: BuildTool -> ()
rnf BuildTool
CabalTool = ()
	rnf BuildTool
StackTool = ()

instance Display BuildTool where
	display :: BuildTool -> String
display BuildTool
CabalTool = String
"cabal"
	display BuildTool
StackTool = String
"stack"
	displayType :: BuildTool -> String
displayType BuildTool
_ = String
"build-tool"

instance Formattable BuildTool where
	formattable :: BuildTool -> FormatFlags -> Formatted
formattable = String -> FormatFlags -> Formatted
forall a. Formattable a => a -> FormatFlags -> Formatted
formattable (String -> FormatFlags -> Formatted)
-> (BuildTool -> String) -> BuildTool -> FormatFlags -> Formatted
forall b c a. (b -> c) -> (a -> b) -> a -> c
. BuildTool -> String
forall a. Display a => a -> String
display

instance ToJSON BuildTool where
	toJSON :: BuildTool -> Value
toJSON BuildTool
CabalTool = String -> Value
forall a. ToJSON a => a -> Value
toJSON @String String
"cabal"
	toJSON BuildTool
StackTool = String -> Value
forall a. ToJSON a => a -> Value
toJSON @String String
"stack"

instance FromJSON BuildTool where
	parseJSON :: Value -> Parser BuildTool
parseJSON = String -> (Text -> Parser BuildTool) -> Value -> Parser BuildTool
forall a. String -> (Text -> Parser a) -> Value -> Parser a
withText String
"build-tool" ((Text -> Parser BuildTool) -> Value -> Parser BuildTool)
-> (Text -> Parser BuildTool) -> Value -> Parser BuildTool
forall a b. (a -> b) -> a -> b
$ \case
		Text
"cabal" -> BuildTool -> Parser BuildTool
forall (m :: * -> *) a. Monad m => a -> m a
return BuildTool
CabalTool
		Text
"stack" -> BuildTool -> Parser BuildTool
forall (m :: * -> *) a. Monad m => a -> m a
return BuildTool
StackTool
		Text
other -> String -> Parser BuildTool
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Parser BuildTool) -> String -> Parser BuildTool
forall a b. (a -> b) -> a -> b
$ Format
"Can't parse BuildTool, unknown tool: {}" Format -> Text -> String
forall a r. (Hole a, FormatResult r) => Format -> a -> r
~~ Text
other

data Sandbox = Sandbox { Sandbox -> BuildTool
_sandboxType :: BuildTool, Sandbox -> Text
_sandbox :: Path } deriving (Sandbox -> Sandbox -> Bool
(Sandbox -> Sandbox -> Bool)
-> (Sandbox -> Sandbox -> Bool) -> Eq Sandbox
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Sandbox -> Sandbox -> Bool
$c/= :: Sandbox -> Sandbox -> Bool
== :: Sandbox -> Sandbox -> Bool
$c== :: Sandbox -> Sandbox -> Bool
Eq, Eq Sandbox
Eq Sandbox
-> (Sandbox -> Sandbox -> Ordering)
-> (Sandbox -> Sandbox -> Bool)
-> (Sandbox -> Sandbox -> Bool)
-> (Sandbox -> Sandbox -> Bool)
-> (Sandbox -> Sandbox -> Bool)
-> (Sandbox -> Sandbox -> Sandbox)
-> (Sandbox -> Sandbox -> Sandbox)
-> Ord Sandbox
Sandbox -> Sandbox -> Bool
Sandbox -> Sandbox -> Ordering
Sandbox -> Sandbox -> Sandbox
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 :: Sandbox -> Sandbox -> Sandbox
$cmin :: Sandbox -> Sandbox -> Sandbox
max :: Sandbox -> Sandbox -> Sandbox
$cmax :: Sandbox -> Sandbox -> Sandbox
>= :: Sandbox -> Sandbox -> Bool
$c>= :: Sandbox -> Sandbox -> Bool
> :: Sandbox -> Sandbox -> Bool
$c> :: Sandbox -> Sandbox -> Bool
<= :: Sandbox -> Sandbox -> Bool
$c<= :: Sandbox -> Sandbox -> Bool
< :: Sandbox -> Sandbox -> Bool
$c< :: Sandbox -> Sandbox -> Bool
compare :: Sandbox -> Sandbox -> Ordering
$ccompare :: Sandbox -> Sandbox -> Ordering
$cp1Ord :: Eq Sandbox
Ord)

makeLenses ''Sandbox

instance NFData Sandbox where
	rnf :: Sandbox -> ()
rnf (Sandbox BuildTool
t Text
p) = BuildTool -> ()
forall a. NFData a => a -> ()
rnf BuildTool
t () -> () -> ()
`seq` Text -> ()
forall a. NFData a => a -> ()
rnf Text
p

instance Show Sandbox where
	show :: Sandbox -> String
show (Sandbox BuildTool
_ Text
p) = Text -> String
T.unpack Text
p

instance Display Sandbox where
	display :: Sandbox -> String
display (Sandbox BuildTool
_ Text
fpath) = Text -> String
forall a. Display a => a -> String
display Text
fpath
	displayType :: Sandbox -> String
displayType (Sandbox BuildTool
CabalTool Text
_) = String
"cabal-sandbox"
	displayType (Sandbox BuildTool
StackTool Text
_) = String
"stack-work"

instance Formattable Sandbox where
	formattable :: Sandbox -> FormatFlags -> Formatted
formattable = String -> FormatFlags -> Formatted
forall a. Formattable a => a -> FormatFlags -> Formatted
formattable (String -> FormatFlags -> Formatted)
-> (Sandbox -> String) -> Sandbox -> FormatFlags -> Formatted
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Sandbox -> String
forall a. Display a => a -> String
display

instance ToJSON Sandbox where
	toJSON :: Sandbox -> Value
toJSON (Sandbox BuildTool
t Text
p) = [Pair] -> Value
object [Text
"type" Text -> BuildTool -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= BuildTool
t, Text
"path" Text -> Text -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Text
p]

instance FromJSON Sandbox where
	parseJSON :: Value -> Parser Sandbox
parseJSON = String -> (Object -> Parser Sandbox) -> Value -> Parser Sandbox
forall a. String -> (Object -> Parser a) -> Value -> Parser a
withObject String
"sandbox" ((Object -> Parser Sandbox) -> Value -> Parser Sandbox)
-> (Object -> Parser Sandbox) -> Value -> Parser Sandbox
forall a b. (a -> b) -> a -> b
$ \Object
v -> BuildTool -> Text -> Sandbox
Sandbox (BuildTool -> Text -> Sandbox)
-> Parser BuildTool -> Parser (Text -> Sandbox)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
		Object
v Object -> Text -> Parser BuildTool
forall a. FromJSON a => Object -> Text -> Parser a
.:: Text
"type" Parser (Text -> Sandbox) -> Parser Text -> Parser Sandbox
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*>
		Object
v Object -> Text -> Parser Text
forall a. FromJSON a => Object -> Text -> Parser a
.:: Text
"path"

instance Paths Sandbox where
	paths :: (String -> f String) -> Sandbox -> f Sandbox
paths String -> f String
f (Sandbox BuildTool
st Text
p) = BuildTool -> Text -> Sandbox
Sandbox BuildTool
st (Text -> Sandbox) -> f Text -> f Sandbox
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (String -> f String) -> Text -> f Text
forall a. Paths a => Traversal' a String
paths String -> f String
f Text
p

-- | Cabal project
data Project = Project {
	Project -> Text
_projectName :: Text,
	Project -> Text
_projectPath :: Path,
	Project -> Text
_projectCabal :: Path,
	Project -> Maybe ProjectDescription
_projectDescription :: Maybe ProjectDescription,
	Project -> BuildTool
_projectBuildTool :: BuildTool,
	Project -> Maybe PackageDbStack
_projectPackageDbStack :: Maybe PackageDbStack }

instance NFData Project where
	rnf :: Project -> ()
rnf (Project Text
n Text
p Text
c Maybe ProjectDescription
_ BuildTool
t Maybe PackageDbStack
dbs) = Text -> ()
forall a. NFData a => a -> ()
rnf Text
n () -> () -> ()
`seq` Text -> ()
forall a. NFData a => a -> ()
rnf Text
p () -> () -> ()
`seq` Text -> ()
forall a. NFData a => a -> ()
rnf Text
c () -> () -> ()
`seq` BuildTool -> ()
forall a. NFData a => a -> ()
rnf BuildTool
t () -> () -> ()
`seq` Maybe PackageDbStack -> ()
forall a. NFData a => a -> ()
rnf Maybe PackageDbStack
dbs

instance Eq Project where
	Project
l == :: Project -> Project -> Bool
== Project
r = Project -> Text
_projectCabal Project
l Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Project -> Text
_projectCabal Project
r

instance Ord Project where
	compare :: Project -> Project -> Ordering
compare Project
l Project
r = (Text, Text) -> (Text, Text) -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (Project -> Text
_projectName Project
l, Project -> Text
_projectCabal Project
l) (Project -> Text
_projectName Project
r, Project -> Text
_projectCabal Project
r)

instance Show Project where
	show :: Project -> String
show Project
p = FormatFlags -> String
unlines (FormatFlags -> String) -> FormatFlags -> String
forall a b. (a -> b) -> a -> b
$ [
		String
"project " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Project -> Text
_projectName Project
p Text -> Getting String Text String -> String
forall s a. s -> Getting a s a -> a
^. Getting String Text String
Lens' Text String
path,
		String
"\tcabal: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Project -> Text
_projectCabal Project
p Text -> Getting String Text String -> String
forall s a. s -> Getting a s a -> a
^. Getting String Text String
Lens' Text String
path,
		String
"\tdescription:"] FormatFlags -> FormatFlags -> FormatFlags
forall a. [a] -> [a] -> [a]
++ (ProjectDescription -> FormatFlags)
-> [ProjectDescription] -> FormatFlags
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (ShowS -> FormatFlags -> FormatFlags
forall a b. (a -> b) -> [a] -> [b]
map (Int -> ShowS
tab Int
2) (FormatFlags -> FormatFlags)
-> (ProjectDescription -> FormatFlags)
-> ProjectDescription
-> FormatFlags
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> FormatFlags
lines (String -> FormatFlags)
-> (ProjectDescription -> String)
-> ProjectDescription
-> FormatFlags
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ProjectDescription -> String
forall a. Show a => a -> String
show) (Maybe ProjectDescription -> [ProjectDescription]
forall a. Maybe a -> [a]
maybeToList (Maybe ProjectDescription -> [ProjectDescription])
-> Maybe ProjectDescription -> [ProjectDescription]
forall a b. (a -> b) -> a -> b
$ Project -> Maybe ProjectDescription
_projectDescription Project
p)

instance Display Project where
	display :: Project -> String
display = Text -> String
T.unpack (Text -> String) -> (Project -> Text) -> Project -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Project -> Text
_projectName
	displayType :: Project -> String
displayType Project
_ = String
"project"

instance Formattable Project where
	formattable :: Project -> FormatFlags -> Formatted
formattable = String -> FormatFlags -> Formatted
forall a. Formattable a => a -> FormatFlags -> Formatted
formattable (String -> FormatFlags -> Formatted)
-> (Project -> String) -> Project -> FormatFlags -> Formatted
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Project -> String
forall a. Display a => a -> String
display

instance ToJSON Project where
	toJSON :: Project -> Value
toJSON Project
p = [Pair] -> Value
object [
		Text
"name" Text -> Text -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Project -> Text
_projectName Project
p,
		Text
"path" Text -> Text -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Project -> Text
_projectPath Project
p,
		Text
"cabal" Text -> Text -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Project -> Text
_projectCabal Project
p,
		Text
"description" Text -> Maybe ProjectDescription -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Project -> Maybe ProjectDescription
_projectDescription Project
p,
		Text
"build-tool" Text -> BuildTool -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Project -> BuildTool
_projectBuildTool Project
p,
		Text
"package-db-stack" Text -> Maybe PackageDbStack -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Project -> Maybe PackageDbStack
_projectPackageDbStack Project
p]

instance FromJSON Project where
	parseJSON :: Value -> Parser Project
parseJSON = String -> (Object -> Parser Project) -> Value -> Parser Project
forall a. String -> (Object -> Parser a) -> Value -> Parser a
withObject String
"project" ((Object -> Parser Project) -> Value -> Parser Project)
-> (Object -> Parser Project) -> Value -> Parser Project
forall a b. (a -> b) -> a -> b
$ \Object
v -> Text
-> Text
-> Text
-> Maybe ProjectDescription
-> BuildTool
-> Maybe PackageDbStack
-> Project
Project (Text
 -> Text
 -> Text
 -> Maybe ProjectDescription
 -> BuildTool
 -> Maybe PackageDbStack
 -> Project)
-> Parser Text
-> Parser
     (Text
      -> Text
      -> Maybe ProjectDescription
      -> BuildTool
      -> Maybe PackageDbStack
      -> Project)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
		Object
v Object -> Text -> Parser Text
forall a. FromJSON a => Object -> Text -> Parser a
.:: Text
"name" Parser
  (Text
   -> Text
   -> Maybe ProjectDescription
   -> BuildTool
   -> Maybe PackageDbStack
   -> Project)
-> Parser Text
-> Parser
     (Text
      -> Maybe ProjectDescription
      -> BuildTool
      -> Maybe PackageDbStack
      -> Project)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*>
		Object
v Object -> Text -> Parser Text
forall a. FromJSON a => Object -> Text -> Parser a
.:: Text
"path" Parser
  (Text
   -> Maybe ProjectDescription
   -> BuildTool
   -> Maybe PackageDbStack
   -> Project)
-> Parser Text
-> Parser
     (Maybe ProjectDescription
      -> BuildTool -> Maybe PackageDbStack -> Project)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*>
		Object
v Object -> Text -> Parser Text
forall a. FromJSON a => Object -> Text -> Parser a
.:: Text
"cabal" Parser
  (Maybe ProjectDescription
   -> BuildTool -> Maybe PackageDbStack -> Project)
-> Parser (Maybe ProjectDescription)
-> Parser (BuildTool -> Maybe PackageDbStack -> Project)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*>
		Object
v Object -> Text -> Parser (Maybe ProjectDescription)
forall a. FromJSON a => Object -> Text -> Parser a
.:: Text
"description" Parser (BuildTool -> Maybe PackageDbStack -> Project)
-> Parser BuildTool -> Parser (Maybe PackageDbStack -> Project)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*>
		Object
v Object -> Text -> Parser BuildTool
forall a. FromJSON a => Object -> Text -> Parser a
.:: Text
"build-tool" Parser (Maybe PackageDbStack -> Project)
-> Parser (Maybe PackageDbStack) -> Parser Project
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*>
		Object
v Object -> Text -> Parser (Maybe PackageDbStack)
forall a. FromJSON a => Object -> Text -> Parser (Maybe a)
.::? Text
"package-db-stack"

instance Paths Project where
	paths :: (String -> f String) -> Project -> f Project
paths String -> f String
f (Project Text
nm Text
p Text
c Maybe ProjectDescription
desc BuildTool
t Maybe PackageDbStack
dbs) = Text
-> Text
-> Text
-> Maybe ProjectDescription
-> BuildTool
-> Maybe PackageDbStack
-> Project
Project Text
nm (Text
 -> Text
 -> Maybe ProjectDescription
 -> BuildTool
 -> Maybe PackageDbStack
 -> Project)
-> f Text
-> f (Text
      -> Maybe ProjectDescription
      -> BuildTool
      -> Maybe PackageDbStack
      -> Project)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (String -> f String) -> Text -> f Text
forall a. Paths a => Traversal' a String
paths String -> f String
f Text
p f (Text
   -> Maybe ProjectDescription
   -> BuildTool
   -> Maybe PackageDbStack
   -> Project)
-> f Text
-> f (Maybe ProjectDescription
      -> BuildTool -> Maybe PackageDbStack -> Project)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (String -> f String) -> Text -> f Text
forall a. Paths a => Traversal' a String
paths String -> f String
f Text
c f (Maybe ProjectDescription
   -> BuildTool -> Maybe PackageDbStack -> Project)
-> f (Maybe ProjectDescription)
-> f (BuildTool -> Maybe PackageDbStack -> Project)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (ProjectDescription -> f ProjectDescription)
-> Maybe ProjectDescription -> f (Maybe ProjectDescription)
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse ((String -> f String) -> ProjectDescription -> f ProjectDescription
forall a. Paths a => Traversal' a String
paths String -> f String
f) Maybe ProjectDescription
desc f (BuildTool -> Maybe PackageDbStack -> Project)
-> f BuildTool -> f (Maybe PackageDbStack -> Project)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> BuildTool -> f BuildTool
forall (f :: * -> *) a. Applicative f => a -> f a
pure BuildTool
t f (Maybe PackageDbStack -> Project)
-> f (Maybe PackageDbStack) -> f Project
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Maybe PackageDbStack -> f (Maybe PackageDbStack)
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe PackageDbStack
dbs

-- | Make project by .cabal file
project :: FilePath -> Project
project :: String -> Project
project String
file = Project :: Text
-> Text
-> Text
-> Maybe ProjectDescription
-> BuildTool
-> Maybe PackageDbStack
-> Project
Project {
	-- Should not be the directory of the cabal, s/b the base name of the cabal file.
	_projectName :: Text
_projectName = String -> Text
fromFilePath (String -> Text) -> ShowS -> String -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ShowS
dropExtension ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ShowS
takeBaseName (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$ String
cabal,
	_projectPath :: Text
_projectPath = String -> Text
fromFilePath (String -> Text) -> ShowS -> String -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ShowS
takeDirectory (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$ String
cabal,
	_projectCabal :: Text
_projectCabal = String -> Text
fromFilePath String
cabal,
	_projectDescription :: Maybe ProjectDescription
_projectDescription = Maybe ProjectDescription
forall a. Maybe a
Nothing,
	_projectBuildTool :: BuildTool
_projectBuildTool = BuildTool
CabalTool,
	_projectPackageDbStack :: Maybe PackageDbStack
_projectPackageDbStack = Maybe PackageDbStack
forall a. Maybe a
Nothing }
	where
		file' :: String
file' = ShowS
dropTrailingPathSeparator ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$ ShowS
normalise String
file
		cabal :: String
cabal
			| ShowS
takeExtension String
file' String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
".cabal" = String
file'
			| Bool
otherwise = String
file' String -> ShowS
</> (ShowS
takeBaseName String
file' String -> ShowS
<.> String
"cabal")

data ProjectDescription = ProjectDescription {
	ProjectDescription -> Text
_projectVersion :: Text,
	ProjectDescription -> Maybe Library
_projectLibrary :: Maybe Library,
	ProjectDescription -> [Executable]
_projectExecutables :: [Executable],
	ProjectDescription -> [Test]
_projectTests :: [Test] }
		deriving (ProjectDescription -> ProjectDescription -> Bool
(ProjectDescription -> ProjectDescription -> Bool)
-> (ProjectDescription -> ProjectDescription -> Bool)
-> Eq ProjectDescription
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ProjectDescription -> ProjectDescription -> Bool
$c/= :: ProjectDescription -> ProjectDescription -> Bool
== :: ProjectDescription -> ProjectDescription -> Bool
$c== :: ProjectDescription -> ProjectDescription -> Bool
Eq, ReadPrec [ProjectDescription]
ReadPrec ProjectDescription
Int -> ReadS ProjectDescription
ReadS [ProjectDescription]
(Int -> ReadS ProjectDescription)
-> ReadS [ProjectDescription]
-> ReadPrec ProjectDescription
-> ReadPrec [ProjectDescription]
-> Read ProjectDescription
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [ProjectDescription]
$creadListPrec :: ReadPrec [ProjectDescription]
readPrec :: ReadPrec ProjectDescription
$creadPrec :: ReadPrec ProjectDescription
readList :: ReadS [ProjectDescription]
$creadList :: ReadS [ProjectDescription]
readsPrec :: Int -> ReadS ProjectDescription
$creadsPrec :: Int -> ReadS ProjectDescription
Read)

-- | Build target infos
infos :: Traversal' ProjectDescription Info
infos :: (Info -> f Info) -> ProjectDescription -> f ProjectDescription
infos Info -> f Info
f ProjectDescription
desc = (\Maybe Library
lib [Executable]
exes [Test]
tests -> ProjectDescription
desc { _projectLibrary :: Maybe Library
_projectLibrary = Maybe Library
lib, _projectExecutables :: [Executable]
_projectExecutables = [Executable]
exes, _projectTests :: [Test]
_projectTests = [Test]
tests }) (Maybe Library -> [Executable] -> [Test] -> ProjectDescription)
-> f (Maybe Library)
-> f ([Executable] -> [Test] -> ProjectDescription)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
	((Library -> f Library) -> Maybe Library -> f (Maybe Library)
forall a b. Prism (Maybe a) (Maybe b) a b
_Just ((Library -> f Library) -> Maybe Library -> f (Maybe Library))
-> ((Info -> f Info) -> Library -> f Library)
-> (Info -> f Info)
-> Maybe Library
-> f (Maybe Library)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Info -> f Info) -> Library -> f Library
forall a. Target a => Lens' a Info
buildInfo) Info -> f Info
f (ProjectDescription -> Maybe Library
_projectLibrary ProjectDescription
desc) f ([Executable] -> [Test] -> ProjectDescription)
-> f [Executable] -> f ([Test] -> ProjectDescription)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*>
	((Executable -> f Executable) -> [Executable] -> f [Executable]
forall s t a b. Each s t a b => Traversal s t a b
each ((Executable -> f Executable) -> [Executable] -> f [Executable])
-> ((Info -> f Info) -> Executable -> f Executable)
-> (Info -> f Info)
-> [Executable]
-> f [Executable]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Info -> f Info) -> Executable -> f Executable
forall a. Target a => Lens' a Info
buildInfo) Info -> f Info
f (ProjectDescription -> [Executable]
_projectExecutables ProjectDescription
desc) f ([Test] -> ProjectDescription)
-> f [Test] -> f ProjectDescription
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*>
	((Test -> f Test) -> [Test] -> f [Test]
forall s t a b. Each s t a b => Traversal s t a b
each ((Test -> f Test) -> [Test] -> f [Test])
-> ((Info -> f Info) -> Test -> f Test)
-> (Info -> f Info)
-> [Test]
-> f [Test]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Info -> f Info) -> Test -> f Test
forall a. Target a => Lens' a Info
buildInfo) Info -> f Info
f (ProjectDescription -> [Test]
_projectTests ProjectDescription
desc)

-- | Build target infos, more detailed
targetInfos :: ProjectDescription -> [TargetInfo]
targetInfos :: ProjectDescription -> [TargetInfo]
targetInfos ProjectDescription
desc = [[TargetInfo]] -> [TargetInfo]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [
	(Library -> TargetInfo) -> [Library] -> [TargetInfo]
forall a b. (a -> b) -> [a] -> [b]
map Library -> TargetInfo
forall a. Target a => a -> TargetInfo
targetInfo ([Library] -> [TargetInfo]) -> [Library] -> [TargetInfo]
forall a b. (a -> b) -> a -> b
$ Maybe Library -> [Library]
forall a. Maybe a -> [a]
maybeToList (ProjectDescription -> Maybe Library
_projectLibrary ProjectDescription
desc),
	(Executable -> TargetInfo) -> [Executable] -> [TargetInfo]
forall a b. (a -> b) -> [a] -> [b]
map Executable -> TargetInfo
forall a. Target a => a -> TargetInfo
targetInfo ([Executable] -> [TargetInfo]) -> [Executable] -> [TargetInfo]
forall a b. (a -> b) -> a -> b
$ ProjectDescription -> [Executable]
_projectExecutables ProjectDescription
desc,
	(Test -> TargetInfo) -> [Test] -> [TargetInfo]
forall a b. (a -> b) -> [a] -> [b]
map Test -> TargetInfo
forall a. Target a => a -> TargetInfo
targetInfo ([Test] -> [TargetInfo]) -> [Test] -> [TargetInfo]
forall a b. (a -> b) -> a -> b
$ ProjectDescription -> [Test]
_projectTests ProjectDescription
desc]

instance Show ProjectDescription where
	show :: ProjectDescription -> String
show ProjectDescription
pd = FormatFlags -> String
unlines (FormatFlags -> String) -> FormatFlags -> String
forall a b. (a -> b) -> a -> b
$
		(Library -> FormatFlags) -> [Library] -> FormatFlags
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (String -> FormatFlags
lines (String -> FormatFlags)
-> (Library -> String) -> Library -> FormatFlags
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Library -> String
forall a. Show a => a -> String
show) (Maybe Library -> [Library]
forall a. Maybe a -> [a]
maybeToList (ProjectDescription -> Maybe Library
_projectLibrary ProjectDescription
pd)) FormatFlags -> FormatFlags -> FormatFlags
forall a. [a] -> [a] -> [a]
++
		(Executable -> FormatFlags) -> [Executable] -> FormatFlags
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (String -> FormatFlags
lines (String -> FormatFlags)
-> (Executable -> String) -> Executable -> FormatFlags
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Executable -> String
forall a. Show a => a -> String
show) (ProjectDescription -> [Executable]
_projectExecutables ProjectDescription
pd) FormatFlags -> FormatFlags -> FormatFlags
forall a. [a] -> [a] -> [a]
++
		(Test -> FormatFlags) -> [Test] -> FormatFlags
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (String -> FormatFlags
lines (String -> FormatFlags) -> (Test -> String) -> Test -> FormatFlags
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Test -> String
forall a. Show a => a -> String
show) (ProjectDescription -> [Test]
_projectTests ProjectDescription
pd)

instance ToJSON ProjectDescription where
	toJSON :: ProjectDescription -> Value
toJSON ProjectDescription
d = [Pair] -> Value
object [
		Text
"version" Text -> Text -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= ProjectDescription -> Text
_projectVersion ProjectDescription
d,
		Text
"library" Text -> Maybe Library -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= ProjectDescription -> Maybe Library
_projectLibrary ProjectDescription
d,
		Text
"executables" Text -> [Executable] -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= ProjectDescription -> [Executable]
_projectExecutables ProjectDescription
d,
		Text
"tests" Text -> [Test] -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= ProjectDescription -> [Test]
_projectTests ProjectDescription
d]

instance FromJSON ProjectDescription where
	parseJSON :: Value -> Parser ProjectDescription
parseJSON = String
-> (Object -> Parser ProjectDescription)
-> Value
-> Parser ProjectDescription
forall a. String -> (Object -> Parser a) -> Value -> Parser a
withObject String
"project description" ((Object -> Parser ProjectDescription)
 -> Value -> Parser ProjectDescription)
-> (Object -> Parser ProjectDescription)
-> Value
-> Parser ProjectDescription
forall a b. (a -> b) -> a -> b
$ \Object
v -> Text
-> Maybe Library -> [Executable] -> [Test] -> ProjectDescription
ProjectDescription (Text
 -> Maybe Library -> [Executable] -> [Test] -> ProjectDescription)
-> Parser Text
-> Parser
     (Maybe Library -> [Executable] -> [Test] -> ProjectDescription)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
		Object
v Object -> Text -> Parser Text
forall a. FromJSON a => Object -> Text -> Parser a
.:: Text
"version" Parser
  (Maybe Library -> [Executable] -> [Test] -> ProjectDescription)
-> Parser (Maybe Library)
-> Parser ([Executable] -> [Test] -> ProjectDescription)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*>
		Object
v Object -> Text -> Parser (Maybe Library)
forall a. FromJSON a => Object -> Text -> Parser a
.:: Text
"library" Parser ([Executable] -> [Test] -> ProjectDescription)
-> Parser [Executable] -> Parser ([Test] -> ProjectDescription)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*>
		Object
v Object -> Text -> Parser [Executable]
forall a. FromJSON a => Object -> Text -> Parser a
.:: Text
"executables" Parser ([Test] -> ProjectDescription)
-> Parser [Test] -> Parser ProjectDescription
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*>
		Object
v Object -> Text -> Parser [Test]
forall a. FromJSON a => Object -> Text -> Parser a
.:: Text
"tests"

instance Paths ProjectDescription where
	paths :: (String -> f String) -> ProjectDescription -> f ProjectDescription
paths String -> f String
f (ProjectDescription Text
v Maybe Library
lib [Executable]
exes [Test]
tests) = Text
-> Maybe Library -> [Executable] -> [Test] -> ProjectDescription
ProjectDescription Text
v (Maybe Library -> [Executable] -> [Test] -> ProjectDescription)
-> f (Maybe Library)
-> f ([Executable] -> [Test] -> ProjectDescription)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Library -> f Library) -> Maybe Library -> f (Maybe Library)
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse ((String -> f String) -> Library -> f Library
forall a. Paths a => Traversal' a String
paths String -> f String
f) Maybe Library
lib f ([Executable] -> [Test] -> ProjectDescription)
-> f [Executable] -> f ([Test] -> ProjectDescription)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Executable -> f Executable) -> [Executable] -> f [Executable]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse ((String -> f String) -> Executable -> f Executable
forall a. Paths a => Traversal' a String
paths String -> f String
f) [Executable]
exes f ([Test] -> ProjectDescription)
-> f [Test] -> f ProjectDescription
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Test -> f Test) -> [Test] -> f [Test]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse ((String -> f String) -> Test -> f Test
forall a. Paths a => Traversal' a String
paths String -> f String
f) [Test]
tests

class Target a where
	targetName :: Traversal' a Text
	buildInfo :: Lens' a Info
	targetMain :: a -> Maybe Path
	targetModules :: a -> [[Text]]

data TargetInfo = TargetInfo {
	TargetInfo -> Maybe Text
_targetInfoName :: Maybe Text,
	TargetInfo -> Info
_targetBuildInfo :: Info,
	TargetInfo -> Maybe Text
_targetInfoMain :: Maybe Path,
	TargetInfo -> [[Text]]
_targetInfoModules :: [[Text]] }
		deriving (TargetInfo -> TargetInfo -> Bool
(TargetInfo -> TargetInfo -> Bool)
-> (TargetInfo -> TargetInfo -> Bool) -> Eq TargetInfo
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: TargetInfo -> TargetInfo -> Bool
$c/= :: TargetInfo -> TargetInfo -> Bool
== :: TargetInfo -> TargetInfo -> Bool
$c== :: TargetInfo -> TargetInfo -> Bool
Eq, Eq TargetInfo
Eq TargetInfo
-> (TargetInfo -> TargetInfo -> Ordering)
-> (TargetInfo -> TargetInfo -> Bool)
-> (TargetInfo -> TargetInfo -> Bool)
-> (TargetInfo -> TargetInfo -> Bool)
-> (TargetInfo -> TargetInfo -> Bool)
-> (TargetInfo -> TargetInfo -> TargetInfo)
-> (TargetInfo -> TargetInfo -> TargetInfo)
-> Ord TargetInfo
TargetInfo -> TargetInfo -> Bool
TargetInfo -> TargetInfo -> Ordering
TargetInfo -> TargetInfo -> TargetInfo
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 :: TargetInfo -> TargetInfo -> TargetInfo
$cmin :: TargetInfo -> TargetInfo -> TargetInfo
max :: TargetInfo -> TargetInfo -> TargetInfo
$cmax :: TargetInfo -> TargetInfo -> TargetInfo
>= :: TargetInfo -> TargetInfo -> Bool
$c>= :: TargetInfo -> TargetInfo -> Bool
> :: TargetInfo -> TargetInfo -> Bool
$c> :: TargetInfo -> TargetInfo -> Bool
<= :: TargetInfo -> TargetInfo -> Bool
$c<= :: TargetInfo -> TargetInfo -> Bool
< :: TargetInfo -> TargetInfo -> Bool
$c< :: TargetInfo -> TargetInfo -> Bool
compare :: TargetInfo -> TargetInfo -> Ordering
$ccompare :: TargetInfo -> TargetInfo -> Ordering
$cp1Ord :: Eq TargetInfo
Ord, Int -> TargetInfo -> ShowS
[TargetInfo] -> ShowS
TargetInfo -> String
(Int -> TargetInfo -> ShowS)
-> (TargetInfo -> String)
-> ([TargetInfo] -> ShowS)
-> Show TargetInfo
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [TargetInfo] -> ShowS
$cshowList :: [TargetInfo] -> ShowS
show :: TargetInfo -> String
$cshow :: TargetInfo -> String
showsPrec :: Int -> TargetInfo -> ShowS
$cshowsPrec :: Int -> TargetInfo -> ShowS
Show)

targetInfo :: Target a => a -> TargetInfo
targetInfo :: a -> TargetInfo
targetInfo a
t = Maybe Text -> Info -> Maybe Text -> [[Text]] -> TargetInfo
TargetInfo (a
t a -> Getting (First Text) a Text -> Maybe Text
forall s a. s -> Getting (First a) s a -> Maybe a
^? Getting (First Text) a Text
forall a. Target a => Traversal' a Text
targetName) (a
t a -> Getting Info a Info -> Info
forall s a. s -> Getting a s a -> a
^. Getting Info a Info
forall a. Target a => Lens' a Info
buildInfo) (a -> Maybe Text
forall a. Target a => a -> Maybe Text
targetMain a
t) (a -> [[Text]]
forall a. Target a => a -> [[Text]]
targetModules a
t)

instance Paths TargetInfo where
	paths :: (String -> f String) -> TargetInfo -> f TargetInfo
paths String -> f String
f (TargetInfo Maybe Text
n Info
i Maybe Text
mp [[Text]]
ms) = Maybe Text -> Info -> Maybe Text -> [[Text]] -> TargetInfo
TargetInfo Maybe Text
n (Info -> Maybe Text -> [[Text]] -> TargetInfo)
-> f Info -> f (Maybe Text -> [[Text]] -> TargetInfo)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (String -> f String) -> Info -> f Info
forall a. Paths a => Traversal' a String
paths String -> f String
f Info
i f (Maybe Text -> [[Text]] -> TargetInfo)
-> f (Maybe Text) -> f ([[Text]] -> TargetInfo)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Text -> f Text) -> Maybe Text -> f (Maybe Text)
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse ((String -> f String) -> Text -> f Text
forall a. Paths a => Traversal' a String
paths String -> f String
f) Maybe Text
mp f ([[Text]] -> TargetInfo) -> f [[Text]] -> f TargetInfo
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> [[Text]] -> f [[Text]]
forall (f :: * -> *) a. Applicative f => a -> f a
pure [[Text]]
ms

-- | Library in project
data Library = Library {
	Library -> [[Text]]
_libraryModules :: [[Text]],
	Library -> Info
_libraryBuildInfo :: Info }
		deriving (Library -> Library -> Bool
(Library -> Library -> Bool)
-> (Library -> Library -> Bool) -> Eq Library
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Library -> Library -> Bool
$c/= :: Library -> Library -> Bool
== :: Library -> Library -> Bool
$c== :: Library -> Library -> Bool
Eq, ReadPrec [Library]
ReadPrec Library
Int -> ReadS Library
ReadS [Library]
(Int -> ReadS Library)
-> ReadS [Library]
-> ReadPrec Library
-> ReadPrec [Library]
-> Read Library
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [Library]
$creadListPrec :: ReadPrec [Library]
readPrec :: ReadPrec Library
$creadPrec :: ReadPrec Library
readList :: ReadS [Library]
$creadList :: ReadS [Library]
readsPrec :: Int -> ReadS Library
$creadsPrec :: Int -> ReadS Library
Read)

instance Show Library where
	show :: Library -> String
show Library
l = FormatFlags -> String
unlines (FormatFlags -> String) -> FormatFlags -> String
forall a b. (a -> b) -> a -> b
$
		[String
"library", String
"\tmodules:"] FormatFlags -> FormatFlags -> FormatFlags
forall a. [a] -> [a] -> [a]
++
		(([Text] -> String) -> [[Text]] -> FormatFlags
forall a b. (a -> b) -> [a] -> [b]
map (Int -> ShowS
tab Int
2 ShowS -> ([Text] -> String) -> [Text] -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> String
T.unpack (Text -> String) -> ([Text] -> Text) -> [Text] -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> [Text] -> Text
T.intercalate Text
".") ([[Text]] -> FormatFlags) -> [[Text]] -> FormatFlags
forall a b. (a -> b) -> a -> b
$ Library -> [[Text]]
_libraryModules Library
l) FormatFlags -> FormatFlags -> FormatFlags
forall a. [a] -> [a] -> [a]
++
		(ShowS -> FormatFlags -> FormatFlags
forall a b. (a -> b) -> [a] -> [b]
map (Int -> ShowS
tab Int
1) (FormatFlags -> FormatFlags)
-> (Info -> FormatFlags) -> Info -> FormatFlags
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> FormatFlags
lines (String -> FormatFlags) -> (Info -> String) -> Info -> FormatFlags
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Info -> String
forall a. Show a => a -> String
show (Info -> FormatFlags) -> Info -> FormatFlags
forall a b. (a -> b) -> a -> b
$ Library -> Info
_libraryBuildInfo Library
l)

instance ToJSON Library where
	toJSON :: Library -> Value
toJSON Library
l = [Pair] -> Value
object [
		Text
"modules" Text -> [Text] -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= ([Text] -> Text) -> [[Text]] -> [Text]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Text -> [Text] -> Text
T.intercalate Text
".") (Library -> [[Text]]
_libraryModules Library
l),
		Text
"info" Text -> Info -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Library -> Info
_libraryBuildInfo Library
l]

instance FromJSON Library where
	parseJSON :: Value -> Parser Library
parseJSON = String -> (Object -> Parser Library) -> Value -> Parser Library
forall a. String -> (Object -> Parser a) -> Value -> Parser a
withObject String
"library" ((Object -> Parser Library) -> Value -> Parser Library)
-> (Object -> Parser Library) -> Value -> Parser Library
forall a b. (a -> b) -> a -> b
$ \Object
v -> [[Text]] -> Info -> Library
Library ([[Text]] -> Info -> Library)
-> Parser [[Text]] -> Parser (Info -> Library)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ((Text -> [Text]) -> [Text] -> [[Text]]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((Char -> Bool) -> Text -> [Text]
T.split (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'.')) ([Text] -> [[Text]]) -> Parser [Text] -> Parser [[Text]]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
v Object -> Text -> Parser [Text]
forall a. FromJSON a => Object -> Text -> Parser a
.:: Text
"modules") Parser (Info -> Library) -> Parser Info -> Parser Library
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
v Object -> Text -> Parser Info
forall a. FromJSON a => Object -> Text -> Parser a
.:: Text
"info"

instance Paths Library where
	paths :: (String -> f String) -> Library -> f Library
paths String -> f String
f (Library [[Text]]
ms Info
info) = [[Text]] -> Info -> Library
Library [[Text]]
ms (Info -> Library) -> f Info -> f Library
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (String -> f String) -> Info -> f Info
forall a. Paths a => Traversal' a String
paths String -> f String
f Info
info

-- | Executable
data Executable = Executable {
	Executable -> Text
_executableName :: Text,
	Executable -> Text
_executablePath :: Path,
	Executable -> Info
_executableBuildInfo :: Info }
		deriving (Executable -> Executable -> Bool
(Executable -> Executable -> Bool)
-> (Executable -> Executable -> Bool) -> Eq Executable
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Executable -> Executable -> Bool
$c/= :: Executable -> Executable -> Bool
== :: Executable -> Executable -> Bool
$c== :: Executable -> Executable -> Bool
Eq, ReadPrec [Executable]
ReadPrec Executable
Int -> ReadS Executable
ReadS [Executable]
(Int -> ReadS Executable)
-> ReadS [Executable]
-> ReadPrec Executable
-> ReadPrec [Executable]
-> Read Executable
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [Executable]
$creadListPrec :: ReadPrec [Executable]
readPrec :: ReadPrec Executable
$creadPrec :: ReadPrec Executable
readList :: ReadS [Executable]
$creadList :: ReadS [Executable]
readsPrec :: Int -> ReadS Executable
$creadsPrec :: Int -> ReadS Executable
Read)

instance Show Executable where
	show :: Executable -> String
show Executable
e = FormatFlags -> String
unlines (FormatFlags -> String) -> FormatFlags -> String
forall a b. (a -> b) -> a -> b
$
		[String
"executable " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Text -> String
T.unpack (Executable -> Text
_executableName Executable
e), String
"\tpath: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ (Executable -> Text
_executablePath Executable
e Text -> Getting String Text String -> String
forall s a. s -> Getting a s a -> a
^. Getting String Text String
Lens' Text String
path)] FormatFlags -> FormatFlags -> FormatFlags
forall a. [a] -> [a] -> [a]
++
		(ShowS -> FormatFlags -> FormatFlags
forall a b. (a -> b) -> [a] -> [b]
map (Int -> ShowS
tab Int
1) (FormatFlags -> FormatFlags)
-> (Info -> FormatFlags) -> Info -> FormatFlags
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> FormatFlags
lines (String -> FormatFlags) -> (Info -> String) -> Info -> FormatFlags
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Info -> String
forall a. Show a => a -> String
show (Info -> FormatFlags) -> Info -> FormatFlags
forall a b. (a -> b) -> a -> b
$ Executable -> Info
_executableBuildInfo Executable
e)

instance ToJSON Executable where
	toJSON :: Executable -> Value
toJSON Executable
e = [Pair] -> Value
object [
		Text
"name" Text -> Text -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Executable -> Text
_executableName Executable
e,
		Text
"path" Text -> Text -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Executable -> Text
_executablePath Executable
e,
		Text
"info" Text -> Info -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Executable -> Info
_executableBuildInfo Executable
e]

instance FromJSON Executable where
	parseJSON :: Value -> Parser Executable
parseJSON = String
-> (Object -> Parser Executable) -> Value -> Parser Executable
forall a. String -> (Object -> Parser a) -> Value -> Parser a
withObject String
"executable" ((Object -> Parser Executable) -> Value -> Parser Executable)
-> (Object -> Parser Executable) -> Value -> Parser Executable
forall a b. (a -> b) -> a -> b
$ \Object
v -> Text -> Text -> Info -> Executable
Executable (Text -> Text -> Info -> Executable)
-> Parser Text -> Parser (Text -> Info -> Executable)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
		Object
v Object -> Text -> Parser Text
forall a. FromJSON a => Object -> Text -> Parser a
.:: Text
"name" Parser (Text -> Info -> Executable)
-> Parser Text -> Parser (Info -> Executable)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*>
		Object
v Object -> Text -> Parser Text
forall a. FromJSON a => Object -> Text -> Parser a
.:: Text
"path" Parser (Info -> Executable) -> Parser Info -> Parser Executable
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*>
		Object
v Object -> Text -> Parser Info
forall a. FromJSON a => Object -> Text -> Parser a
.:: Text
"info"

instance Paths Executable where
	paths :: (String -> f String) -> Executable -> f Executable
paths String -> f String
f (Executable Text
n Text
p Info
info) = Text -> Text -> Info -> Executable
Executable Text
n (Text -> Info -> Executable) -> f Text -> f (Info -> Executable)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (String -> f String) -> Text -> f Text
forall a. Paths a => Traversal' a String
paths String -> f String
f Text
p f (Info -> Executable) -> f Info -> f Executable
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (String -> f String) -> Info -> f Info
forall a. Paths a => Traversal' a String
paths String -> f String
f Info
info

-- | Test
data Test = Test {
	Test -> Text
_testName :: Text,
	Test -> Bool
_testEnabled :: Bool,
	Test -> Maybe Text
_testMain :: Maybe Path,
	Test -> Info
_testBuildInfo :: Info }
		deriving (Test -> Test -> Bool
(Test -> Test -> Bool) -> (Test -> Test -> Bool) -> Eq Test
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Test -> Test -> Bool
$c/= :: Test -> Test -> Bool
== :: Test -> Test -> Bool
$c== :: Test -> Test -> Bool
Eq, ReadPrec [Test]
ReadPrec Test
Int -> ReadS Test
ReadS [Test]
(Int -> ReadS Test)
-> ReadS [Test] -> ReadPrec Test -> ReadPrec [Test] -> Read Test
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [Test]
$creadListPrec :: ReadPrec [Test]
readPrec :: ReadPrec Test
$creadPrec :: ReadPrec Test
readList :: ReadS [Test]
$creadList :: ReadS [Test]
readsPrec :: Int -> ReadS Test
$creadsPrec :: Int -> ReadS Test
Read)

instance Show Test where
	show :: Test -> String
show Test
t = FormatFlags -> String
unlines (FormatFlags -> String) -> FormatFlags -> String
forall a b. (a -> b) -> a -> b
$
		[String
"test " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Text -> String
T.unpack (Test -> Text
_testName Test
t), String
"\tenabled: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Bool -> String
forall a. Show a => a -> String
show (Test -> Bool
_testEnabled Test
t)] FormatFlags -> FormatFlags -> FormatFlags
forall a. [a] -> [a] -> [a]
++
		FormatFlags -> (Text -> FormatFlags) -> Maybe Text -> FormatFlags
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] (\Text
f -> [String
"\tmain-is: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Text
f Text -> Getting String Text String -> String
forall s a. s -> Getting a s a -> a
^. Getting String Text String
Lens' Text String
path]) (Test -> Maybe Text
_testMain Test
t) FormatFlags -> FormatFlags -> FormatFlags
forall a. [a] -> [a] -> [a]
++
		(ShowS -> FormatFlags -> FormatFlags
forall a b. (a -> b) -> [a] -> [b]
map (Int -> ShowS
tab Int
1) (FormatFlags -> FormatFlags)
-> (Info -> FormatFlags) -> Info -> FormatFlags
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> FormatFlags
lines (String -> FormatFlags) -> (Info -> String) -> Info -> FormatFlags
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Info -> String
forall a. Show a => a -> String
show (Info -> FormatFlags) -> Info -> FormatFlags
forall a b. (a -> b) -> a -> b
$ Test -> Info
_testBuildInfo Test
t)

instance ToJSON Test where
	toJSON :: Test -> Value
toJSON Test
t = [Pair] -> Value
object [
		Text
"name" Text -> Text -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Test -> Text
_testName Test
t,
		Text
"enabled" Text -> Bool -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Test -> Bool
_testEnabled Test
t,
		Text
"main" Text -> Maybe Text -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Test -> Maybe Text
_testMain Test
t,
		Text
"info" Text -> Info -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Test -> Info
_testBuildInfo Test
t]

instance FromJSON Test where
	parseJSON :: Value -> Parser Test
parseJSON = String -> (Object -> Parser Test) -> Value -> Parser Test
forall a. String -> (Object -> Parser a) -> Value -> Parser a
withObject String
"test" ((Object -> Parser Test) -> Value -> Parser Test)
-> (Object -> Parser Test) -> Value -> Parser Test
forall a b. (a -> b) -> a -> b
$ \Object
v -> Text -> Bool -> Maybe Text -> Info -> Test
Test (Text -> Bool -> Maybe Text -> Info -> Test)
-> Parser Text -> Parser (Bool -> Maybe Text -> Info -> Test)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
		Object
v Object -> Text -> Parser Text
forall a. FromJSON a => Object -> Text -> Parser a
.:: Text
"name" Parser (Bool -> Maybe Text -> Info -> Test)
-> Parser Bool -> Parser (Maybe Text -> Info -> Test)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*>
		Object
v Object -> Text -> Parser Bool
forall a. FromJSON a => Object -> Text -> Parser a
.:: Text
"enabled" Parser (Maybe Text -> Info -> Test)
-> Parser (Maybe Text) -> Parser (Info -> Test)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*>
		Object
v Object -> Text -> Parser (Maybe Text)
forall a. FromJSON a => Object -> Text -> Parser (Maybe a)
.::? Text
"main" Parser (Info -> Test) -> Parser Info -> Parser Test
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*>
		Object
v Object -> Text -> Parser Info
forall a. FromJSON a => Object -> Text -> Parser a
.:: Text
"info"

instance Paths Test where
	paths :: (String -> f String) -> Test -> f Test
paths String -> f String
f (Test Text
n Bool
e Maybe Text
m Info
info) = Text -> Bool -> Maybe Text -> Info -> Test
Test Text
n Bool
e (Maybe Text -> Info -> Test) -> f (Maybe Text) -> f (Info -> Test)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Text -> f Text) -> Maybe Text -> f (Maybe Text)
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse ((String -> f String) -> Text -> f Text
forall a. Paths a => Traversal' a String
paths String -> f String
f) Maybe Text
m f (Info -> Test) -> f Info -> f Test
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (String -> f String) -> Info -> f Info
forall a. Paths a => Traversal' a String
paths String -> f String
f Info
info

-- | Build info
data Info = Info {
	Info -> [Text]
_infoDepends :: [Text],
	Info -> Maybe Language
_infoLanguage :: Maybe Language,
	Info -> [Extension]
_infoExtensions :: [Extension],
	Info -> [Text]
_infoGHCOptions :: [Text],
	Info -> [Text]
_infoSourceDirs :: [Path],
	Info -> [[Text]]
_infoOtherModules :: [[Text]] }
		deriving (Info -> Info -> Bool
(Info -> Info -> Bool) -> (Info -> Info -> Bool) -> Eq Info
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Info -> Info -> Bool
$c/= :: Info -> Info -> Bool
== :: Info -> Info -> Bool
$c== :: Info -> Info -> Bool
Eq, ReadPrec [Info]
ReadPrec Info
Int -> ReadS Info
ReadS [Info]
(Int -> ReadS Info)
-> ReadS [Info] -> ReadPrec Info -> ReadPrec [Info] -> Read Info
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [Info]
$creadListPrec :: ReadPrec [Info]
readPrec :: ReadPrec Info
$creadPrec :: ReadPrec Info
readList :: ReadS [Info]
$creadList :: ReadS [Info]
readsPrec :: Int -> ReadS Info
$creadsPrec :: Int -> ReadS Info
Read)

instance Semigroup Info where
	Info
l <> :: Info -> Info -> Info
<> Info
r = [Text]
-> Maybe Language
-> [Extension]
-> [Text]
-> [Text]
-> [[Text]]
-> Info
Info
		([Text] -> [Text]
forall a. Ord a => [a] -> [a]
ordNub ([Text] -> [Text]) -> [Text] -> [Text]
forall a b. (a -> b) -> a -> b
$ Info -> [Text]
_infoDepends Info
l [Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ Info -> [Text]
_infoDepends Info
r)
		(First Language -> Maybe Language
forall a. First a -> Maybe a
getFirst (First Language -> Maybe Language)
-> First Language -> Maybe Language
forall a b. (a -> b) -> a -> b
$ Maybe Language -> First Language
forall a. Maybe a -> First a
First (Info -> Maybe Language
_infoLanguage Info
l) First Language -> First Language -> First Language
forall a. Monoid a => a -> a -> a
`mappend` Maybe Language -> First Language
forall a. Maybe a -> First a
First (Info -> Maybe Language
_infoLanguage Info
r))
		(Info -> [Extension]
_infoExtensions Info
l [Extension] -> [Extension] -> [Extension]
forall a. [a] -> [a] -> [a]
++ Info -> [Extension]
_infoExtensions Info
r)
		(Info -> [Text]
_infoGHCOptions Info
l [Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ Info -> [Text]
_infoGHCOptions Info
r)
		([Text] -> [Text]
forall a. Ord a => [a] -> [a]
ordNub ([Text] -> [Text]) -> [Text] -> [Text]
forall a b. (a -> b) -> a -> b
$ Info -> [Text]
_infoSourceDirs Info
l [Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ Info -> [Text]
_infoSourceDirs Info
r)
		([[Text]] -> [[Text]]
forall a. Ord a => [a] -> [a]
ordNub ([[Text]] -> [[Text]]) -> [[Text]] -> [[Text]]
forall a b. (a -> b) -> a -> b
$ Info -> [[Text]]
_infoOtherModules Info
l [[Text]] -> [[Text]] -> [[Text]]
forall a. [a] -> [a] -> [a]
++ Info -> [[Text]]
_infoOtherModules Info
r)

instance Monoid Info where
	mempty :: Info
mempty = [Text]
-> Maybe Language
-> [Extension]
-> [Text]
-> [Text]
-> [[Text]]
-> Info
Info [] Maybe Language
forall a. Maybe a
Nothing [] [] [] []
	mappend :: Info -> Info -> Info
mappend Info
l Info
r = Info
l Info -> Info -> Info
forall a. Semigroup a => a -> a -> a
<> Info
r

instance Ord Info where
	compare :: Info -> Info -> Ordering
compare Info
l Info
r = ([Text], [Text], [Text]) -> ([Text], [Text], [Text]) -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (Info -> [Text]
_infoSourceDirs Info
l, Info -> [Text]
_infoDepends Info
l, Info -> [Text]
_infoGHCOptions Info
l) (Info -> [Text]
_infoSourceDirs Info
r, Info -> [Text]
_infoDepends Info
r, Info -> [Text]
_infoGHCOptions Info
r)

instance Show Info where
	show :: Info -> String
show Info
i = FormatFlags -> String
unlines (FormatFlags -> String) -> FormatFlags -> String
forall a b. (a -> b) -> a -> b
$ FormatFlags
lang FormatFlags -> FormatFlags -> FormatFlags
forall a. [a] -> [a] -> [a]
++ FormatFlags
exts FormatFlags -> FormatFlags -> FormatFlags
forall a. [a] -> [a] -> [a]
++ FormatFlags
opts FormatFlags -> FormatFlags -> FormatFlags
forall a. [a] -> [a] -> [a]
++ FormatFlags
sources FormatFlags -> FormatFlags -> FormatFlags
forall a. [a] -> [a] -> [a]
++ FormatFlags
otherMods where
		lang :: FormatFlags
lang = FormatFlags
-> (Language -> FormatFlags) -> Maybe Language -> FormatFlags
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] (\Language
l -> [String
"default-language: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Language -> String
forall a. Pretty a => a -> String
D.display Language
l]) (Maybe Language -> FormatFlags) -> Maybe Language -> FormatFlags
forall a b. (a -> b) -> a -> b
$ Info -> Maybe Language
_infoLanguage Info
i
		exts :: FormatFlags
exts
			| [Extension] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null (Info -> [Extension]
_infoExtensions Info
i) = []
			| Bool
otherwise = String
"extensions:" String -> FormatFlags -> FormatFlags
forall a. a -> [a] -> [a]
: (Extension -> String) -> [Extension] -> FormatFlags
forall a b. (a -> b) -> [a] -> [b]
map (Int -> ShowS
tab Int
1 ShowS -> (Extension -> String) -> Extension -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Extension -> String
forall a. Pretty a => a -> String
D.display) (Info -> [Extension]
_infoExtensions Info
i)
		opts :: FormatFlags
opts
			| [Text] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null (Info -> [Text]
_infoGHCOptions Info
i) = []
			| Bool
otherwise = String
"ghc-options:" String -> FormatFlags -> FormatFlags
forall a. a -> [a] -> [a]
: (Text -> String) -> [Text] -> FormatFlags
forall a b. (a -> b) -> [a] -> [b]
map (Int -> ShowS
tab Int
1 ShowS -> (Text -> String) -> Text -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> String
T.unpack) (Info -> [Text]
_infoGHCOptions Info
i)
		sources :: FormatFlags
sources = String
"source-dirs:" String -> FormatFlags -> FormatFlags
forall a. a -> [a] -> [a]
: (Text -> String) -> [Text] -> FormatFlags
forall a b. (a -> b) -> [a] -> [b]
map (Int -> ShowS
tab Int
1 ShowS -> (Text -> String) -> Text -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> String
T.unpack) (Info -> [Text]
_infoSourceDirs Info
i)
		otherMods :: FormatFlags
otherMods = String
"other-modules:" String -> FormatFlags -> FormatFlags
forall a. a -> [a] -> [a]
: ((Text -> String) -> [Text] -> FormatFlags
forall a b. (a -> b) -> [a] -> [b]
map (Int -> ShowS
tab Int
1 ShowS -> (Text -> String) -> Text -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> String
T.unpack) ([Text] -> FormatFlags)
-> ([[Text]] -> [Text]) -> [[Text]] -> FormatFlags
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Text] -> Text) -> [[Text]] -> [Text]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Text -> [Text] -> Text
T.intercalate Text
".") ([[Text]] -> FormatFlags) -> [[Text]] -> FormatFlags
forall a b. (a -> b) -> a -> b
$ Info -> [[Text]]
_infoOtherModules Info
i)

instance ToJSON Info where
	toJSON :: Info -> Value
toJSON Info
i = [Pair] -> Value
object [
		Text
"build-depends" Text -> [Text] -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Info -> [Text]
_infoDepends Info
i,
		Text
"language" Text -> Maybe Language -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Info -> Maybe Language
_infoLanguage Info
i,
		Text
"extensions" Text -> [Extension] -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Info -> [Extension]
_infoExtensions Info
i,
		Text
"ghc-options" Text -> [Text] -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Info -> [Text]
_infoGHCOptions Info
i,
		Text
"source-dirs" Text -> [Text] -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Info -> [Text]
_infoSourceDirs Info
i,
		Text
"other-modules" Text -> [[Text]] -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Info -> [[Text]]
_infoOtherModules Info
i]

instance FromJSON Info where
	parseJSON :: Value -> Parser Info
parseJSON = String -> (Object -> Parser Info) -> Value -> Parser Info
forall a. String -> (Object -> Parser a) -> Value -> Parser a
withObject String
"info" ((Object -> Parser Info) -> Value -> Parser Info)
-> (Object -> Parser Info) -> Value -> Parser Info
forall a b. (a -> b) -> a -> b
$ \Object
v -> [Text]
-> Maybe Language
-> [Extension]
-> [Text]
-> [Text]
-> [[Text]]
-> Info
Info ([Text]
 -> Maybe Language
 -> [Extension]
 -> [Text]
 -> [Text]
 -> [[Text]]
 -> Info)
-> Parser [Text]
-> Parser
     (Maybe Language
      -> [Extension] -> [Text] -> [Text] -> [[Text]] -> Info)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
		Object
v Object -> Text -> Parser [Text]
forall a. FromJSON a => Object -> Text -> Parser a
.: Text
"build-depends" Parser
  (Maybe Language
   -> [Extension] -> [Text] -> [Text] -> [[Text]] -> Info)
-> Parser (Maybe Language)
-> Parser ([Extension] -> [Text] -> [Text] -> [[Text]] -> Info)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*>
		Object
v Object -> Text -> Parser (Maybe Language)
forall a. FromJSON a => Object -> Text -> Parser a
.:: Text
"language" Parser ([Extension] -> [Text] -> [Text] -> [[Text]] -> Info)
-> Parser [Extension]
-> Parser ([Text] -> [Text] -> [[Text]] -> Info)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*>
		Object
v Object -> Text -> Parser [Extension]
forall a. FromJSON a => Object -> Text -> Parser a
.:: Text
"extensions" Parser ([Text] -> [Text] -> [[Text]] -> Info)
-> Parser [Text] -> Parser ([Text] -> [[Text]] -> Info)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*>
		Object
v Object -> Text -> Parser [Text]
forall a. FromJSON a => Object -> Text -> Parser a
.:: Text
"ghc-options" Parser ([Text] -> [[Text]] -> Info)
-> Parser [Text] -> Parser ([[Text]] -> Info)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*>
		Object
v Object -> Text -> Parser [Text]
forall a. FromJSON a => Object -> Text -> Parser a
.:: Text
"source-dirs" Parser ([[Text]] -> Info) -> Parser [[Text]] -> Parser Info
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*>
		Object
v Object -> Text -> Parser [[Text]]
forall a. FromJSON a => Object -> Text -> Parser a
.:: Text
"other-modules"

instance ToJSON Language where
	toJSON :: Language -> Value
toJSON = String -> Value
forall a. ToJSON a => a -> Value
toJSON (String -> Value) -> (Language -> String) -> Language -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Language -> String
forall a. Pretty a => a -> String
D.display

instance FromJSON Language where
	parseJSON :: Value -> Parser Language
parseJSON = String -> (Text -> Parser Language) -> Value -> Parser Language
forall a. String -> (Text -> Parser a) -> Value -> Parser a
withText String
"language" ((Text -> Parser Language) -> Value -> Parser Language)
-> (Text -> Parser Language) -> Value -> Parser Language
forall a b. (a -> b) -> a -> b
$ \Text
txt -> String -> String -> Parser Language
forall (m :: * -> *) a.
(MonadFail m, Monad m, Parsec a) =>
String -> String -> m a
parseDT String
"Language" (Text -> String
T.unpack Text
txt)

instance ToJSON Extension where
	toJSON :: Extension -> Value
toJSON = String -> Value
forall a. ToJSON a => a -> Value
toJSON (String -> Value) -> (Extension -> String) -> Extension -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Extension -> String
forall a. Pretty a => a -> String
D.display

instance FromJSON Extension where
	parseJSON :: Value -> Parser Extension
parseJSON = String -> (Text -> Parser Extension) -> Value -> Parser Extension
forall a. String -> (Text -> Parser a) -> Value -> Parser a
withText String
"extension" ((Text -> Parser Extension) -> Value -> Parser Extension)
-> (Text -> Parser Extension) -> Value -> Parser Extension
forall a b. (a -> b) -> a -> b
$ \Text
txt -> String -> String -> Parser Extension
forall (m :: * -> *) a.
(MonadFail m, Monad m, Parsec a) =>
String -> String -> m a
parseDT String
"Extension" (Text -> String
T.unpack Text
txt)

instance Paths Info where
	paths :: (String -> f String) -> Info -> f Info
paths String -> f String
f (Info [Text]
deps Maybe Language
lang [Extension]
exts [Text]
opts [Text]
dirs [[Text]]
omods) = [Text]
-> Maybe Language
-> [Extension]
-> [Text]
-> [Text]
-> [[Text]]
-> Info
Info [Text]
deps Maybe Language
lang [Extension]
exts [Text]
opts ([Text] -> [[Text]] -> Info) -> f [Text] -> f ([[Text]] -> Info)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Text -> f Text) -> [Text] -> f [Text]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse ((String -> f String) -> Text -> f Text
forall a. Paths a => Traversal' a String
paths String -> f String
f) [Text]
dirs f ([[Text]] -> Info) -> f [[Text]] -> f Info
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> [[Text]] -> f [[Text]]
forall (f :: * -> *) a. Applicative f => a -> f a
pure [[Text]]
omods

-- | Entity with project extensions
data Extensions a = Extensions {
	Extensions a -> [Extension]
_extensions :: [Extension],
	Extensions a -> [Text]
_ghcOptions :: [Text],
	Extensions a -> a
_entity :: a }
		deriving (Extensions a -> Extensions a -> Bool
(Extensions a -> Extensions a -> Bool)
-> (Extensions a -> Extensions a -> Bool) -> Eq (Extensions a)
forall a. Eq a => Extensions a -> Extensions a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Extensions a -> Extensions a -> Bool
$c/= :: forall a. Eq a => Extensions a -> Extensions a -> Bool
== :: Extensions a -> Extensions a -> Bool
$c== :: forall a. Eq a => Extensions a -> Extensions a -> Bool
Eq, ReadPrec [Extensions a]
ReadPrec (Extensions a)
Int -> ReadS (Extensions a)
ReadS [Extensions a]
(Int -> ReadS (Extensions a))
-> ReadS [Extensions a]
-> ReadPrec (Extensions a)
-> ReadPrec [Extensions a]
-> Read (Extensions a)
forall a. Read a => ReadPrec [Extensions a]
forall a. Read a => ReadPrec (Extensions a)
forall a. Read a => Int -> ReadS (Extensions a)
forall a. Read a => ReadS [Extensions a]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [Extensions a]
$creadListPrec :: forall a. Read a => ReadPrec [Extensions a]
readPrec :: ReadPrec (Extensions a)
$creadPrec :: forall a. Read a => ReadPrec (Extensions a)
readList :: ReadS [Extensions a]
$creadList :: forall a. Read a => ReadS [Extensions a]
readsPrec :: Int -> ReadS (Extensions a)
$creadsPrec :: forall a. Read a => Int -> ReadS (Extensions a)
Read, Int -> Extensions a -> ShowS
[Extensions a] -> ShowS
Extensions a -> String
(Int -> Extensions a -> ShowS)
-> (Extensions a -> String)
-> ([Extensions a] -> ShowS)
-> Show (Extensions a)
forall a. Show a => Int -> Extensions a -> ShowS
forall a. Show a => [Extensions a] -> ShowS
forall a. Show a => Extensions a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Extensions a] -> ShowS
$cshowList :: forall a. Show a => [Extensions a] -> ShowS
show :: Extensions a -> String
$cshow :: forall a. Show a => Extensions a -> String
showsPrec :: Int -> Extensions a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> Extensions a -> ShowS
Show)

instance Ord a => Ord (Extensions a) where
	compare :: Extensions a -> Extensions a -> Ordering
compare = (Extensions a -> a) -> Extensions a -> Extensions a -> Ordering
forall a b. Ord a => (b -> a) -> b -> b -> Ordering
comparing Extensions a -> a
forall a. Extensions a -> a
_entity

instance Functor Extensions where
	fmap :: (a -> b) -> Extensions a -> Extensions b
fmap a -> b
f (Extensions [Extension]
e [Text]
o a
x) = [Extension] -> [Text] -> b -> Extensions b
forall a. [Extension] -> [Text] -> a -> Extensions a
Extensions [Extension]
e [Text]
o (a -> b
f a
x)

instance Applicative Extensions where
	pure :: a -> Extensions a
pure = [Extension] -> [Text] -> a -> Extensions a
forall a. [Extension] -> [Text] -> a -> Extensions a
Extensions [] []
	(Extensions [Extension]
l [Text]
lo a -> b
f) <*> :: Extensions (a -> b) -> Extensions a -> Extensions b
<*> (Extensions [Extension]
r [Text]
ro a
x) = [Extension] -> [Text] -> b -> Extensions b
forall a. [Extension] -> [Text] -> a -> Extensions a
Extensions ([Extension] -> [Extension]
forall a. Ord a => [a] -> [a]
ordNub ([Extension] -> [Extension]) -> [Extension] -> [Extension]
forall a b. (a -> b) -> a -> b
$ [Extension]
l [Extension] -> [Extension] -> [Extension]
forall a. [a] -> [a] -> [a]
++ [Extension]
r) ([Text] -> [Text]
forall a. Ord a => [a] -> [a]
ordNub ([Text] -> [Text]) -> [Text] -> [Text]
forall a b. (a -> b) -> a -> b
$ [Text]
lo [Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ [Text]
ro) (a -> b
f a
x)

instance Foldable Extensions where
	foldMap :: (a -> m) -> Extensions a -> m
foldMap a -> m
f (Extensions [Extension]
_ [Text]
_ a
x) = a -> m
f a
x

instance Traversable Extensions where
	traverse :: (a -> f b) -> Extensions a -> f (Extensions b)
traverse a -> f b
f (Extensions [Extension]
e [Text]
o a
x) = [Extension] -> [Text] -> b -> Extensions b
forall a. [Extension] -> [Text] -> a -> Extensions a
Extensions [Extension]
e [Text]
o (b -> Extensions b) -> f b -> f (Extensions b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> a -> f b
f a
x

makeLenses ''Project
makeLenses ''ProjectDescription
makeLenses ''TargetInfo
makeLenses ''Library
makeLenses ''Executable
makeLenses ''Test
makeLenses ''Info
makeLenses ''Extensions

instance Target Library where
	targetName :: (Text -> f Text) -> Library -> f Library
targetName Text -> f Text
_ = Library -> f Library
forall (f :: * -> *) a. Applicative f => a -> f a
pure
	buildInfo :: (Info -> f Info) -> Library -> f Library
buildInfo = (Info -> f Info) -> Library -> f Library
Lens' Library Info
libraryBuildInfo
	targetMain :: Library -> Maybe Text
targetMain Library
_ = Maybe Text
forall a. Maybe a
Nothing
	targetModules :: Library -> [[Text]]
targetModules Library
lib' = Library
lib' Library -> Getting (Endo [[Text]]) Library [Text] -> [[Text]]
forall s a. s -> Getting (Endo [a]) s a -> [a]
^.. ([[Text]] -> Const (Endo [[Text]]) [[Text]])
-> Library -> Const (Endo [[Text]]) Library
Lens' Library [[Text]]
libraryModules (([[Text]] -> Const (Endo [[Text]]) [[Text]])
 -> Library -> Const (Endo [[Text]]) Library)
-> (([Text] -> Const (Endo [[Text]]) [Text])
    -> [[Text]] -> Const (Endo [[Text]]) [[Text]])
-> Getting (Endo [[Text]]) Library [Text]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Text] -> Const (Endo [[Text]]) [Text])
-> [[Text]] -> Const (Endo [[Text]]) [[Text]]
forall s t a b. Each s t a b => Traversal s t a b
each

instance Target Executable where
	targetName :: (Text -> f Text) -> Executable -> f Executable
targetName = (Text -> f Text) -> Executable -> f Executable
Lens' Executable Text
executableName
	buildInfo :: (Info -> f Info) -> Executable -> f Executable
buildInfo = (Info -> f Info) -> Executable -> f Executable
Lens' Executable Info
executableBuildInfo
	targetMain :: Executable -> Maybe Text
targetMain Executable
exe' = Text -> Maybe Text
forall a. a -> Maybe a
Just (Text -> Maybe Text) -> Text -> Maybe Text
forall a b. (a -> b) -> a -> b
$ Executable
exe' Executable -> Getting Text Executable Text -> Text
forall s a. s -> Getting a s a -> a
^. Getting Text Executable Text
Lens' Executable Text
executablePath
	targetModules :: Executable -> [[Text]]
targetModules Executable
_ = []

instance Target Test where
	targetName :: (Text -> f Text) -> Test -> f Test
targetName = (Text -> f Text) -> Test -> f Test
Lens' Test Text
testName
	buildInfo :: (Info -> f Info) -> Test -> f Test
buildInfo = (Info -> f Info) -> Test -> f Test
Lens' Test Info
testBuildInfo
	targetMain :: Test -> Maybe Text
targetMain Test
test' = (String -> Text) -> Maybe String -> Maybe Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap String -> Text
toPath (Test
test' Test -> Getting (First String) Test String -> Maybe String
forall s a. s -> Getting (First a) s a -> Maybe a
^? (Maybe Text -> Const (First String) (Maybe Text))
-> Test -> Const (First String) Test
Lens' Test (Maybe Text)
testMain ((Maybe Text -> Const (First String) (Maybe Text))
 -> Test -> Const (First String) Test)
-> ((String -> Const (First String) String)
    -> Maybe Text -> Const (First String) (Maybe Text))
-> Getting (First String) Test String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Text -> Const (First String) Text)
-> Maybe Text -> Const (First String) (Maybe Text)
forall a b. Prism (Maybe a) (Maybe b) a b
_Just ((Text -> Const (First String) Text)
 -> Maybe Text -> Const (First String) (Maybe Text))
-> ((String -> Const (First String) String)
    -> Text -> Const (First String) Text)
-> (String -> Const (First String) String)
-> Maybe Text
-> Const (First String) (Maybe Text)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String -> Const (First String) String)
-> Text -> Const (First String) Text
Lens' Text String
path) where
		toPath :: String -> Text
toPath String
f
			| String -> Bool
haskellSource String
f = String -> Text
fromFilePath String
f
			| Bool
otherwise = String -> Text
fromFilePath (String
f String -> ShowS
<.> String
"hs")
	targetModules :: Test -> [[Text]]
targetModules Test
_ = []

instance Target TargetInfo where
	targetName :: (Text -> f Text) -> TargetInfo -> f TargetInfo
targetName = (Maybe Text -> f (Maybe Text)) -> TargetInfo -> f TargetInfo
Lens' TargetInfo (Maybe Text)
targetInfoName ((Maybe Text -> f (Maybe Text)) -> TargetInfo -> f TargetInfo)
-> ((Text -> f Text) -> Maybe Text -> f (Maybe Text))
-> (Text -> f Text)
-> TargetInfo
-> f TargetInfo
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Text -> f Text) -> Maybe Text -> f (Maybe Text)
forall a b. Prism (Maybe a) (Maybe b) a b
_Just
	buildInfo :: (Info -> f Info) -> TargetInfo -> f TargetInfo
buildInfo = (Info -> f Info) -> TargetInfo -> f TargetInfo
Lens' TargetInfo Info
targetBuildInfo
	targetMain :: TargetInfo -> Maybe Text
targetMain = TargetInfo -> Maybe Text
_targetInfoMain
	targetModules :: TargetInfo -> [[Text]]
targetModules = TargetInfo -> [[Text]]
_targetInfoModules