module Portager.Writes where
import Control.Monad (unless)
import Control.Monad.Trans.Class (lift)
import Control.Monad.Trans.Reader (ReaderT, asks)
import Data.List (partition)
import Data.Maybe (mapMaybe)
import Data.Semigroup ((<>))
import qualified Data.Set as Set (toAscList)
import Data.Text (Text)
import qualified Data.Text as Text (unlines, unpack, unwords)
import qualified Data.Text.IO as Text (putStrLn, writeFile)
import System.Directory (createDirectoryIfMissing)
import System.FilePath (FilePath, (</>))
import Text.Printf (printf)
import Portager.DSL
import Portager.Flatten (FlatPackage(..), flattenSet)
import Portager.Options (Options(..), WorldSet)
withAtom :: FlatPackage -> Text -> Text
withAtom fp t = showText (_fpAtom fp) <> " " <> t
toPackageUseRecord :: FlatPackage -> Maybe Text
toPackageUseRecord fp
| null useflags = Nothing
| otherwise = Just $ withAtom fp $ showText useflags
where useflags = Set.toAscList $_fpUseflags fp
toPackageUse :: [FlatPackage] -> [Text]
toPackageUse = mapMaybe toPackageUseRecord
toPackageAcceptKeywordRecord :: FlatPackage -> Maybe Text
toPackageAcceptKeywordRecord fp
| null kws = Nothing
| otherwise = Just $ withAtom fp $ showText kws
where kws = Set.toAscList $_fpKeywords fp
toPackageAcceptKeywords :: [FlatPackage] -> [Text]
toPackageAcceptKeywords = mapMaybe toPackageAcceptKeywordRecord
toPackageLicenseRecord :: FlatPackage -> Maybe Text
toPackageLicenseRecord fp
| null licenses = Nothing
| otherwise = Just $ withAtom fp $ showText licenses
where licenses = Set.toAscList $_fpLicenses fp
toPackageLicense :: [FlatPackage] -> [Text]
toPackageLicense = mapMaybe toPackageLicenseRecord
toPortageSet :: SetConfiguration -> [Text]
toPortageSet = map (showText . _atom) . _setPackages
data PortageSetConfig =
PortageSetConfig
{ _portageSetName :: Name
, _portageSet :: [Text]
, _portagePackageUse :: [Text]
, _portagePackageAcceptKeywords :: [Text]
, _portagePackageLicense :: [Text]
} deriving (Eq, Show)
createPortageSetConfig :: PackageSet -> PortageSetConfig
createPortageSetConfig s =
let cfg = _setConfiguration s
flat = Set.toAscList $ flattenSet s
in PortageSetConfig
{ _portageSetName = _setName s
, _portageSet = toPortageSet cfg
, _portagePackageUse = toPackageUse flat
, _portagePackageAcceptKeywords = toPackageAcceptKeywords flat
, _portagePackageLicense = toPackageLicense flat
}
writeLines :: FilePath -> [Text] -> IO ()
writeLines fp = Text.writeFile fp . Text.unlines
writePortageSetFile :: FilePath -> FilePath -> [Text] -> ReaderT Options IO ()
writePortageSetFile dir file lns = unless (null lns) $ do
root <- asks _targetDir
lift $ createDirectoryIfMissing False (root </> dir)
lift $ writeLines (root </> dir </> file) lns
writePortageSetConfig :: Int -> PortageSetConfig -> ReaderT Options IO ()
writePortageSetConfig index (PortageSetConfig pName pSet pUseflags pKeywords pLicenses) =
do writePortageSetFile "sets" name pSet
writePortageSetFile "package.use" (printf "%02d" index <> name) pUseflags
writePortageSetFile "package.accept_keywords" name pKeywords
writePortageSetFile "package.license" name pLicenses
where name = Text.unpack pName
writePortageSetConfigs :: [WorldSet] -> [PortageSetConfig] -> ReaderT Options IO ()
writePortageSetConfigs ws cfgs =
let (process, skipped) = partition (\psc -> _portageSetName psc `elem` ws) cfgs
in do unless (null skipped) $ lift $ Text.putStrLn $ "Skipping configuration for sets not listed in world_sets files: " <> (Text.unwords $ map _portageSetName skipped)
mapM_ (uncurry $ writePortageSetConfig) $ zip [1..] process