realMain :: Config -> IO ()
realMain ic = do
        iopts <- liftIO . execParser $ opts ic
        mcsrc <- readSafe BS.L.readFile Nothing $ configFile iopts
        options <- case mcsrc of
            Just csrc -> do
                c <- case eitherDecode csrc of
                    Left e -> (printError . JSONDecodingError $ T.pack e) >> pure ic
                    Right t -> pure t
                liftIO . execParser $ opts c
            Nothing -> pure iopts
        flip runConfigured options $ do
            config <- ask
            if null $ sourceFiles config
            then throwError $ InvocationError "No source files provided"
            else do
                ps <- liftIO . mapM canonicalizePath $ sourceFiles config
                case outputFormat config of
                    "html" -> do
                        page <- lift . diagnosticsHTML (language config) $ head ps
                        liftIO . T.L.IO.putStrLn . T.L.E.decodeUtf8 $ renderHtml page
                    "dense" -> do
                        os <- lift $ mapM (diagnosticsJSON (language config)) ps
                        liftIO . T.L.IO.putStrLn . T.L.E.decodeUtf8 . encode $ object os
                    _ -> do
                        os <- lift $ mapM (diagnosticsJSON (language config)) ps
                        liftIO . T.L.IO.putStrLn . T.L.E.decodeUtf8 . encodePretty $ object os
    where opts c = info (helper <*> parseOptions c)
                        (fullDesc <> progDesc "Output diagnostic information about source files" <> header "diagnostics - output assorted information about source code")
realMain :: Config -> IO ()
realMain ic = do
        iopts <- liftIO . execParser $ opts ic
        mcsrc <- readSafe BS.L.readFile Nothing $ configFile iopts
        options <- case mcsrc of
            Just csrc -> do
                c <- case eitherDecode csrc of
                    Left e -> (printError . JSONDecodingError $ T.pack e) >> pure ic
                    Right t -> pure t
                liftIO . execParser $ opts c
            Nothing -> pure iopts
        flip runConfigured options $ do
            config <- ask
            if null $ sourceFiles config
            then throwError $ InvocationError "No source files provided"
            else do
                ps <- liftIO . mapM canonicalizePath $ sourceFiles config
                case outputFormat config of
                    "html" -> do
                        page <- lift . diagnosticsHTML (language config) $ head ps
                        liftIO . T.L.IO.putStrLn . T.L.E.decodeUtf8 $ renderHtml page
                    "dense" -> do
                        os <- lift $ mapM (diagnosticsJSON (language config)) ps
                        liftIO . T.L.IO.putStrLn . T.L.E.decodeUtf8 . encode $ object os
                    _ -> do
                        os <- lift $ mapM (diagnosticsJSON (language config)) ps
                        liftIO . T.L.IO.putStrLn . T.L.E.decodeUtf8 . encodePretty $ object os
    where opts c = info (helper <*> parseOptions c)
                        (fullDesc <> progDesc "Output diagnostic information about source files" <> header "diagnostics - output assorted information about source code")
realMain ic = do
        iopts <- liftIO . execParser $ opts ic
        mcsrc <- readSafe BS.L.readFile Nothing $ configFile iopts
        options <- case mcsrc of
            Just csrc -> do
                c <- case eitherDecode csrc of
                    Left e -> (printError . JSONDecodingError $ T.pack e) >> pure ic
                    Right t -> pure t
                liftIO . execParser $ opts c
            Nothing -> pure iopts
        flip runConfigured options $ do
            config <- ask
            if null $ sourceFiles config
            then throwError $ InvocationError "No source files provided"
            else do
                ps <- liftIO . mapM canonicalizePath $ sourceFiles config
                case outputFormat config of
                    "html" -> do
                        page <- lift . diagnosticsHTML (language config) $ head ps
                        liftIO . T.L.IO.putStrLn . T.L.E.decodeUtf8 $ renderHtml page
                    "dense" -> do
                        os <- lift $ mapM (diagnosticsJSON (language config)) ps
                        liftIO . T.L.IO.putStrLn . T.L.E.decodeUtf8 . encode $ object os
                    _ -> do
                        os <- lift $ mapM (diagnosticsJSON (language config)) ps
                        liftIO . T.L.IO.putStrLn . T.L.E.decodeUtf8 . encodePretty $ object os
    where opts c = info (helper <*> parseOptions c)
                        (fullDesc <> progDesc "Output diagnostic information about source files" <> header "diagnostics - output assorted information about source code")