purescript-0.14.2: app/Command/Graph.hs
module Command.Graph (command) where
import Prelude
import Control.Applicative (many)
import Control.Monad (unless, when)
import qualified Data.Aeson as Json
import Data.Bool (bool)
import qualified Data.ByteString.Lazy as LB
import qualified Data.ByteString.Lazy.UTF8 as LBU8
import qualified Language.PureScript as P
import Language.PureScript.Errors.JSON
import qualified Options.Applicative as Opts
import qualified System.Console.ANSI as ANSI
import System.Exit (exitFailure)
import System.Directory (getCurrentDirectory)
import System.FilePath.Glob (glob)
import System.IO (hPutStr, hPutStrLn, stderr)
data GraphOptions = GraphOptions
{ graphInput :: [FilePath]
, graphJSONErrors :: Bool
}
graph :: GraphOptions -> IO ()
graph GraphOptions{..} = do
input <- globWarningOnMisses (unless graphJSONErrors . warnFileTypeNotFound) graphInput
when (null input && not graphJSONErrors) $ do
hPutStr stderr $ unlines
[ "purs graph: No input files."
, "Usage: For basic information, try the `--help' option."
]
exitFailure
(makeResult, makeWarnings) <- P.graph input
printWarningsAndErrors graphJSONErrors makeWarnings makeResult
>>= (LB.putStr . Json.encode)
where
warnFileTypeNotFound :: String -> IO ()
warnFileTypeNotFound =
hPutStrLn stderr . ("purs graph: No files found using pattern: " <>)
command :: Opts.Parser (IO ())
command = graph <$> (Opts.helper <*> graphOptions)
where
graphOptions :: Opts.Parser GraphOptions
graphOptions =
GraphOptions <$> many inputFile
<*> jsonErrors
inputFile :: Opts.Parser FilePath
inputFile =
Opts.strArgument $
Opts.metavar "FILE" <>
Opts.help "The input .purs file(s)."
jsonErrors :: Opts.Parser Bool
jsonErrors =
Opts.switch $
Opts.long "json-errors" <>
Opts.help "Print errors to stderr as JSON"
-- | Arguments: use JSON, warnings, errors
printWarningsAndErrors :: Bool -> P.MultipleErrors -> Either P.MultipleErrors a -> IO a
printWarningsAndErrors False warnings errors = do
pwd <- getCurrentDirectory
cc <- bool Nothing (Just P.defaultCodeColor) <$> ANSI.hSupportsANSI stderr
let ppeOpts = P.defaultPPEOptions { P.ppeCodeColor = cc, P.ppeFull = True, P.ppeRelativeDirectory = pwd }
when (P.nonEmpty warnings) $
hPutStrLn stderr (P.prettyPrintMultipleWarnings ppeOpts warnings)
case errors of
Left errs -> do
hPutStrLn stderr (P.prettyPrintMultipleErrors ppeOpts errs)
exitFailure
Right res -> pure res
printWarningsAndErrors True warnings errors = do
let verbose = True
hPutStrLn stderr . LBU8.toString . Json.encode $
JSONResult (toJSONErrors verbose P.Warning warnings)
(either (toJSONErrors verbose P.Error) (const []) errors)
case errors of
Left _errs -> exitFailure
Right res -> pure res
globWarningOnMisses :: (String -> IO ()) -> [FilePath] -> IO [FilePath]
globWarningOnMisses warn = concatMapM globWithWarning
where
globWithWarning :: String -> IO [FilePath]
globWithWarning pattern' = do
paths <- glob pattern'
when (null paths) $ warn pattern'
return paths
concatMapM :: (a -> IO [b]) -> [a] -> IO [b]
concatMapM f = fmap concat . mapM f