{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE DeriveGeneric #-}
module Control.Funflow.External.Nix
( NixConfig(..)
, NixpkgsSource(..)
, Environment(..)
, nix )where
import Control.Funflow
import Path
import Control.Funflow.ContentHashable
import Control.Funflow.ContentStore as CS
import Control.Funflow.External as E
import Data.Semigroup ((<>))
import qualified Data.Text as T
import GHC.Generics (Generic)
import Data.List
import Text.URI (URI)
import qualified Text.URI as URI
data NixpkgsSource = NIX_PATH
| NixpkgsTarball URI
deriving Generic
data NixConfig =
NixShellConfig {
environment :: Environment,
nixpkgsSource :: NixpkgsSource,
command :: T.Text,
args :: [ParamField],
env :: [(T.Text, Param)],
stdout :: OutputCapture
}
data Environment = ShellFile (Content File)
| PackageList [T.Text]
deriving Generic
instance ContentHashable IO Environment where
instance ContentHashable IO NixpkgsSource where
contentHashUpdate ctx NIX_PATH = contentHashUpdate_fingerprint ctx NIX_PATH
contentHashUpdate ctx (NixpkgsTarball s) = contentHashUpdate ctx (URI.render s)
nixpkgsSourceToParam :: NixpkgsSource -> Param
nixpkgsSourceToParam NIX_PATH = envParam "NIX_PATH"
nixpkgsSourceToParam (NixpkgsTarball uri) = textParam ("nixpkgs=" <> URI.render uri)
toExternal :: NixConfig -> ExternalTask
toExternal NixShellConfig{..} = ExternalTask
{ _etCommand = "nix-shell"
, _etParams =
[ "--run"
, Param [ParamCmd (Param (intersperse (ParamText " ") (ParamText command : args)))]
] ++ packageSpec environment
, _etEnv = E.EnvExplicit $ ("NIX_PATH", nixpkgsSourceToParam nixpkgsSource ) : env
, _etWriteToStdOut = stdout
}
where
packageSpec :: Environment -> [Param]
packageSpec (ShellFile ip) = [contentParam ip]
packageSpec (PackageList ps) = [textParam ("-p " <> p) | p <- ps]
nix :: (ContentHashable IO a, ArrowFlow eff ex arr) => (a -> NixConfig)
-> arr a CS.Item
nix f = external $ toExternal . f