22{-# LANGUAGE ScopedTypeVariables #-}
33{-# LANGUAGE TypeFamilies #-}
44{-# LANGUAGE ViewPatterns #-}
5+ {-# LANGUAGE RecordWildCards #-}
56
6- module Main where
7+ module Main ( main ) where
78
89import Nix.Utils
910import Control.Comonad ( extract )
@@ -46,59 +47,61 @@ main =
4647 time <- getCurrentTime
4748 opts <- execParser $ nixOptionsInfo time
4849
49- runWithBasicEffectsIO opts $ execContentsFilesOrRepl opts
50+ main' opts
5051
52+ main' :: Options -> IO ()
53+ main' (opts@ Options {.. }) = runWithBasicEffectsIO opts execContentsFilesOrRepl
5154 where
52- execContentsFilesOrRepl opts =
53- maybe
54- (maybe
55- (maybe
56- (list
57- (withNixContext mempty Repl. main) -- run REPL
58- (\ case
59- [" -" ] -> handleResult opts mempty . parseNixTextLoc =<< liftIO Text. getContents
60- _paths -> traverse_ (processFile opts) _paths
61- )
62- (filePaths opts)
63- )
64- (\ x ->
65- -- We can start use Text as in the base case, requires changing FilePath -> Text
66- traverse_ (processFile opts) . String. lines =<< liftIO
67- (case x of
68- " -" -> getContents -- get user input
69- _path -> readFile _path
70- )
71- )
72- (fromFile opts)
73- )
74- (handleResult opts mempty . parseNixTextLoc)
75- (expression opts)
76- )
77- (\ path ->
78- do
55+ execContentsFilesOrRepl =
56+ firstJust
57+ -- The `--read` option: load expression from a serialized file.
58+ [ readFrom <&> \ path -> do
7959 let file = addExtension (dropExtension path) " nixc"
80- process opts (pure file) =<< liftIO (readCache path)
81- )
82- (readFrom opts)
60+ process (Just file) =<< liftIO (readCache path)
8361
84- processFile opts path =
85- do
86- eres <- parseNixFileLoc path
87- handleResult opts (pure path) eres
62+ -- The `--expr` option: read expression from the argument string
63+ , expression <&> processText
64+
65+ -- The `--file` argument: read expressions from the files listed in the argument file
66+ , fromFile <&> \ x ->
67+ -- We can start use Text as in the base case, requires changing FilePath -> Text
68+ traverse_ processFile . String. lines =<< liftIO
69+ (case x of
70+ " -" -> getContents
71+ fp -> readFile fp
72+ )
73+ ]
74+ `orElse`
75+ -- The base case: read expressions from the files listed on the command line
76+ case filePaths of
77+ -- With no files, fall back to running the REPL
78+ [] -> withNixContext mempty Repl. main
79+ [" -" ] -> processText =<< liftIO Text. getContents
80+ _paths -> traverse_ processFile _paths
81+
82+ firstJust :: [Maybe a ] -> Maybe a
83+ firstJust = asum
84+
85+ orElse :: Maybe a -> a -> a
86+ orElse = flip fromMaybe
87+
88+ processText text = handleResult Nothing $ parseNixTextLoc text
89+
90+ processFile path = handleResult (Just path) =<< parseNixFileLoc path
8891
89- handleResult opts mpath =
92+ handleResult mpath =
9093 either
9194 (\ err ->
9295 bool
9396 errorWithoutStackTrace
9497 (liftIO . hPutStrLn stderr)
95- ( ignoreErrors opts)
98+ ignoreErrors
9699 $ " Parse failed: " <> show err
97100 )
98101
99102 (\ expr ->
100103 do
101- when ( check opts) $
104+ when check $
102105 do
103106 expr' <- liftIO (reduceExpr mpath expr)
104107 either
@@ -111,7 +114,7 @@ main =
111114 -- liftIO $ putStrLn $ runST $
112115 -- runLintM opts . renderSymbolic =<< lint opts expr
113116
114- catch (process opts mpath expr) $
117+ catch (process mpath expr) $
115118 \ case
116119 NixException frames ->
117120 errorWithoutStackTrace . show =<<
@@ -120,53 +123,50 @@ main =
120123 @ (StdThunk (StandardT (StdIdT IO )))
121124 frames
122125
123- when ( repl opts) $
126+ when repl $
124127 withNixContext mempty $
125128 bool
126129 Repl. main
127130 (do
128131 val <- Nix. nixEvalExprLoc mpath expr
129132 Repl. main' $ pure val
130133 )
131- ( evaluate opts)
134+ evaluate
132135 )
133136
134- process opts mpath expr
135- | evaluate opts =
137+ process mpath expr
138+ | evaluate =
136139 if
137- | tracing opts -> evaluateExpression mpath Nix. nixTracingEvalExprLoc printer expr
138- | Just path <- reduce opts -> evaluateExpression mpath (reduction path) printer expr
139- | not ( null (arg opts)
140- && null (argstr opts)
141- ) -> evaluateExpression mpath Nix. nixEvalExprLoc printer expr
142- | otherwise -> processResult printer =<< Nix. nixEvalExprLoc mpath expr
143- | xml opts = fail " Rendering expression trees to XML is not yet implemented"
144- | json opts = fail " Rendering expression trees to JSON is not implemented"
145- | verbose opts >= DebugInfo = liftIO $ putStr $ PS. ppShow $ stripAnnotation expr
146- | cache opts
147- , Just path <- mpath = liftIO $ writeCache (addExtension (dropExtension path) " nixc" ) expr
148- | parseOnly opts = void $ liftIO $ Exc. evaluate $ Deep. force expr
149- | otherwise =
140+ | tracing -> evaluateExpression mpath Nix. nixTracingEvalExprLoc printer expr
141+ | Just path <- reduce -> evaluateExpression mpath (reduction path) printer expr
142+ | not (null arg && null argstr) -> evaluateExpression mpath Nix. nixEvalExprLoc printer expr
143+ | otherwise -> processResult printer =<< Nix. nixEvalExprLoc mpath expr
144+ | xml = fail " Rendering expression trees to XML is not yet implemented"
145+ | json = fail " Rendering expression trees to JSON is not implemented"
146+ | verbose >= DebugInfo = liftIO $ putStr $ PS. ppShow $ stripAnnotation expr
147+ | cache , Just path <- mpath = liftIO $ writeCache (addExtension (dropExtension path) " nixc" ) expr
148+ | parseOnly = void $ liftIO $ Exc. evaluate $ Deep. force expr
149+ | otherwise =
150150 liftIO $
151151 renderIO
152152 stdout
153153 . layoutPretty (LayoutOptions $ AvailablePerLine 80 0.4 )
154154 . prettyNix
155- . stripAnnotation $
156- expr
155+ . stripAnnotation
156+ $ expr
157157 where
158158 printer
159- | finder opts = findAttrs <=< fromValue @ (AttrSet (StdValue (StandardT (StdIdT IO ))))
160- | xml opts = liftIO . Text. putStrLn . stringIgnoreContext . toXML <=< normalForm
159+ | finder = findAttrs <=< fromValue @ (AttrSet (StdValue (StandardT (StdIdT IO ))))
160+ | xml = liftIO . Text. putStrLn . stringIgnoreContext . toXML <=< normalForm
161161 -- 2021-05-27: NOTE: With naive fix of the #941
162162 -- This is overall a naive printer implementation, as options should interact/respect one another.
163163 -- A nice question: "Should respect one another to what degree?": Go full combinator way, for which
164164 -- old Nix CLI is nototrious for (and that would mean to reimplement the old Nix CLI),
165165 -- OR: https://github.com/haskell-nix/hnix/issues/172 and have some sane standart/default behaviour for (most) keys.
166- | json opts = liftIO . Text. putStrLn . stringIgnoreContext <=< nvalueToJSONNixString <=< normalForm
167- | strict opts = liftIO . print . prettyNValue <=< normalForm
168- | values opts = liftIO . print . prettyNValueProv <=< removeEffects
169- | otherwise = liftIO . print . prettyNValue <=< removeEffects
166+ | json = liftIO . Text. putStrLn . stringIgnoreContext <=< nvalueToJSONNixString <=< normalForm
167+ | strict = liftIO . print . prettyNValue <=< normalForm
168+ | values = liftIO . print . prettyNValueProv <=< removeEffects
169+ | otherwise = liftIO . print . prettyNValue <=< removeEffects
170170 where
171171 findAttrs
172172 :: AttrSet (StdValue (StandardT (StdIdT IO )))
0 commit comments