2018-07-27 18:07:33 +02:00
|
|
|
|
{-| This module contains the top-level entrypoint and options parsing for the
|
|
|
|
|
@dhall@ executable
|
|
|
|
|
-}
|
|
|
|
|
|
2018-06-07 12:26:38 +02:00
|
|
|
|
{-# LANGUAGE DeriveAnyClass #-}
|
2019-08-03 13:03:42 +02:00
|
|
|
|
{-# LANGUAGE LambdaCase #-}
|
2018-11-26 06:24:20 +01:00
|
|
|
|
{-# LANGUAGE NamedFieldPuns #-}
|
2018-06-07 12:26:38 +02:00
|
|
|
|
{-# LANGUAGE OverloadedStrings #-}
|
|
|
|
|
{-# LANGUAGE RecordWildCards #-}
|
|
|
|
|
|
|
|
|
|
module Dhall.Main
|
2018-07-27 18:07:33 +02:00
|
|
|
|
( -- * Options
|
|
|
|
|
Options(..)
|
|
|
|
|
, Mode(..)
|
|
|
|
|
, parseOptions
|
2018-06-07 12:26:38 +02:00
|
|
|
|
, parserInfoOptions
|
2018-07-27 18:07:33 +02:00
|
|
|
|
|
|
|
|
|
-- * Execution
|
2018-06-07 12:26:38 +02:00
|
|
|
|
, command
|
|
|
|
|
, main
|
|
|
|
|
) where
|
|
|
|
|
|
2018-06-10 19:54:22 +02:00
|
|
|
|
import Control.Applicative (optional, (<|>))
|
2019-08-31 15:18:46 +02:00
|
|
|
|
import Control.Exception (Handler(..), SomeException)
|
2019-10-18 22:33:53 +02:00
|
|
|
|
import Control.Monad (when)
|
2019-07-08 12:55:15 +02:00
|
|
|
|
import Data.List.NonEmpty (NonEmpty(..))
|
2018-08-12 16:29:54 +02:00
|
|
|
|
import Data.Monoid ((<>))
|
2018-06-09 10:00:52 +02:00
|
|
|
|
import Data.Text (Text)
|
2018-09-16 17:32:01 +02:00
|
|
|
|
import Data.Text.Prettyprint.Doc (Doc, Pretty)
|
2019-10-14 07:22:39 +02:00
|
|
|
|
import Data.Void (Void)
|
2019-07-08 19:18:09 +02:00
|
|
|
|
import Dhall.Core (Expr(Annot), Import, pretty)
|
2019-06-01 18:44:01 +02:00
|
|
|
|
import Dhall.Freeze (Intent(..), Scope(..))
|
2019-10-19 04:40:27 +02:00
|
|
|
|
import Dhall.Import (Imported(..), Depends(..), SemanticCacheMode(..), _semanticCacheMode)
|
2018-06-07 12:26:38 +02:00
|
|
|
|
import Dhall.Parser (Src)
|
2019-11-04 04:31:49 +01:00
|
|
|
|
import Dhall.Pretty (Ann, CharacterSet(..), annToAnsiStyle)
|
2019-10-14 07:22:39 +02:00
|
|
|
|
import Dhall.TypeCheck (Censored(..), DetailedTypeError(..), TypeError)
|
2019-10-22 19:45:08 +02:00
|
|
|
|
import Dhall.Util (Censor(..), Header (..), Input(..), Output(..))
|
2019-09-20 17:53:13 +02:00
|
|
|
|
import Dhall.Version (dhallVersionString)
|
2018-06-07 12:26:38 +02:00
|
|
|
|
import Options.Applicative (Parser, ParserInfo)
|
2019-08-31 15:18:46 +02:00
|
|
|
|
import System.Exit (ExitCode, exitFailure)
|
2018-06-07 12:26:38 +02:00
|
|
|
|
import System.IO (Handle)
|
2019-07-08 12:55:15 +02:00
|
|
|
|
import Text.Dot ((.->.))
|
2018-06-07 12:26:38 +02:00
|
|
|
|
|
2018-11-29 02:51:20 +01:00
|
|
|
|
import qualified Codec.CBOR.JSON
|
|
|
|
|
import qualified Codec.CBOR.Read
|
|
|
|
|
import qualified Codec.CBOR.Write
|
2018-06-07 12:26:38 +02:00
|
|
|
|
import qualified Control.Exception
|
2018-08-03 15:50:03 +02:00
|
|
|
|
import qualified Control.Monad.Trans.State.Strict as State
|
2018-11-29 02:51:20 +01:00
|
|
|
|
import qualified Data.Aeson
|
|
|
|
|
import qualified Data.Aeson.Encode.Pretty
|
2018-09-18 17:33:54 +02:00
|
|
|
|
import qualified Data.ByteString.Lazy
|
2018-11-29 02:51:20 +01:00
|
|
|
|
import qualified Data.ByteString.Lazy.Char8
|
2019-11-22 04:57:14 +01:00
|
|
|
|
import qualified Data.Map
|
2018-06-09 10:00:52 +02:00
|
|
|
|
import qualified Data.Text
|
2018-06-07 12:26:38 +02:00
|
|
|
|
import qualified Data.Text.IO
|
|
|
|
|
import qualified Data.Text.Prettyprint.Doc as Pretty
|
|
|
|
|
import qualified Data.Text.Prettyprint.Doc.Render.Terminal as Pretty
|
2018-06-09 10:00:52 +02:00
|
|
|
|
import qualified Dhall
|
2018-08-03 15:50:03 +02:00
|
|
|
|
import qualified Dhall.Binary
|
2018-06-07 12:26:38 +02:00
|
|
|
|
import qualified Dhall.Core
|
2018-06-09 10:00:52 +02:00
|
|
|
|
import qualified Dhall.Diff
|
2018-06-25 17:00:11 +02:00
|
|
|
|
import qualified Dhall.Format
|
2018-06-26 19:30:54 +02:00
|
|
|
|
import qualified Dhall.Freeze
|
2018-08-03 15:50:03 +02:00
|
|
|
|
import qualified Dhall.Import
|
2018-11-26 06:24:20 +01:00
|
|
|
|
import qualified Dhall.Import.Types
|
2018-06-25 17:00:11 +02:00
|
|
|
|
import qualified Dhall.Lint
|
2019-11-21 17:20:48 +01:00
|
|
|
|
import qualified Dhall.Map
|
2019-10-19 03:59:29 +02:00
|
|
|
|
import qualified Dhall.Tags
|
2018-09-11 15:38:13 +02:00
|
|
|
|
import qualified Dhall.Pretty
|
2018-06-08 06:33:03 +02:00
|
|
|
|
import qualified Dhall.Repl
|
2018-06-07 12:26:38 +02:00
|
|
|
|
import qualified Dhall.TypeCheck
|
2019-09-14 07:01:23 +02:00
|
|
|
|
import qualified Dhall.Util
|
2018-07-14 18:20:03 +02:00
|
|
|
|
import qualified GHC.IO.Encoding
|
2018-06-07 12:26:38 +02:00
|
|
|
|
import qualified Options.Applicative
|
|
|
|
|
import qualified System.Console.ANSI
|
2019-08-31 15:18:46 +02:00
|
|
|
|
import qualified System.Exit as Exit
|
2018-06-07 12:26:38 +02:00
|
|
|
|
import qualified System.IO
|
2019-06-14 17:50:37 +02:00
|
|
|
|
import qualified System.FilePath
|
2018-11-26 06:24:20 +01:00
|
|
|
|
import qualified Text.Dot
|
2019-11-22 04:57:14 +01:00
|
|
|
|
import qualified Text.Pretty.Simple
|
2018-06-07 12:26:38 +02:00
|
|
|
|
|
2018-07-27 18:07:33 +02:00
|
|
|
|
-- | Top-level program options
|
2018-06-07 12:26:38 +02:00
|
|
|
|
data Options = Options
|
2019-09-14 07:01:23 +02:00
|
|
|
|
{ mode :: Mode
|
|
|
|
|
, explain :: Bool
|
|
|
|
|
, plain :: Bool
|
|
|
|
|
, ascii :: Bool
|
|
|
|
|
, censor :: Censor
|
2018-06-07 12:26:38 +02:00
|
|
|
|
}
|
|
|
|
|
|
2019-10-18 22:33:53 +02:00
|
|
|
|
ignoreSemanticCache :: Mode -> Bool
|
|
|
|
|
ignoreSemanticCache Default {..} = semanticCacheMode == IgnoreSemanticCache
|
2019-10-19 04:40:27 +02:00
|
|
|
|
ignoreSemanticCache Resolve {..} = semanticCacheMode == IgnoreSemanticCache
|
2019-10-19 15:47:27 +02:00
|
|
|
|
ignoreSemanticCache Type {..} = semanticCacheMode == IgnoreSemanticCache
|
2019-10-18 22:33:53 +02:00
|
|
|
|
ignoreSemanticCache _ = False
|
|
|
|
|
|
2018-07-27 18:07:33 +02:00
|
|
|
|
-- | The subcommands for the @dhall@ executable
|
2018-06-25 17:00:11 +02:00
|
|
|
|
data Mode
|
2019-09-09 22:37:30 +02:00
|
|
|
|
= Default
|
2019-09-14 07:01:23 +02:00
|
|
|
|
{ file :: Input
|
2019-10-07 11:51:30 +02:00
|
|
|
|
, output :: Output
|
2019-09-09 22:37:30 +02:00
|
|
|
|
, annotate :: Bool
|
|
|
|
|
, alpha :: Bool
|
|
|
|
|
, semanticCacheMode :: SemanticCacheMode
|
2019-09-22 05:55:26 +02:00
|
|
|
|
, version :: Bool
|
2019-09-09 22:37:30 +02:00
|
|
|
|
}
|
2018-06-25 17:00:11 +02:00
|
|
|
|
| Version
|
2019-10-19 04:40:27 +02:00
|
|
|
|
| Resolve
|
|
|
|
|
{ file :: Input
|
|
|
|
|
, resolveMode :: Maybe ResolveMode
|
|
|
|
|
, semanticCacheMode :: SemanticCacheMode
|
|
|
|
|
}
|
2019-10-19 15:47:27 +02:00
|
|
|
|
| Type
|
|
|
|
|
{ file :: Input
|
|
|
|
|
, quiet :: Bool
|
|
|
|
|
, semanticCacheMode :: SemanticCacheMode
|
|
|
|
|
}
|
2019-09-14 07:01:23 +02:00
|
|
|
|
| Normalize { file :: Input , alpha :: Bool }
|
2018-06-25 17:00:11 +02:00
|
|
|
|
| Repl
|
2019-02-07 03:19:25 +01:00
|
|
|
|
| Format { formatMode :: Dhall.Format.FormatMode }
|
2019-09-14 07:01:23 +02:00
|
|
|
|
| Freeze { inplace :: Input, all_ :: Bool, cache :: Bool }
|
2019-10-20 00:38:44 +02:00
|
|
|
|
| Hash { file :: Input }
|
2018-09-16 17:32:01 +02:00
|
|
|
|
| Diff { expr1 :: Text, expr2 :: Text }
|
2019-09-14 07:01:23 +02:00
|
|
|
|
| Lint { inplace :: Input }
|
2019-10-19 03:59:29 +02:00
|
|
|
|
| Tags
|
|
|
|
|
{ input :: Input
|
|
|
|
|
, output :: Output
|
|
|
|
|
, suffixes :: Maybe [Text]
|
|
|
|
|
, followSymlinks :: Bool
|
|
|
|
|
}
|
2019-09-14 07:01:23 +02:00
|
|
|
|
| Encode { file :: Input, json :: Bool }
|
|
|
|
|
| Decode { file :: Input, json :: Bool }
|
|
|
|
|
| Text { file :: Input }
|
2019-11-22 04:57:14 +01:00
|
|
|
|
| SyntaxTree { file :: Input }
|
2018-06-07 12:26:38 +02:00
|
|
|
|
|
2019-02-01 00:24:17 +01:00
|
|
|
|
data ResolveMode
|
2019-01-29 06:43:37 +01:00
|
|
|
|
= Dot
|
2019-02-01 00:24:17 +01:00
|
|
|
|
| ListTransitiveDependencies
|
|
|
|
|
| ListImmediateDependencies
|
|
|
|
|
|
2019-01-29 06:43:37 +01:00
|
|
|
|
|
2018-07-27 18:07:33 +02:00
|
|
|
|
-- | `Parser` for the `Options` type
|
2018-06-07 12:26:38 +02:00
|
|
|
|
parseOptions :: Parser Options
|
2018-08-03 15:50:03 +02:00
|
|
|
|
parseOptions =
|
|
|
|
|
Options
|
|
|
|
|
<$> parseMode
|
2018-09-11 15:38:13 +02:00
|
|
|
|
<*> switch "explain" "Explain error messages in more detail"
|
|
|
|
|
<*> switch "plain" "Disable syntax highlighting"
|
2018-09-16 17:32:01 +02:00
|
|
|
|
<*> switch "ascii" "Format code using only ASCII syntax"
|
2019-09-14 07:01:23 +02:00
|
|
|
|
<*> parseCensor
|
2018-06-07 12:26:38 +02:00
|
|
|
|
where
|
2018-09-11 15:38:13 +02:00
|
|
|
|
switch name description =
|
2018-06-07 12:26:38 +02:00
|
|
|
|
Options.Applicative.switch
|
2018-09-11 15:38:13 +02:00
|
|
|
|
( Options.Applicative.long name
|
|
|
|
|
<> Options.Applicative.help description
|
2018-06-07 12:26:38 +02:00
|
|
|
|
)
|
|
|
|
|
|
2019-09-14 07:01:23 +02:00
|
|
|
|
parseCensor = fmap f (switch "censor" "Hide source code in error messages")
|
|
|
|
|
where
|
|
|
|
|
f True = Censor
|
|
|
|
|
f False = NoCensor
|
|
|
|
|
|
2019-11-22 04:57:14 +01:00
|
|
|
|
subcommand' :: Bool -> String -> String -> Parser a -> Parser a
|
|
|
|
|
subcommand' internal name description parser =
|
2018-09-16 17:32:01 +02:00
|
|
|
|
Options.Applicative.hsubparser
|
|
|
|
|
( Options.Applicative.command name parserInfo
|
|
|
|
|
<> Options.Applicative.metavar name
|
2019-11-22 04:57:14 +01:00
|
|
|
|
<> if internal then Options.Applicative.internal else mempty
|
2018-09-16 17:32:01 +02:00
|
|
|
|
)
|
|
|
|
|
where
|
|
|
|
|
parserInfo =
|
|
|
|
|
Options.Applicative.info parser
|
|
|
|
|
( Options.Applicative.fullDesc
|
|
|
|
|
<> Options.Applicative.progDesc description
|
|
|
|
|
)
|
|
|
|
|
|
2019-11-22 04:57:14 +01:00
|
|
|
|
subcommand :: String -> String -> Parser a -> Parser a
|
|
|
|
|
subcommand = subcommand' False
|
|
|
|
|
|
|
|
|
|
internalSubcommand :: String -> String -> Parser a -> Parser a
|
|
|
|
|
internalSubcommand = subcommand' True
|
|
|
|
|
|
2018-06-07 12:26:38 +02:00
|
|
|
|
parseMode :: Parser Mode
|
|
|
|
|
parseMode =
|
2018-09-16 17:32:01 +02:00
|
|
|
|
subcommand
|
|
|
|
|
"version"
|
|
|
|
|
"Display version"
|
|
|
|
|
(pure Version)
|
|
|
|
|
<|> subcommand
|
|
|
|
|
"resolve"
|
|
|
|
|
"Resolve an expression's imports"
|
2019-10-19 04:40:27 +02:00
|
|
|
|
(Resolve <$> parseFile <*> parseResolveMode <*> parseSemanticCacheMode)
|
2018-09-16 17:32:01 +02:00
|
|
|
|
<|> subcommand
|
|
|
|
|
"type"
|
|
|
|
|
"Infer an expression's type"
|
2019-10-19 15:47:27 +02:00
|
|
|
|
(Type <$> parseFile <*> parseQuiet <*> parseSemanticCacheMode)
|
2018-09-16 17:32:01 +02:00
|
|
|
|
<|> subcommand
|
|
|
|
|
"normalize"
|
|
|
|
|
"Normalize an expression"
|
2019-09-14 07:01:23 +02:00
|
|
|
|
(Normalize <$> parseFile <*> parseAlpha)
|
2018-09-16 17:32:01 +02:00
|
|
|
|
<|> subcommand
|
|
|
|
|
"repl"
|
|
|
|
|
"Interpret expressions in a REPL"
|
|
|
|
|
(pure Repl)
|
|
|
|
|
<|> subcommand
|
|
|
|
|
"diff"
|
|
|
|
|
"Render the difference between the normal form of two expressions"
|
|
|
|
|
(Diff <$> argument "expr1" <*> argument "expr2")
|
|
|
|
|
<|> subcommand
|
|
|
|
|
"hash"
|
|
|
|
|
"Compute semantic hashes for Dhall expressions"
|
2019-10-20 00:38:44 +02:00
|
|
|
|
(Hash <$> parseFile)
|
2018-09-16 17:32:01 +02:00
|
|
|
|
<|> subcommand
|
|
|
|
|
"lint"
|
2019-08-31 16:00:28 +02:00
|
|
|
|
"Improve Dhall code by using newer language features and removing dead code"
|
2019-09-14 07:01:23 +02:00
|
|
|
|
(Lint <$> parseInplace)
|
2019-10-10 16:16:20 +02:00
|
|
|
|
<|> subcommand
|
|
|
|
|
"tags"
|
2019-10-19 03:59:29 +02:00
|
|
|
|
"Generate etags file"
|
|
|
|
|
(Tags <$> parseInput <*> parseTagsOutput <*> parseSuffixes <*> parseFollowSymlinks)
|
2018-09-16 17:32:01 +02:00
|
|
|
|
<|> subcommand
|
|
|
|
|
"format"
|
2019-08-31 16:00:28 +02:00
|
|
|
|
"Standard code formatter for the Dhall language"
|
2019-02-07 03:19:25 +01:00
|
|
|
|
(Format <$> parseFormatMode)
|
2018-09-16 17:32:01 +02:00
|
|
|
|
<|> subcommand
|
|
|
|
|
"freeze"
|
2019-02-01 16:46:03 +01:00
|
|
|
|
"Add integrity checks to remote import statements of an expression"
|
2019-09-14 07:01:23 +02:00
|
|
|
|
(Freeze <$> parseInplace <*> parseAllFlag <*> parseCacheFlag)
|
2018-09-18 17:33:54 +02:00
|
|
|
|
<|> subcommand
|
|
|
|
|
"encode"
|
|
|
|
|
"Encode a Dhall expression to binary"
|
2019-09-14 07:01:23 +02:00
|
|
|
|
(Encode <$> parseFile <*> parseJSONFlag)
|
2018-09-18 17:33:54 +02:00
|
|
|
|
<|> subcommand
|
|
|
|
|
"decode"
|
|
|
|
|
"Decode a Dhall expression from binary"
|
2019-09-14 07:01:23 +02:00
|
|
|
|
(Decode <$> parseFile <*> parseJSONFlag)
|
2019-07-08 19:18:09 +02:00
|
|
|
|
<|> subcommand
|
|
|
|
|
"text"
|
|
|
|
|
"Render a Dhall expression that evaluates to a Text literal"
|
2019-09-14 07:01:23 +02:00
|
|
|
|
(Text <$> parseFile)
|
2019-11-22 04:57:14 +01:00
|
|
|
|
<|> internalSubcommand
|
|
|
|
|
"haskell-syntax-tree"
|
|
|
|
|
"Output the parsed syntax tree (for debugging)"
|
|
|
|
|
(SyntaxTree <$> parseFile)
|
2019-09-22 05:55:26 +02:00
|
|
|
|
<|> ( Default
|
|
|
|
|
<$> parseFile
|
2019-10-07 11:51:30 +02:00
|
|
|
|
<*> parseOutput
|
2019-09-22 05:55:26 +02:00
|
|
|
|
<*> parseAnnotate
|
|
|
|
|
<*> parseAlpha
|
|
|
|
|
<*> parseSemanticCacheMode
|
|
|
|
|
<*> parseVersion
|
|
|
|
|
)
|
2018-06-07 12:26:38 +02:00
|
|
|
|
where
|
2018-09-16 17:32:01 +02:00
|
|
|
|
argument =
|
|
|
|
|
fmap Data.Text.pack
|
|
|
|
|
. Options.Applicative.strArgument
|
|
|
|
|
. Options.Applicative.metavar
|
|
|
|
|
|
2019-09-14 07:01:23 +02:00
|
|
|
|
parseFile = fmap f (optional p)
|
|
|
|
|
where
|
|
|
|
|
f Nothing = StandardInput
|
2019-10-10 16:16:20 +02:00
|
|
|
|
f (Just file) = InputFile file
|
2019-09-14 07:01:23 +02:00
|
|
|
|
|
|
|
|
|
p = Options.Applicative.strOption
|
|
|
|
|
( Options.Applicative.long "file"
|
|
|
|
|
<> Options.Applicative.help "Read expression from a file instead of standard input"
|
|
|
|
|
<> Options.Applicative.metavar "FILE"
|
|
|
|
|
)
|
2019-05-13 18:26:38 +02:00
|
|
|
|
|
2019-10-07 11:51:30 +02:00
|
|
|
|
parseOutput = fmap f (optional p)
|
|
|
|
|
where
|
|
|
|
|
f Nothing = StandardOutput
|
|
|
|
|
f (Just file) = OutputFile file
|
|
|
|
|
|
|
|
|
|
p = Options.Applicative.strOption
|
|
|
|
|
( Options.Applicative.long "output"
|
|
|
|
|
<> Options.Applicative.help "Write result to a file instead of standard output"
|
|
|
|
|
<> Options.Applicative.metavar "FILE"
|
|
|
|
|
)
|
|
|
|
|
|
2019-03-16 19:20:19 +01:00
|
|
|
|
parseAlpha =
|
|
|
|
|
Options.Applicative.switch
|
|
|
|
|
( Options.Applicative.long "alpha"
|
|
|
|
|
<> Options.Applicative.help "α-normalize expression"
|
|
|
|
|
)
|
|
|
|
|
|
2018-09-16 17:32:01 +02:00
|
|
|
|
parseAnnotate =
|
|
|
|
|
Options.Applicative.switch
|
2019-03-24 19:42:27 +01:00
|
|
|
|
( Options.Applicative.long "annotate"
|
|
|
|
|
<> Options.Applicative.help "Add a type annotation to the output"
|
|
|
|
|
)
|
2018-09-16 17:32:01 +02:00
|
|
|
|
|
2019-09-09 22:37:30 +02:00
|
|
|
|
parseSemanticCacheMode =
|
|
|
|
|
Options.Applicative.flag
|
|
|
|
|
UseSemanticCache
|
|
|
|
|
IgnoreSemanticCache
|
|
|
|
|
( Options.Applicative.long "no-cache"
|
|
|
|
|
<> Options.Applicative.help
|
|
|
|
|
"Handle protected imports as if the cache was empty"
|
|
|
|
|
)
|
|
|
|
|
|
2019-09-22 05:55:26 +02:00
|
|
|
|
parseVersion =
|
|
|
|
|
Options.Applicative.switch
|
|
|
|
|
( Options.Applicative.long "version"
|
|
|
|
|
<> Options.Applicative.help "Display version"
|
|
|
|
|
)
|
|
|
|
|
|
2019-01-29 06:43:37 +01:00
|
|
|
|
parseResolveMode =
|
|
|
|
|
Options.Applicative.flag' (Just Dot)
|
|
|
|
|
( Options.Applicative.long "dot"
|
|
|
|
|
<> Options.Applicative.help
|
|
|
|
|
"Output import dependency graph in dot format"
|
|
|
|
|
)
|
|
|
|
|
<|>
|
2019-02-01 00:24:17 +01:00
|
|
|
|
Options.Applicative.flag' (Just ListImmediateDependencies)
|
|
|
|
|
( Options.Applicative.long "immediate-dependencies"
|
|
|
|
|
<> Options.Applicative.help
|
|
|
|
|
"List immediate import dependencies"
|
|
|
|
|
)
|
|
|
|
|
<|>
|
|
|
|
|
Options.Applicative.flag' (Just ListTransitiveDependencies)
|
|
|
|
|
( Options.Applicative.long "transitive-dependencies"
|
2019-01-29 06:43:37 +01:00
|
|
|
|
<> Options.Applicative.help
|
2019-11-21 17:20:48 +01:00
|
|
|
|
"List transitive import dependencies in post-order"
|
2019-01-29 06:43:37 +01:00
|
|
|
|
)
|
|
|
|
|
<|> pure Nothing
|
2018-11-26 06:24:20 +01:00
|
|
|
|
|
2019-09-19 07:45:39 +02:00
|
|
|
|
parseQuiet =
|
|
|
|
|
Options.Applicative.switch
|
|
|
|
|
( Options.Applicative.long "quiet"
|
|
|
|
|
<> Options.Applicative.help "Don't print the inferred type"
|
|
|
|
|
)
|
|
|
|
|
|
2019-09-14 07:01:23 +02:00
|
|
|
|
parseInplace = fmap f (optional p)
|
|
|
|
|
where
|
|
|
|
|
f Nothing = StandardInput
|
2019-10-10 16:16:20 +02:00
|
|
|
|
f (Just file) = InputFile file
|
2019-09-14 07:01:23 +02:00
|
|
|
|
|
|
|
|
|
p = Options.Applicative.strOption
|
|
|
|
|
( Options.Applicative.long "inplace"
|
|
|
|
|
<> Options.Applicative.help "Modify the specified file in-place"
|
|
|
|
|
<> Options.Applicative.metavar "FILE"
|
|
|
|
|
)
|
2018-09-16 17:32:01 +02:00
|
|
|
|
|
2019-10-10 16:16:20 +02:00
|
|
|
|
parseInput = fmap f (optional p)
|
|
|
|
|
where
|
|
|
|
|
f Nothing = StandardInput
|
|
|
|
|
f (Just path) = InputFile path
|
|
|
|
|
|
|
|
|
|
p = Options.Applicative.strOption
|
|
|
|
|
( Options.Applicative.long "path"
|
|
|
|
|
<> Options.Applicative.help "Index all files in path recursively. Will get list of files from STDIN if omitted."
|
|
|
|
|
<> Options.Applicative.metavar "PATH"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
parseTagsOutput = fmap f (optional p)
|
|
|
|
|
where
|
|
|
|
|
f Nothing = OutputFile "tags"
|
|
|
|
|
f (Just file) = OutputFile file
|
|
|
|
|
|
|
|
|
|
p = Options.Applicative.strOption
|
|
|
|
|
( Options.Applicative.long "output"
|
|
|
|
|
<> Options.Applicative.help "The name of the file that the tags are written to. Defaults to \"tags\""
|
|
|
|
|
<> Options.Applicative.metavar "FILENAME"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
parseSuffixes = fmap f (optional p)
|
|
|
|
|
where
|
|
|
|
|
f Nothing = Just [".dhall"]
|
|
|
|
|
f (Just "") = Nothing
|
|
|
|
|
f (Just line) = Just (Data.Text.splitOn " " line)
|
|
|
|
|
|
|
|
|
|
p = Options.Applicative.strOption
|
|
|
|
|
( Options.Applicative.long "suffixes"
|
|
|
|
|
<> Options.Applicative.help "Index only files with suffixes. \"\" to index all files."
|
|
|
|
|
<> Options.Applicative.metavar "SUFFIXES"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
parseFollowSymlinks =
|
|
|
|
|
Options.Applicative.switch
|
|
|
|
|
( Options.Applicative.long "follow-symlinks"
|
|
|
|
|
<> Options.Applicative.help "Follow symlinks when recursing directories"
|
|
|
|
|
)
|
|
|
|
|
|
2018-11-29 02:51:20 +01:00
|
|
|
|
parseJSONFlag =
|
|
|
|
|
Options.Applicative.switch
|
|
|
|
|
( Options.Applicative.long "json"
|
|
|
|
|
<> Options.Applicative.help "Use JSON representation of CBOR"
|
|
|
|
|
)
|
|
|
|
|
|
2019-02-01 16:46:03 +01:00
|
|
|
|
parseAllFlag =
|
|
|
|
|
Options.Applicative.switch
|
|
|
|
|
( Options.Applicative.long "all"
|
|
|
|
|
<> Options.Applicative.help "Add integrity checks to all imports (not just remote imports)"
|
|
|
|
|
)
|
|
|
|
|
|
2019-06-01 18:44:01 +02:00
|
|
|
|
parseCacheFlag =
|
|
|
|
|
Options.Applicative.switch
|
|
|
|
|
( Options.Applicative.long "cache"
|
|
|
|
|
<> Options.Applicative.help "Add fallback unprotected imports when using integrity checks purely for caching purposes"
|
|
|
|
|
)
|
|
|
|
|
|
2019-02-07 03:19:25 +01:00
|
|
|
|
parseCheck =
|
|
|
|
|
Options.Applicative.switch
|
|
|
|
|
( Options.Applicative.long "check"
|
|
|
|
|
<> Options.Applicative.help "Only check if the input is formatted"
|
|
|
|
|
)
|
|
|
|
|
|
2019-09-14 07:01:23 +02:00
|
|
|
|
parseFormatMode = adapt <$> parseCheck <*> parseInplace
|
2019-02-07 03:19:25 +01:00
|
|
|
|
where
|
|
|
|
|
adapt True path = Dhall.Format.Check {..}
|
|
|
|
|
adapt False inplace = Dhall.Format.Modify {..}
|
|
|
|
|
|
2018-07-27 18:07:33 +02:00
|
|
|
|
-- | `ParserInfo` for the `Options` type
|
2018-06-07 12:26:38 +02:00
|
|
|
|
parserInfoOptions :: ParserInfo Options
|
|
|
|
|
parserInfoOptions =
|
|
|
|
|
Options.Applicative.info
|
|
|
|
|
(Options.Applicative.helper <*> parseOptions)
|
|
|
|
|
( Options.Applicative.progDesc "Interpreter for the Dhall language"
|
|
|
|
|
<> Options.Applicative.fullDesc
|
|
|
|
|
)
|
|
|
|
|
|
2018-07-27 18:07:33 +02:00
|
|
|
|
-- | Run the command specified by the `Options` type
|
2018-06-07 12:26:38 +02:00
|
|
|
|
command :: Options -> IO ()
|
|
|
|
|
command (Options {..}) = do
|
2018-09-11 15:38:13 +02:00
|
|
|
|
let characterSet = case ascii of
|
|
|
|
|
True -> ASCII
|
|
|
|
|
False -> Unicode
|
|
|
|
|
|
2018-07-14 18:20:03 +02:00
|
|
|
|
GHC.IO.Encoding.setLocaleEncoding System.IO.utf8
|
2018-06-07 12:26:38 +02:00
|
|
|
|
|
2019-08-03 13:03:42 +02:00
|
|
|
|
let rootDirectory = \case
|
2019-10-10 16:16:20 +02:00
|
|
|
|
InputFile f -> System.FilePath.takeDirectory f
|
2019-09-14 07:01:23 +02:00
|
|
|
|
StandardInput -> "."
|
2019-08-03 13:03:42 +02:00
|
|
|
|
|
|
|
|
|
let toStatus = Dhall.Import.emptyStatus . rootDirectory
|
2018-08-03 15:50:03 +02:00
|
|
|
|
|
2019-09-14 07:01:23 +02:00
|
|
|
|
let getExpression = Dhall.Util.getExpression censor
|
|
|
|
|
let getExpressionAndHeader = Dhall.Util.getExpressionAndHeader censor
|
|
|
|
|
|
2019-08-31 15:18:46 +02:00
|
|
|
|
let handle io =
|
|
|
|
|
Control.Exception.catches io
|
|
|
|
|
[ Handler handleTypeError
|
|
|
|
|
, Handler handleImported
|
|
|
|
|
, Handler handleExitCode
|
|
|
|
|
]
|
2018-06-07 12:26:38 +02:00
|
|
|
|
where
|
2019-08-31 15:18:46 +02:00
|
|
|
|
handleAll e = do
|
|
|
|
|
let string = show (e :: SomeException)
|
|
|
|
|
|
|
|
|
|
if not (null string)
|
|
|
|
|
then System.IO.hPutStrLn System.IO.stderr string
|
|
|
|
|
else return ()
|
|
|
|
|
|
|
|
|
|
System.Exit.exitFailure
|
|
|
|
|
|
|
|
|
|
handleTypeError e = Control.Exception.handle handleAll $ do
|
2019-10-14 07:22:39 +02:00
|
|
|
|
let _ = e :: TypeError Src Void
|
2018-06-07 12:26:38 +02:00
|
|
|
|
System.IO.hPutStrLn System.IO.stderr ""
|
|
|
|
|
if explain
|
2019-09-22 06:44:51 +02:00
|
|
|
|
then
|
|
|
|
|
case censor of
|
|
|
|
|
Censor -> Control.Exception.throwIO (CensoredDetailed (DetailedTypeError e))
|
|
|
|
|
NoCensor -> Control.Exception.throwIO (DetailedTypeError e)
|
|
|
|
|
|
2018-06-07 12:26:38 +02:00
|
|
|
|
else do
|
|
|
|
|
Data.Text.IO.hPutStrLn System.IO.stderr "\ESC[2mUse \"dhall --explain\" for detailed errors\ESC[0m"
|
2019-09-22 06:44:51 +02:00
|
|
|
|
case censor of
|
|
|
|
|
Censor -> Control.Exception.throwIO (Censored e)
|
|
|
|
|
NoCensor -> Control.Exception.throwIO e
|
2018-06-07 12:26:38 +02:00
|
|
|
|
|
2019-08-31 15:18:46 +02:00
|
|
|
|
handleImported (Imported ps e) = Control.Exception.handle handleAll $ do
|
2019-10-14 07:22:39 +02:00
|
|
|
|
let _ = e :: TypeError Src Void
|
2018-06-07 12:26:38 +02:00
|
|
|
|
System.IO.hPutStrLn System.IO.stderr ""
|
|
|
|
|
if explain
|
|
|
|
|
then Control.Exception.throwIO (Imported ps (DetailedTypeError e))
|
|
|
|
|
else do
|
|
|
|
|
Data.Text.IO.hPutStrLn System.IO.stderr "\ESC[2mUse \"dhall --explain\" for detailed errors\ESC[0m"
|
|
|
|
|
Control.Exception.throwIO (Imported ps e)
|
|
|
|
|
|
2019-08-31 15:18:46 +02:00
|
|
|
|
handleExitCode e = do
|
|
|
|
|
Control.Exception.throwIO (e :: ExitCode)
|
2018-06-07 12:26:38 +02:00
|
|
|
|
|
2018-09-16 17:32:01 +02:00
|
|
|
|
let renderDoc :: Handle -> Doc Ann -> IO ()
|
|
|
|
|
renderDoc h doc = do
|
2019-11-04 04:31:49 +01:00
|
|
|
|
let stream = Dhall.Pretty.layout doc
|
2018-06-07 12:26:38 +02:00
|
|
|
|
|
|
|
|
|
supportsANSI <- System.Console.ANSI.hSupportsANSI h
|
|
|
|
|
let ansiStream =
|
|
|
|
|
if supportsANSI && not plain
|
|
|
|
|
then fmap annToAnsiStyle stream
|
|
|
|
|
else Pretty.unAnnotateS stream
|
|
|
|
|
|
|
|
|
|
Pretty.renderIO h ansiStream
|
|
|
|
|
Data.Text.IO.hPutStrLn h ""
|
|
|
|
|
|
2019-09-05 06:41:44 +02:00
|
|
|
|
let render :: Pretty a => Handle -> Expr Src a -> IO ()
|
2018-09-16 17:32:01 +02:00
|
|
|
|
render h expression = do
|
|
|
|
|
let doc = Dhall.Pretty.prettyCharacterSet characterSet expression
|
|
|
|
|
|
|
|
|
|
renderDoc h doc
|
2019-10-07 11:51:30 +02:00
|
|
|
|
|
2019-10-18 22:33:53 +02:00
|
|
|
|
when (not $ ignoreSemanticCache mode) Dhall.Import.warnAboutMissingCaches
|
2018-09-16 17:32:01 +02:00
|
|
|
|
|
2018-06-07 12:26:38 +02:00
|
|
|
|
handle $ case mode of
|
|
|
|
|
Version -> do
|
2019-09-20 17:53:13 +02:00
|
|
|
|
putStrLn dhallVersionString
|
2018-06-07 12:26:38 +02:00
|
|
|
|
|
2018-08-12 16:29:54 +02:00
|
|
|
|
Default {..} -> do
|
2019-09-22 05:55:26 +02:00
|
|
|
|
if version
|
|
|
|
|
then do
|
|
|
|
|
putStrLn dhallVersionString
|
|
|
|
|
Exit.exitSuccess
|
|
|
|
|
else return ()
|
|
|
|
|
|
2019-05-13 18:26:38 +02:00
|
|
|
|
expression <- getExpression file
|
2018-06-07 12:26:38 +02:00
|
|
|
|
|
2019-09-09 22:37:30 +02:00
|
|
|
|
resolvedExpression <-
|
|
|
|
|
Dhall.Import.loadRelativeTo (rootDirectory file) semanticCacheMode expression
|
2018-06-07 12:26:38 +02:00
|
|
|
|
|
2019-04-24 22:01:46 +02:00
|
|
|
|
inferredType <- Dhall.Core.throws (Dhall.TypeCheck.typeOf resolvedExpression)
|
2018-06-07 12:26:38 +02:00
|
|
|
|
|
2018-08-12 16:29:54 +02:00
|
|
|
|
let normalizedExpression = Dhall.Core.normalize resolvedExpression
|
2018-06-07 12:26:38 +02:00
|
|
|
|
|
2019-03-16 19:20:19 +01:00
|
|
|
|
let alphaNormalizedExpression =
|
|
|
|
|
if alpha
|
|
|
|
|
then Dhall.Core.alphaNormalize normalizedExpression
|
|
|
|
|
else normalizedExpression
|
|
|
|
|
|
2018-08-12 16:29:54 +02:00
|
|
|
|
let annotatedExpression =
|
|
|
|
|
if annotate
|
2019-03-16 19:20:19 +01:00
|
|
|
|
then Annot alphaNormalizedExpression inferredType
|
|
|
|
|
else alphaNormalizedExpression
|
2018-06-07 12:26:38 +02:00
|
|
|
|
|
2019-10-07 11:51:30 +02:00
|
|
|
|
case output of
|
|
|
|
|
StandardOutput -> render System.IO.stdout annotatedExpression
|
|
|
|
|
OutputFile file_ ->
|
|
|
|
|
System.IO.withFile file_ System.IO.WriteMode $ \h -> render h annotatedExpression
|
2018-06-07 12:26:38 +02:00
|
|
|
|
|
2019-05-13 18:26:38 +02:00
|
|
|
|
Resolve { resolveMode = Just Dot, ..} -> do
|
|
|
|
|
expression <- getExpression file
|
2019-02-01 00:24:17 +01:00
|
|
|
|
|
2019-07-08 12:55:15 +02:00
|
|
|
|
(Dhall.Import.Types.Status { _graph, _stack }) <-
|
2019-10-19 04:40:27 +02:00
|
|
|
|
State.execStateT (Dhall.Import.loadWith expression) (toStatus file) { _semanticCacheMode = semanticCacheMode }
|
2019-02-01 00:24:17 +01:00
|
|
|
|
|
2019-07-08 12:55:15 +02:00
|
|
|
|
let (rootImport :| _) = _stack
|
|
|
|
|
imports = rootImport : map parent _graph ++ map child _graph
|
|
|
|
|
importIds = Data.Map.fromList (zip imports [Text.Dot.userNodeId i | i <- [0..]])
|
|
|
|
|
|
|
|
|
|
let dotNode (i, nodeId) =
|
|
|
|
|
Text.Dot.userNode
|
|
|
|
|
nodeId
|
|
|
|
|
[ ("label", Data.Text.unpack $ pretty i)
|
|
|
|
|
, ("shape", "box")
|
|
|
|
|
, ("style", "rounded")
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
let dotEdge (Depends parent child) =
|
|
|
|
|
case (Data.Map.lookup parent importIds, Data.Map.lookup child importIds) of
|
|
|
|
|
(Just from, Just to) -> from .->. to
|
|
|
|
|
_ -> pure ()
|
|
|
|
|
|
|
|
|
|
let dot = do Text.Dot.attribute ("rankdir", "LR")
|
|
|
|
|
mapM_ dotNode (Data.Map.assocs importIds)
|
|
|
|
|
mapM_ dotEdge _graph
|
|
|
|
|
|
|
|
|
|
putStr . ("strict " <>) . Text.Dot.showDot $ dot
|
2019-02-01 00:24:17 +01:00
|
|
|
|
|
2019-05-13 18:26:38 +02:00
|
|
|
|
Resolve { resolveMode = Just ListImmediateDependencies, ..} -> do
|
|
|
|
|
expression <- getExpression file
|
2018-06-07 12:26:38 +02:00
|
|
|
|
|
2019-02-01 00:24:17 +01:00
|
|
|
|
mapM_ (print
|
|
|
|
|
. Pretty.pretty
|
|
|
|
|
. Dhall.Core.importHashed) expression
|
|
|
|
|
|
2019-05-13 18:26:38 +02:00
|
|
|
|
Resolve { resolveMode = Just ListTransitiveDependencies, ..} -> do
|
|
|
|
|
expression <- getExpression file
|
2019-02-01 00:24:17 +01:00
|
|
|
|
|
|
|
|
|
(Dhall.Import.Types.Status { _cache }) <-
|
2019-10-19 04:40:27 +02:00
|
|
|
|
State.execStateT (Dhall.Import.loadWith expression) (toStatus file) { _semanticCacheMode = semanticCacheMode }
|
2019-02-01 00:24:17 +01:00
|
|
|
|
|
|
|
|
|
mapM_ print
|
|
|
|
|
. fmap ( Pretty.pretty
|
|
|
|
|
. Dhall.Core.importType
|
2019-07-17 17:20:48 +02:00
|
|
|
|
. Dhall.Core.importHashed
|
|
|
|
|
. Dhall.Import.chainedImport )
|
2019-11-21 17:20:48 +01:00
|
|
|
|
. reverse
|
|
|
|
|
. Dhall.Map.keys
|
2019-02-01 00:24:17 +01:00
|
|
|
|
$ _cache
|
|
|
|
|
|
2019-05-13 18:26:38 +02:00
|
|
|
|
Resolve { resolveMode = Nothing, ..} -> do
|
|
|
|
|
expression <- getExpression file
|
2019-02-01 00:24:17 +01:00
|
|
|
|
|
2019-09-09 22:37:30 +02:00
|
|
|
|
resolvedExpression <-
|
2019-10-19 04:40:27 +02:00
|
|
|
|
Dhall.Import.loadRelativeTo (rootDirectory file) semanticCacheMode expression
|
2019-09-09 22:37:30 +02:00
|
|
|
|
|
2019-02-01 00:24:17 +01:00
|
|
|
|
render System.IO.stdout resolvedExpression
|
|
|
|
|
|
2019-03-16 19:20:19 +01:00
|
|
|
|
Normalize {..} -> do
|
2019-05-13 18:26:38 +02:00
|
|
|
|
expression <- getExpression file
|
2018-06-07 12:26:38 +02:00
|
|
|
|
|
2018-09-18 01:24:49 +02:00
|
|
|
|
resolvedExpression <- Dhall.Import.assertNoImports expression
|
2018-06-07 12:26:38 +02:00
|
|
|
|
|
2019-04-24 22:01:46 +02:00
|
|
|
|
_ <- Dhall.Core.throws (Dhall.TypeCheck.typeOf resolvedExpression)
|
2018-06-07 12:26:38 +02:00
|
|
|
|
|
2019-03-16 19:20:19 +01:00
|
|
|
|
let normalizedExpression = Dhall.Core.normalize resolvedExpression
|
|
|
|
|
|
|
|
|
|
let alphaNormalizedExpression =
|
|
|
|
|
if alpha
|
|
|
|
|
then Dhall.Core.alphaNormalize normalizedExpression
|
|
|
|
|
else normalizedExpression
|
|
|
|
|
|
|
|
|
|
render System.IO.stdout alphaNormalizedExpression
|
2018-06-07 12:26:38 +02:00
|
|
|
|
|
2019-05-13 18:26:38 +02:00
|
|
|
|
Type {..} -> do
|
|
|
|
|
expression <- getExpression file
|
2018-06-07 12:26:38 +02:00
|
|
|
|
|
2019-09-09 22:37:30 +02:00
|
|
|
|
resolvedExpression <-
|
2019-10-19 15:47:27 +02:00
|
|
|
|
Dhall.Import.loadRelativeTo (rootDirectory file) semanticCacheMode expression
|
2018-06-07 12:26:38 +02:00
|
|
|
|
|
2019-04-24 22:01:46 +02:00
|
|
|
|
inferredType <- Dhall.Core.throws (Dhall.TypeCheck.typeOf resolvedExpression)
|
2018-06-07 12:26:38 +02:00
|
|
|
|
|
2019-09-19 07:45:39 +02:00
|
|
|
|
if quiet
|
|
|
|
|
then return ()
|
|
|
|
|
else render System.IO.stdout inferredType
|
2018-06-07 12:26:38 +02:00
|
|
|
|
|
2018-06-08 06:33:03 +02:00
|
|
|
|
Repl -> do
|
2019-07-31 03:49:53 +02:00
|
|
|
|
Dhall.Repl.repl characterSet explain
|
2018-06-08 06:33:03 +02:00
|
|
|
|
|
2018-09-16 17:32:01 +02:00
|
|
|
|
Diff {..} -> do
|
2018-06-09 10:00:52 +02:00
|
|
|
|
expression1 <- Dhall.inputExpr expr1
|
|
|
|
|
|
|
|
|
|
expression2 <- Dhall.inputExpr expr2
|
|
|
|
|
|
|
|
|
|
let diff = Dhall.Diff.diffNormalized expression1 expression2
|
|
|
|
|
|
2019-08-31 15:18:46 +02:00
|
|
|
|
renderDoc System.IO.stdout (Dhall.Diff.doc diff)
|
|
|
|
|
|
|
|
|
|
if Dhall.Diff.same diff
|
|
|
|
|
then return ()
|
|
|
|
|
else Exit.exitFailure
|
2018-06-09 10:00:52 +02:00
|
|
|
|
|
2018-09-16 17:32:01 +02:00
|
|
|
|
Format {..} -> do
|
2019-02-07 03:19:25 +01:00
|
|
|
|
Dhall.Format.format (Dhall.Format.Format {..})
|
2018-06-10 19:54:22 +02:00
|
|
|
|
|
2018-09-16 17:32:01 +02:00
|
|
|
|
Freeze {..} -> do
|
2019-06-01 18:44:01 +02:00
|
|
|
|
let scope = if all_ then AllImports else OnlyRemoteImports
|
|
|
|
|
|
|
|
|
|
let intent = if cache then Cache else Secure
|
|
|
|
|
|
2019-09-14 07:01:23 +02:00
|
|
|
|
Dhall.Freeze.freeze inplace scope intent characterSet censor
|
2018-06-26 19:30:54 +02:00
|
|
|
|
|
2019-10-20 00:38:44 +02:00
|
|
|
|
Hash {..} -> do
|
|
|
|
|
expression <- getExpression file
|
|
|
|
|
|
|
|
|
|
resolvedExpression <-
|
|
|
|
|
Dhall.Import.loadRelativeTo (rootDirectory file) UseSemanticCache expression
|
|
|
|
|
|
|
|
|
|
_ <- Dhall.Core.throws (Dhall.TypeCheck.typeOf resolvedExpression)
|
|
|
|
|
|
|
|
|
|
let normalizedExpression =
|
|
|
|
|
Dhall.Core.alphaNormalize (Dhall.Core.normalize resolvedExpression)
|
|
|
|
|
|
|
|
|
|
Data.Text.IO.putStrLn (Dhall.Import.hashExpressionToCode normalizedExpression)
|
2018-06-10 19:54:22 +02:00
|
|
|
|
|
2018-09-16 17:32:01 +02:00
|
|
|
|
Lint {..} -> do
|
2019-10-22 19:45:08 +02:00
|
|
|
|
(Header header, expression) <- getExpressionAndHeader inplace
|
2018-06-25 17:00:11 +02:00
|
|
|
|
|
2019-09-14 07:01:23 +02:00
|
|
|
|
case inplace of
|
2019-10-10 16:16:20 +02:00
|
|
|
|
InputFile file -> do
|
2018-06-25 17:00:11 +02:00
|
|
|
|
let lintedExpression = Dhall.Lint.lint expression
|
|
|
|
|
|
2018-09-11 15:38:13 +02:00
|
|
|
|
let doc = Pretty.pretty header
|
2018-09-16 17:32:01 +02:00
|
|
|
|
<> Dhall.Pretty.prettyCharacterSet characterSet lintedExpression
|
2018-06-25 17:00:11 +02:00
|
|
|
|
|
|
|
|
|
System.IO.withFile file System.IO.WriteMode (\h -> do
|
2018-09-16 17:32:01 +02:00
|
|
|
|
renderDoc h doc )
|
|
|
|
|
|
2019-09-14 07:01:23 +02:00
|
|
|
|
StandardInput -> do
|
2018-06-25 17:00:11 +02:00
|
|
|
|
let lintedExpression = Dhall.Lint.lint expression
|
|
|
|
|
|
2018-09-11 15:38:13 +02:00
|
|
|
|
let doc = Pretty.pretty header
|
|
|
|
|
<> Dhall.Pretty.prettyCharacterSet characterSet lintedExpression
|
2018-06-25 17:00:11 +02:00
|
|
|
|
|
2018-09-16 17:32:01 +02:00
|
|
|
|
renderDoc System.IO.stdout doc
|
2018-06-25 17:00:11 +02:00
|
|
|
|
|
2018-11-29 02:51:20 +01:00
|
|
|
|
Encode {..} -> do
|
2019-05-13 18:26:38 +02:00
|
|
|
|
expression <- getExpression file
|
2018-09-18 17:33:54 +02:00
|
|
|
|
|
2019-11-01 04:05:22 +01:00
|
|
|
|
let bytes = Dhall.Binary.encodeExpression (Dhall.Core.denote expression)
|
2018-09-18 17:33:54 +02:00
|
|
|
|
|
2018-11-29 02:51:20 +01:00
|
|
|
|
if json
|
|
|
|
|
then do
|
|
|
|
|
let decoder = Codec.CBOR.JSON.decodeValue False
|
|
|
|
|
|
2019-04-24 22:01:46 +02:00
|
|
|
|
(_, value) <- Dhall.Core.throws (Codec.CBOR.Read.deserialiseFromBytes decoder bytes)
|
2018-11-29 02:51:20 +01:00
|
|
|
|
|
|
|
|
|
let jsonBytes = Data.Aeson.Encode.Pretty.encodePretty value
|
2018-09-18 17:33:54 +02:00
|
|
|
|
|
2018-11-29 02:51:20 +01:00
|
|
|
|
Data.ByteString.Lazy.Char8.putStrLn jsonBytes
|
|
|
|
|
|
|
|
|
|
else do
|
|
|
|
|
Data.ByteString.Lazy.putStr bytes
|
|
|
|
|
|
|
|
|
|
Decode {..} -> do
|
2019-05-13 18:26:38 +02:00
|
|
|
|
bytes <- do
|
|
|
|
|
case file of
|
2019-10-10 16:16:20 +02:00
|
|
|
|
InputFile f -> Data.ByteString.Lazy.readFile f
|
2019-09-14 07:01:23 +02:00
|
|
|
|
StandardInput -> Data.ByteString.Lazy.getContents
|
2018-09-18 17:33:54 +02:00
|
|
|
|
|
2019-11-01 04:05:22 +01:00
|
|
|
|
expression <- do
|
2018-11-29 02:51:20 +01:00
|
|
|
|
if json
|
|
|
|
|
then do
|
|
|
|
|
value <- case Data.Aeson.eitherDecode' bytes of
|
|
|
|
|
Left string -> fail string
|
|
|
|
|
Right value -> return value
|
|
|
|
|
|
|
|
|
|
let encoding = Codec.CBOR.JSON.encodeValue value
|
|
|
|
|
|
2019-11-01 04:05:22 +01:00
|
|
|
|
let cborgBytes = Codec.CBOR.Write.toLazyByteString encoding
|
|
|
|
|
|
|
|
|
|
Dhall.Core.throws (Dhall.Binary.decodeExpression cborgBytes)
|
2018-11-29 02:51:20 +01:00
|
|
|
|
else do
|
2019-11-01 04:05:22 +01:00
|
|
|
|
Dhall.Core.throws (Dhall.Binary.decodeExpression bytes)
|
2018-09-18 17:33:54 +02:00
|
|
|
|
|
|
|
|
|
|
2019-11-01 04:05:22 +01:00
|
|
|
|
let doc = Dhall.Pretty.prettyCharacterSet characterSet (Dhall.Core.renote expression :: Expr Src Import)
|
2018-09-18 17:33:54 +02:00
|
|
|
|
|
|
|
|
|
renderDoc System.IO.stdout doc
|
|
|
|
|
|
2019-07-08 19:18:09 +02:00
|
|
|
|
Text {..} -> do
|
|
|
|
|
expression <- getExpression file
|
|
|
|
|
|
2019-09-09 22:37:30 +02:00
|
|
|
|
resolvedExpression <-
|
|
|
|
|
Dhall.Import.loadRelativeTo (rootDirectory file) UseSemanticCache expression
|
2019-07-08 19:18:09 +02:00
|
|
|
|
|
|
|
|
|
_ <- Dhall.Core.throws (Dhall.TypeCheck.typeOf (Annot resolvedExpression Dhall.Core.Text))
|
|
|
|
|
|
|
|
|
|
let normalizedExpression = Dhall.Core.normalize resolvedExpression
|
|
|
|
|
|
|
|
|
|
case normalizedExpression of
|
|
|
|
|
Dhall.Core.TextLit (Dhall.Core.Chunks [] text) -> do
|
|
|
|
|
Data.Text.IO.putStr text
|
|
|
|
|
_ -> do
|
2019-10-30 16:13:51 +01:00
|
|
|
|
let invalidDecoderExpected :: Expr Void Void
|
|
|
|
|
invalidDecoderExpected = Dhall.Core.Text
|
2019-07-08 19:18:09 +02:00
|
|
|
|
|
2019-10-30 16:13:51 +01:00
|
|
|
|
let invalidDecoderExpression :: Expr Void Void
|
|
|
|
|
invalidDecoderExpression = normalizedExpression
|
2019-07-08 19:18:09 +02:00
|
|
|
|
|
2019-10-30 14:24:15 +01:00
|
|
|
|
Control.Exception.throwIO (Dhall.InvalidDecoder {..})
|
2019-07-08 19:18:09 +02:00
|
|
|
|
|
2019-10-19 03:59:29 +02:00
|
|
|
|
Tags {..} -> do
|
|
|
|
|
tags <- Dhall.Tags.generate input suffixes followSymlinks
|
2019-10-10 16:16:20 +02:00
|
|
|
|
|
|
|
|
|
case output of
|
|
|
|
|
OutputFile file ->
|
|
|
|
|
System.IO.withFile file System.IO.WriteMode (`Data.Text.IO.hPutStr` tags)
|
|
|
|
|
|
|
|
|
|
StandardOutput -> Data.Text.IO.putStrLn tags
|
2019-11-22 04:57:14 +01:00
|
|
|
|
|
|
|
|
|
SyntaxTree {..} -> do
|
|
|
|
|
expression <- getExpression file
|
|
|
|
|
|
|
|
|
|
let denoted :: Expr Void Import
|
|
|
|
|
denoted = Dhall.Core.denote expression
|
|
|
|
|
|
|
|
|
|
Text.Pretty.Simple.pPrintNoColor denoted
|
2019-10-10 16:16:20 +02:00
|
|
|
|
|
2018-07-27 18:07:33 +02:00
|
|
|
|
-- | Entry point for the @dhall@ executable
|
2018-06-07 12:26:38 +02:00
|
|
|
|
main :: IO ()
|
|
|
|
|
main = do
|
|
|
|
|
options <- Options.Applicative.execParser parserInfoOptions
|
|
|
|
|
command options
|