{-# LANGUAGE OverloadedStrings #-} module Horizon.Gen.Nix.Writers ( writeOverlay , writeMakePackageSet , writeCabal2Nix , writeDerivation , writeHaskellPackage , writeHaskellPackages ) where import Cabal2nix (Options, cabal2nix') import Control.Monad (forM_, unless, (>=>)) import Data.Map (keys, toList) import qualified Data.Text as T import Distribution.Nixpkgs.Haskell.Derivation (Derivation) import Horizon.Gen.Nix.Cabal2Nix.Options (haskellPackageToCabal2NixOptions) import Horizon.Gen.Nix.Pretty (prettyDerivation) import Horizon.Gen.Nix.Types.OverlayFile (OverlayFile (MkOverlayFile)) import Horizon.Gen.Nix.Types.PackagesDirectory (PackagesDirectory (MkPackagesDirectory)) import Horizon.Gen.Nix.Types.PackageSetFile (PackageSetFile (MkPackageSetFile)) import Horizon.Spec (HaskellPackage, Name (MkName), Overlay (MkOverlay), PackageList (MkPackageList), PackageSet (MkPackageSet), fromName, fromPackageList) import Path (File, Path, parseRelFile, toFilePath, ()) import Path.Dhall () import System.Directory (createDirectoryIfMissing, doesFileExist) import System.IO (IOMode (WriteMode), hPutStrLn, stderr, stdout, withFile) import System.IO.Silently (hSilence) import Text.PrettyPrint.HughesPJClass (render) writeOverlay :: PackagesDirectory -> OverlayFile -> Overlay -> IO () writeOverlay (MkPackagesDirectory d) (MkOverlayFile f) (MkOverlay (MkPackageList xs)) = withFile (toFilePath f) WriteMode $ \h -> do hPutStrLn h "{ pkgs, ... }:" hPutStrLn h "" hPutStrLn h "final: prev: with pkgs.haskell.lib; {" forM_ (keys xs) $ \x -> do y <- parseRelFile $ T.unpack $ fromName x <> ".nix" hPutStrLn h (" " <> T.unpack (fromName x) <> " = final.callPackage (./" <> toFilePath (d y) <> ") { };") hPutStrLn h "" hPutStrLn h "}" writeMakePackageSet :: PackagesDirectory -> PackageSetFile -> PackageSet -> IO () writeMakePackageSet (MkPackagesDirectory d) (MkPackageSetFile f) (MkPackageSet _ (MkPackageList xs)) = withFile (toFilePath f) WriteMode $ \h -> do hPutStrLn h "{ pkgs, lib, callPackage, ... }:" hPutStrLn h "" hPutStrLn h "self: with pkgs.haskell.lib; {" forM_ (keys xs) $ \x -> do y <- parseRelFile $ T.unpack $ fromName x <> ".nix" hPutStrLn h (" " <> T.unpack (fromName x) <> " = self.callPackage (./" <> toFilePath (d y) <> ") { };") hPutStrLn h "" hPutStrLn h "}" writeCabal2Nix :: Path b File -> Options -> IO () writeCabal2Nix f = hSilence [stdout, stderr] . cabal2nix' >=> either (print . render) (writeDerivation f) writeDerivation :: Path b File -> Derivation -> IO () writeDerivation f = writeFile (toFilePath f) . show . prettyDerivation writeHaskellPackage :: PackagesDirectory -> Name -> HaskellPackage -> IO () writeHaskellPackage (MkPackagesDirectory d) (MkName f) y = do let o = haskellPackageToCabal2NixOptions y createDirectoryIfMissing True (toFilePath d) f' <- parseRelFile $ T.unpack (f <> ".nix") let j = d f' q <- doesFileExist $ toFilePath j unless q $ writeCabal2Nix j o writeHaskellPackages :: PackagesDirectory -> PackageList -> IO () writeHaskellPackages d = mapM_ (uncurry $ writeHaskellPackage d) . toList . fromPackageList