@@ -6,10 +6,19 @@
6{-# LANGUAGE OverloadedStrings #-}
6{-# LANGUAGE OverloadedStrings #-}
7{-# LANGUAGE Rank2Types #-}
7{-# LANGUAGE Rank2Types #-}
8{-# LANGUAGE ScopedTypeVariables #-}
8{-# LANGUAGE ScopedTypeVariables #-}
9+{-# LANGUAGE TemplateHaskell #-}
9{-# LANGUAGE TypeApplications #-}
10{-# LANGUAGE TypeApplications #-}
10module Obelisk.Command.Nix
11module Obelisk.Command.Nix
11− ( nixBuild
12+ ( nixCmd
14+ , nixCmdConfig_target
16+ , nixCmdConfig_builders
12 , NixBuildConfig (..)
17 , NixBuildConfig (..)
18+ , nixBuildConfig_outLink
19+ , NixInstantiateConfig (..)
20+ , nixInstantiateConfig_eval
21+ , NixCommonConfig (..)
13 , Target (..)
22 , Target (..)
14 , OutLink (..)
23 , OutLink (..)
15 , Arg (..)
24 , Arg (..)
@@ -18,6 +27,9 @@ module Obelisk.Command.Nix
30+import Control.Monad (guard)
21import Data.Bool (bool)
33import Data.Bool (bool)
22import Data.Default
34import Data.Default
23import Data.List (intercalate)
35import Data.List (intercalate)
@@ -28,20 +40,12 @@ import System.Process (proc)
28import Obelisk.App (MonadObelisk)
40import Obelisk.App (MonadObelisk)
29import Obelisk.CliApp
41import Obelisk.CliApp
31−-- | Where to put nix-build output
35− | OutLink_IndirectRoot FilePath
37−instance Default OutLink where
38− def = OutLink_Default
40-- | What to build
43-- | What to build
41data Target = Target
44data Target = Target
42 { _target_path :: FilePath
45 { _target_path :: FilePath
43 , _target_attr :: Maybe String
46 , _target_attr :: Maybe String
46instance Default Target where
50instance Default Target where
47 def = Target
51 def = Target
@@ -68,36 +72,103 @@ cliFromArgs = concatMap $ \case
68 Arg_Str k v -> ["--argstr", k, v]
72 Arg_Str k v -> ["--argstr", k, v]
69 Arg_Expr k v -> ["--arg", k, v]
73 Arg_Expr k v -> ["--arg", k, v]
71−data NixBuildConfig = NixBuildConfig
75+data NixCommonConfig = NixCommonConfig
72− { _nixBuildConfig_target :: Target
76+ { _nixCmdConfig_target :: Target
73− , _nixBuildConfig_outLink :: OutLink
77+ , _nixCmdConfig_args :: [Arg]
74− , _nixBuildConfig_args :: [Arg]
78+ , _nixCmdConfig_builders :: [String]
75− , _nixBuildConfig_builders :: [String]
80+makeClassy ''NixCommonConfig
78−instance Default NixBuildConfig where
82+instance Default NixCommonConfig where
79− def = NixBuildConfig def def mempty mempty
83+ def = NixCommonConfig def mempty mempty
81−nixBuild :: MonadObelisk m => NixBuildConfig -> m FilePath
85+runNixCommonConfig :: NixCommonConfig -> [FilePath]
82−nixBuild cfg = withSpinner' ("Running nix-build on " <> desc) (Just $ const $ "Built " <> desc) $ do
83− output <- readProcessAndLogStderr Debug $ proc "nix-build" $ mconcat
84− [[path], attrArg, args, outLink, buildersArg]
86+runNixCommonConfig cfg = mconcat [[path], attrArg, args, buildersArg]
85− -- Remove final newline that Nix appends
86− Just (outPath, '\n') <- pure $ T.unsnoc output
87− pure $ T.unpack outPath
89− path = _target_path $ _nixBuildConfig_target cfg
88+ path = _target_path $ _nixCmdConfig_target cfg
90− attr = _target_attr $ _nixBuildConfig_target cfg
89+ attr = _target_attr $ _nixCmdConfig_target cfg
91 attrArg = case attr of
90 attrArg = case attr of
92 Nothing -> []
91 Nothing -> []
93 Just a -> ["-A", a]
92 Just a -> ["-A", a]
94− args = cliFromArgs $ _nixBuildConfig_args cfg
93+ args = cliFromArgs $ _nixCmdConfig_args cfg
94+ buildersArg = case _nixCmdConfig_builders cfg of
96+ builders -> ["--builders", intercalate ";" builders]
98+-- | Where to put nix-build output
102+ | OutLink_IndirectRoot FilePath
104+instance Default OutLink where
105+ def = OutLink_Default
107+data NixBuildConfig = NixBuildConfig
108+ { _nixBuildConfig_common :: NixCommonConfig
109+ , _nixBuildConfig_outLink :: OutLink
111+makeLenses ''NixBuildConfig
113+instance HasNixCommonConfig NixBuildConfig where
114+ nixCommonConfig = nixBuildConfig_common
116+instance Default NixBuildConfig where
117+ def = NixBuildConfig def def
119+runNixBuildConfig :: NixBuildConfig -> [FilePath]
120+runNixBuildConfig cfg = mconcat
121+ [ runNixCommonConfig $ cfg ^. nixCommonConfig
95− outLink = case _nixBuildConfig_outLink cfg of
122+ , case _nixBuildConfig_outLink cfg of
96 OutLink_Default -> []
123 OutLink_Default -> []
97 OutLink_None -> ["--no-out-link"]
124 OutLink_None -> ["--no-out-link"]
98 OutLink_IndirectRoot l -> ["--out-link", l]
125 OutLink_IndirectRoot l -> ["--out-link", l]
99− desc = T.pack $ path <> maybe "" (\a -> " [" <> a <> "]") attr
126+ ]
100− buildersArg = case _nixBuildConfig_builders cfg of
102− builders -> ["--builders", intercalate ";" builders]
128+data NixInstantiateConfig = NixInstantiateConfig
129+ { _nixInstantiateConfig_common :: NixCommonConfig
130+ , _nixInstantiateConfig_eval :: Bool
132+makeLenses ''NixInstantiateConfig
134+instance HasNixCommonConfig NixInstantiateConfig where
135+ nixCommonConfig = nixInstantiateConfig_common
137+instance Default NixInstantiateConfig where
138+ def = NixInstantiateConfig def False
140+runNixInstantiateConfig :: NixInstantiateConfig -> [FilePath]
141+runNixInstantiateConfig cfg = mconcat
142+ [ runNixCommonConfig $ cfg ^. nixCommonConfig
143+ , "--eval" <$ guard (_nixInstantiateConfig_eval cfg)
147+ = NixCmd_Build NixBuildConfig
148+ | NixCmd_Instantiate NixInstantiateConfig
150+instance Default NixCmd where
151+ def = NixCmd_Build def
153+nixCmd :: MonadObelisk m => NixCmd -> m FilePath
154+nixCmd cmdCfg = withSpinner' ("Running " <> cmd <> " on " <> desc) (Just $ const $ "Built " <> desc) $ do
155+ output <- readProcessAndLogStderr Debug $ proc (T.unpack cmd) $ options
156+ -- Remove final newline that Nix appends
157+ Just (outPath, '\n') <- pure $ T.unsnoc output
158+ pure $ T.unpack outPath
160+ (cmd, options, commonCfg) = case cmdCfg of
161+ NixCmd_Build cfg' ->
163+ , runNixBuildConfig cfg'
164+ , cfg' ^. nixCommonConfig
166+ NixCmd_Instantiate cfg' ->
168+ , runNixInstantiateConfig cfg'
169+ , cfg' ^. nixCommonConfig
171+ path = commonCfg ^. nixCmdConfig_target . target_path
172+ desc = T.pack $ path <> maybe ""
173+ (\a -> " [" <> a <> "]")
174+ (commonCfg ^. nixCmdConfig_target . target_attr)