{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric  #-}

module Package.C.Type ( CPkg (..)
                      , BuildVars (..)
                      , Verbosity (..)
                      , EnvVar (..)
                      , Command (..)
                      , Dep (..)
                      , Version (..)
                      , OS (..)
                      , TargetTriple (..)
                      -- * Helper functions
                      , cPkgDhallToCPkg
                      , showVersion
                      ) where

import           CPkgPrelude
import qualified Data.Text                as T
import           GHC.Generics             (Generic)
import qualified Package.C.Dhall.Type     as Dhall
import           Package.C.Triple.Type
import           Package.C.Type.Shared
import           Package.C.Type.Vars
import           Package.C.Type.Verbosity
import           Package.C.Type.Version

data EnvVar = EnvVar { EnvVar -> String
var :: String, EnvVar -> String
value :: String }
            deriving (EnvVar -> EnvVar -> Bool
(EnvVar -> EnvVar -> Bool)
-> (EnvVar -> EnvVar -> Bool) -> Eq EnvVar
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: EnvVar -> EnvVar -> Bool
== :: EnvVar -> EnvVar -> Bool
$c/= :: EnvVar -> EnvVar -> Bool
/= :: EnvVar -> EnvVar -> Bool
Eq, Eq EnvVar
Eq EnvVar =>
(EnvVar -> EnvVar -> Ordering)
-> (EnvVar -> EnvVar -> Bool)
-> (EnvVar -> EnvVar -> Bool)
-> (EnvVar -> EnvVar -> Bool)
-> (EnvVar -> EnvVar -> Bool)
-> (EnvVar -> EnvVar -> EnvVar)
-> (EnvVar -> EnvVar -> EnvVar)
-> Ord EnvVar
EnvVar -> EnvVar -> Bool
EnvVar -> EnvVar -> Ordering
EnvVar -> EnvVar -> EnvVar
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
$ccompare :: EnvVar -> EnvVar -> Ordering
compare :: EnvVar -> EnvVar -> Ordering
$c< :: EnvVar -> EnvVar -> Bool
< :: EnvVar -> EnvVar -> Bool
$c<= :: EnvVar -> EnvVar -> Bool
<= :: EnvVar -> EnvVar -> Bool
$c> :: EnvVar -> EnvVar -> Bool
> :: EnvVar -> EnvVar -> Bool
$c>= :: EnvVar -> EnvVar -> Bool
>= :: EnvVar -> EnvVar -> Bool
$cmax :: EnvVar -> EnvVar -> EnvVar
max :: EnvVar -> EnvVar -> EnvVar
$cmin :: EnvVar -> EnvVar -> EnvVar
min :: EnvVar -> EnvVar -> EnvVar
Ord, (forall x. EnvVar -> Rep EnvVar x)
-> (forall x. Rep EnvVar x -> EnvVar) -> Generic EnvVar
forall x. Rep EnvVar x -> EnvVar
forall x. EnvVar -> Rep EnvVar x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. EnvVar -> Rep EnvVar x
from :: forall x. EnvVar -> Rep EnvVar x
$cto :: forall x. Rep EnvVar x -> EnvVar
to :: forall x. Rep EnvVar x -> EnvVar
Generic, Get EnvVar
[EnvVar] -> Put
EnvVar -> Put
(EnvVar -> Put) -> Get EnvVar -> ([EnvVar] -> Put) -> Binary EnvVar
forall t. (t -> Put) -> Get t -> ([t] -> Put) -> Binary t
$cput :: EnvVar -> Put
put :: EnvVar -> Put
$cget :: Get EnvVar
get :: Get EnvVar
$cputList :: [EnvVar] -> Put
putList :: [EnvVar] -> Put
Binary, Eq EnvVar
Eq EnvVar =>
(Int -> EnvVar -> Int) -> (EnvVar -> Int) -> Hashable EnvVar
Int -> EnvVar -> Int
EnvVar -> Int
forall a. Eq a => (Int -> a -> Int) -> (a -> Int) -> Hashable a
$chashWithSalt :: Int -> EnvVar -> Int
hashWithSalt :: Int -> EnvVar -> Int
$chash :: EnvVar -> Int
hash :: EnvVar -> Int
Hashable)

data Command = CreateDirectory { Command -> String
dir :: String }
             | MakeExecutable { Command -> String
file :: String }
             | Call { Command -> String
program     :: String
                    , Command -> [String]
arguments   :: [String]
                    , Command -> Maybe [EnvVar]
environment :: Maybe [EnvVar]
                    , Command -> Maybe String
procDir     :: Maybe String
                    }
             | SymlinkBinary { file :: String }
             | SymlinkManpage { file :: String, Command -> Int
section :: Int }
             | Symlink { Command -> String
tgt :: String, Command -> String
linkName :: String }
             | Write { Command -> Text
contents :: T.Text, file :: FilePath }
             | CopyFile { Command -> String
src :: FilePath, Command -> String
dest :: FilePath }
             | Patch { Command -> Text
patchContents :: T.Text }
             deriving (Command -> Command -> Bool
(Command -> Command -> Bool)
-> (Command -> Command -> Bool) -> Eq Command
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Command -> Command -> Bool
== :: Command -> Command -> Bool
$c/= :: Command -> Command -> Bool
/= :: Command -> Command -> Bool
Eq, Eq Command
Eq Command =>
(Command -> Command -> Ordering)
-> (Command -> Command -> Bool)
-> (Command -> Command -> Bool)
-> (Command -> Command -> Bool)
-> (Command -> Command -> Bool)
-> (Command -> Command -> Command)
-> (Command -> Command -> Command)
-> Ord Command
Command -> Command -> Bool
Command -> Command -> Ordering
Command -> Command -> Command
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
$ccompare :: Command -> Command -> Ordering
compare :: Command -> Command -> Ordering
$c< :: Command -> Command -> Bool
< :: Command -> Command -> Bool
$c<= :: Command -> Command -> Bool
<= :: Command -> Command -> Bool
$c> :: Command -> Command -> Bool
> :: Command -> Command -> Bool
$c>= :: Command -> Command -> Bool
>= :: Command -> Command -> Bool
$cmax :: Command -> Command -> Command
max :: Command -> Command -> Command
$cmin :: Command -> Command -> Command
min :: Command -> Command -> Command
Ord, (forall x. Command -> Rep Command x)
-> (forall x. Rep Command x -> Command) -> Generic Command
forall x. Rep Command x -> Command
forall x. Command -> Rep Command x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Command -> Rep Command x
from :: forall x. Command -> Rep Command x
$cto :: forall x. Rep Command x -> Command
to :: forall x. Rep Command x -> Command
Generic, Get Command
[Command] -> Put
Command -> Put
(Command -> Put)
-> Get Command -> ([Command] -> Put) -> Binary Command
forall t. (t -> Put) -> Get t -> ([t] -> Put) -> Binary t
$cput :: Command -> Put
put :: Command -> Put
$cget :: Get Command
get :: Get Command
$cputList :: [Command] -> Put
putList :: [Command] -> Put
Binary, Eq Command
Eq Command =>
(Int -> Command -> Int) -> (Command -> Int) -> Hashable Command
Int -> Command -> Int
Command -> Int
forall a. Eq a => (Int -> a -> Int) -> (a -> Int) -> Hashable a
$chashWithSalt :: Int -> Command -> Int
hashWithSalt :: Int -> Command -> Int
$chash :: Command -> Int
hash :: Command -> Int
Hashable)

-- TODO: build script should take OS as an argument?
-- That way we can use make/gmake where we want it
data CPkg = CPkg { CPkg -> String
pkgName          :: String
                 , CPkg -> Version
pkgVersion       :: Version
                 , CPkg -> String
pkgUrl           :: String
                 , CPkg -> String
pkgSubdir        :: String
                 , CPkg -> [Dep]
pkgBuildDeps     :: [ Dep ]
                 , CPkg -> [Dep]
pkgDeps          :: [ Dep ]
                 , CPkg -> BuildVars -> [Command]
configureCommand :: BuildVars -> [ Command ]
                 , CPkg -> BuildVars -> [Command]
buildCommand     :: BuildVars -> [ Command ]
                 , CPkg -> BuildVars -> [Command]
installCommand   :: BuildVars -> [ Command ]
                 }

envVarDhallToEnvVar :: Dhall.EnvVar -> EnvVar
envVarDhallToEnvVar :: EnvVar -> EnvVar
envVarDhallToEnvVar (Dhall.EnvVar Text
ev Text
x) = String -> String -> EnvVar
EnvVar (Text -> String
T.unpack Text
ev) (Text -> String
T.unpack Text
x)

commandDhallToCommand :: Dhall.Command -> Command
commandDhallToCommand :: Command -> Command
commandDhallToCommand (Dhall.CreateDirectory Text
d)   = String -> Command
CreateDirectory (Text -> String
T.unpack Text
d)
commandDhallToCommand (Dhall.MakeExecutable Text
exe)  = String -> Command
MakeExecutable (Text -> String
T.unpack Text
exe)
commandDhallToCommand (Dhall.Call Text
p [Text]
as Maybe [EnvVar]
env Maybe Text
proc)  = String -> [String] -> Maybe [EnvVar] -> Maybe String -> Command
Call (Text -> String
T.unpack Text
p) (Text -> String
T.unpack (Text -> String) -> [Text] -> [String]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Text]
as) ((EnvVar -> EnvVar) -> [EnvVar] -> [EnvVar]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap EnvVar -> EnvVar
envVarDhallToEnvVar ([EnvVar] -> [EnvVar]) -> Maybe [EnvVar] -> Maybe [EnvVar]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe [EnvVar]
env) (Text -> String
T.unpack (Text -> String) -> Maybe Text -> Maybe String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Text
proc)
commandDhallToCommand (Dhall.SymlinkBinary Text
b)     = String -> Command
SymlinkBinary (Text -> String
T.unpack Text
b)
commandDhallToCommand (Dhall.SymlinkManpage Text
b Natural
s)  = String -> Int -> Command
SymlinkManpage (Text -> String
T.unpack Text
b) (Natural -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Natural
s)
commandDhallToCommand (Dhall.Write Text
out Text
fp)        = Text -> String -> Command
Write Text
out (Text -> String
T.unpack Text
fp)
commandDhallToCommand (Dhall.CopyFile Text
src' Text
dest') = String -> String -> Command
CopyFile (Text -> String
T.unpack Text
src') (Text -> String
T.unpack Text
dest')
commandDhallToCommand (Dhall.Symlink Text
t Text
l)         = String -> String -> Command
Symlink (Text -> String
T.unpack Text
t) (Text -> String
T.unpack Text
l)
commandDhallToCommand (Dhall.Patch Text
c)             = Text -> Command
Patch Text
c

buildVarsToDhallBuildVars :: BuildVars -> Dhall.BuildVars
buildVarsToDhallBuildVars :: BuildVars -> BuildVars
buildVarsToDhallBuildVars (BuildVars String
dir' String
cd Maybe TargetTriple
tgt' Bool
cross [String]
incls [String]
prelds [String]
shr [String]
lds [String]
bins OS
os' Arch
arch' Bool
sta Int
nproc) = Text
-> Text
-> Maybe TargetTriple
-> Bool
-> [Text]
-> [Text]
-> [Text]
-> [Text]
-> [Text]
-> OS
-> Arch
-> Bool
-> Natural
-> BuildVars
Dhall.BuildVars (String -> Text
T.pack String
dir') (String -> Text
T.pack String
cd) Maybe TargetTriple
tgt' Bool
cross (String -> Text
T.pack (String -> Text) -> [String] -> [Text]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [String]
incls) (String -> Text
T.pack (String -> Text) -> [String] -> [Text]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [String]
prelds) (String -> Text
T.pack (String -> Text) -> [String] -> [Text]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [String]
shr) (String -> Text
T.pack (String -> Text) -> [String] -> [Text]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [String]
lds) (String -> Text
T.pack (String -> Text) -> [String] -> [Text]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [String]
bins) OS
os' Arch
arch' Bool
sta (Int -> Natural
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
nproc)

cPkgDhallToCPkg :: Dhall.CPkg -> CPkg
cPkgDhallToCPkg :: CPkg -> CPkg
cPkgDhallToCPkg (Dhall.CPkg Text
n [Natural]
v Text
url Text
subdir [Dep]
bldDeps [Dep]
deps BuildVars -> [Command]
cfgCmd BuildVars -> [Command]
buildCmd BuildVars -> [Command]
installCmd) =
    String
-> Version
-> String
-> String
-> [Dep]
-> [Dep]
-> (BuildVars -> [Command])
-> (BuildVars -> [Command])
-> (BuildVars -> [Command])
-> CPkg
CPkg (Text -> String
T.unpack Text
n) ([Natural] -> Version
Version [Natural]
v) (Text -> String
T.unpack Text
url) (Text -> String
T.unpack Text
subdir) [Dep]
bldDeps [Dep]
deps BuildVars -> [Command]
configure BuildVars -> [Command]
build BuildVars -> [Command]
install

    where configure :: BuildVars -> [Command]
configure BuildVars
cfg = Command -> Command
commandDhallToCommand (Command -> Command) -> [Command] -> [Command]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> BuildVars -> [Command]
cfgCmd (BuildVars -> BuildVars
buildVarsToDhallBuildVars BuildVars
cfg)
          build :: BuildVars -> [Command]
build BuildVars
cfg = Command -> Command
commandDhallToCommand (Command -> Command) -> [Command] -> [Command]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> BuildVars -> [Command]
buildCmd (BuildVars -> BuildVars
buildVarsToDhallBuildVars BuildVars
cfg)
          install :: BuildVars -> [Command]
install BuildVars
cfg = Command -> Command
commandDhallToCommand (Command -> Command) -> [Command] -> [Command]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> BuildVars -> [Command]
installCmd (BuildVars -> BuildVars
buildVarsToDhallBuildVars BuildVars
cfg)