hnix/main/Main.hs

147 lines
5.4 KiB
Haskell
Raw Normal View History

{-# LANGUAGE FlexibleContexts #-}
2018-04-06 06:10:06 +02:00
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE MultiWayIf #-}
2018-04-12 06:31:48 +02:00
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
module Main where
2018-04-14 18:44:55 +02:00
import qualified Control.DeepSeq as Deep
2018-04-10 17:34:21 +02:00
import qualified Control.Exception as Exc
import Control.Monad
import Control.Monad.Catch
import Control.Monad.IO.Class
import Control.Monad.ST
import qualified Data.Aeson.Encoding as A
import qualified Data.Aeson.Text as A
import qualified Data.Text.IO as Text
import qualified Data.Text.Lazy.Encoding as TL
import qualified Data.Text.Lazy.IO as TL
2018-04-14 18:44:55 +02:00
import Nix
import Nix.Convert
import qualified Nix.Eval as Eval
import Nix.Lint
import Nix.Utils
import Options.Applicative hiding (ParserResult(..))
import qualified Repl
import System.FilePath
import System.IO
import Text.PrettyPrint.ANSI.Leijen hiding ((<$>))
main :: IO ()
main = do
opts <- execParser nixOptionsInfo
2018-04-24 21:25:40 +02:00
runLazyM opts $ case readFrom opts of
Just path -> do
let file = addExtension (dropExtension path) "nix"
2018-04-24 21:25:40 +02:00
process opts (Just file) =<< liftIO (readCache path)
Nothing -> case expression opts of
Just s -> handleResult opts Nothing (parseNixTextLoc s)
Nothing -> case fromFile opts of
Just "-" ->
2018-04-24 21:25:40 +02:00
mapM_ (processFile opts)
=<< (lines <$> liftIO getContents)
Just path ->
2018-04-24 21:25:40 +02:00
mapM_ (processFile opts)
=<< (lines <$> liftIO (readFile path))
Nothing -> case filePaths opts of
[] -> Repl.shell (pure ())
["-"] ->
handleResult opts Nothing . parseNixTextLoc
2018-04-24 21:25:40 +02:00
=<< liftIO Text.getContents
paths ->
mapM_ (processFile opts) paths
where
processFile opts path = do
eres <- parseNixFileLoc path
handleResult opts (Just path) eres
handleResult opts mpath = \case
Failure err ->
(if ignoreErrors opts
2018-04-24 21:25:40 +02:00
then liftIO . hPutStrLn stderr
else errorWithoutStackTrace) $ "Parse failed: " ++ show err
2018-04-24 21:25:40 +02:00
Success expr -> do
when (check opts) $
liftIO $ putStrLn $ runST $
runLintM opts . renderSymbolic =<< lint opts expr
2018-04-09 11:07:40 +02:00
2018-04-24 21:25:40 +02:00
catch (process opts mpath expr) $ \case
NixException frames ->
errorWithoutStackTrace . show
=<< renderFrames @(NThunk (Lazy IO)) frames
2018-04-24 21:25:40 +02:00
when (repl opts) $ Repl.shell (pure ())
2018-04-24 21:25:40 +02:00
process opts mpath expr = do
let printer :: (MonadNix e m, MonadIO m) => NValue m -> m ()
printer | xml opts =
liftIO . putStrLn . toXML <=< normalForm
| json opts =
liftIO . TL.putStrLn
. TL.decodeUtf8
. A.encodingToLazyByteString
. toEncodingSorted
<=< fromNix
| normalize opts =
2018-04-28 05:08:47 +02:00
liftIO . print . prettyNValueNF <=< normalForm
| values opts =
2018-04-28 06:00:45 +02:00
liftIO . print <=< prettyNValueProv
| otherwise =
2018-04-28 06:00:45 +02:00
liftIO . print <=< prettyNValue
if | evaluate opts, tracing opts ->
2018-04-24 21:25:40 +02:00
evaluateExpression mpath
Nix.nixTracingEvalExprLoc printer expr
| evaluate opts, Just path <- reduce opts ->
evaluateExpression mpath (reduction path) printer expr
2018-04-12 06:31:48 +02:00
| evaluate opts, not (null (arg opts) && null (argstr opts)) ->
2018-04-24 21:25:40 +02:00
evaluateExpression mpath
Nix.nixEvalExprLoc printer expr
2018-04-12 06:31:48 +02:00
2018-04-24 21:25:40 +02:00
| evaluate opts ->
processResult printer =<< Nix.nixEvalExprLoc mpath expr
2018-04-12 06:31:48 +02:00
| xml opts ->
error "Rendering expression trees to XML is not yet implemented"
| json opts ->
2018-04-24 21:25:40 +02:00
liftIO $ TL.putStrLn $
A.encodeToLazyText (stripAnnotation expr)
2018-04-24 21:25:40 +02:00
| verbose opts >= DebugInfo ->
liftIO $ print $ stripAnnotation expr
2018-04-12 06:31:48 +02:00
| cache opts, Just path <- mpath ->
2018-04-24 21:25:40 +02:00
liftIO $ writeCache (addExtension (dropExtension path) "nixc") expr
2018-04-12 06:31:48 +02:00
2018-04-24 21:25:40 +02:00
| parseOnly opts ->
void $ liftIO $ Exc.evaluate $ Deep.force expr
2018-04-12 06:31:48 +02:00
| otherwise ->
2018-04-24 21:25:40 +02:00
liftIO $ displayIO stdout
. renderPretty 0.4 80
. prettyNix
. stripAnnotation $ expr
reduction path mp x = do
eres <- Nix.withNixContext mp $
Nix.reducingEvalExpr (Eval.eval . annotated . getCompose) mp x
handleReduced path eres
handleReduced :: (MonadThrow m, MonadIO m)
=> FilePath
-> (NExprLoc, Either SomeException (NValue m))
-> m (NValue m)
handleReduced path (expr', eres) = do
liftIO $ do
putStrLn $ "Wrote winnowed expression tree to " ++ path
writeFile path $ show $ prettyNix (stripAnnotation expr')
case eres of
Left err -> throwM err
Right v -> return v