{-# LANGUAGE DeriveAnyClass #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE OverloadedStrings #-} module Language.ATS.Package.Type ( Pkg (..) , Bin (..) , printConfig , pkgToAction , mkPkg , mkManpage ) where import Control.Composition import Control.Monad.IO.Class (MonadIO) import Data.Maybe (fromMaybe) import Data.Semigroup (Semigroup (..)) import qualified Data.Text.Lazy as TL import Development.Shake import Development.Shake.ATS import Development.Shake.FilePath import Development.Shake.Man import Dhall options :: ShakeOptions options = shakeOptions { shakeFiles = ".atspkg" , shakeThreads = 4 } mkPkg :: IO () mkPkg = shakeArgs options $ mkTest >> mkClean >> mkManpage >> mkInstall >> (pkgToAction =<< getConfig) mkManpage :: Rules () mkManpage = do c <- getConfig case man c of Just _ -> manpages _ -> pure () getConfig :: MonadIO m => m Pkg getConfig = liftIO (input auto "./atspkg.dhall") manTarget :: Text -> FilePath manTarget m = TL.unpack m -<.> "1" mkInstall :: Rules () mkInstall = "install" ~> do config <- getConfig bins <- fmap (TL.unpack . target) . bin <$> getConfig need bins home <- fromMaybe "" <$> getEnv "HOME" let binDest = fmap (((home <> "/.local/bin/") <>) . takeBaseName) bins void $ zipWithM copyFile' bins binDest case man config of Just mt -> do let mt' = manTarget mt manDest = (home <> "/.local/share/man/man1/") <> mt' need [mt'] copyFile' mt' manDest Nothing -> pure () mkClean :: Rules () mkClean = "clean" ~> do removeFilesAfter "." ["//*.1","//*.c", "tags"] removeFilesAfter ".shake" ["//*"] removeFilesAfter "target" ["//*"] mkTest :: Rules () mkTest = "test" ~> do config <- getConfig let tests = fmap (TL.unpack . target) . test $ config need tests mapM_ cmd_ tests pkgToAction :: Pkg -> Rules () pkgToAction (Pkg bs ts mt v) = do action (need ["atspkg.dhall"]) mapM_ g (bs ++ ts) let bins = TL.unpack . target <$> bs case mt of (Just m) -> want (manTarget m : bins) Nothing -> want bins where g (Bin s t ls gc') = atsBin (Version v) gc' (TL.unpack <$> ls) (TL.unpack s) (TL.unpack t) -- TODO configuration for a library? data Bin = Bin { src :: Text, target :: Text, libs :: [Text], gc :: Bool } deriving (Show, Eq, Generic, Interpret) data Pkg = Pkg { bin :: [Bin], test :: [Bin], man :: Maybe Text, version :: [Integer] } deriving (Show, Eq, Generic, Interpret) printConfig :: IO () printConfig = do x <- input auto "./atspkg.dhall" print (x :: Pkg)