gdritter repos bricoleur / master src / Bricoleur / Utils.hs
master

Tree @master (Download .tar.gz)

Utils.hs @masterraw · history · blame

{-# LANGUAGE OverloadedStrings #-}

module Bricoleur.Utils
  ( cOutput,
    cDebug,
    cWarn,
    cError,
    cDie,
    bsErrorLn,
    cOpenFile,
    throw,
    F.format,
    (F.%),
    F.stext,
    F.text,
    F.string,
    F.shown,
  )
where

import qualified Data.ByteString.Lazy.Char8 as BS
import qualified Data.Text.Lazy as TL
import qualified Data.Text.Lazy.Builder as TL
import qualified Data.Text.Lazy.IO as TL
import qualified Formatting as F
import qualified System.Directory as Sys
import qualified System.Exit as Sys
import qualified System.IO as Sys
import qualified System.Posix.IO as Posix
import qualified System.Posix.Terminal as Posix
import Prelude (Either (Left), FilePath, IO, ($), (.))

-- | Produce a 'Left' value from a format string
throw :: F.Format (Either TL.Text r) a -> a
throw f =
  F.runFormat f (Left . TL.toLazyText)

stderr :: TL.Text -> IO ()
stderr = TL.hPutStr Sys.stderr

-- | Write output to stdout
cOutput :: TL.Text -> IO ()
cOutput = TL.putStrLn

-- | Write a debug message to stderr.
cDebug :: F.Format (IO ()) a -> a
cDebug msg = F.runFormat msg $ \b ->
  TL.hPutStrLn Sys.stderr (TL.toLazyText b)

-- | Write a warning message to stderr. If we are connected to a TTY,
-- then this will write in an orange color.
cWarn :: F.Format (IO ()) a -> a
cWarn msg = F.runFormat msg $ \b -> do
  isTTY <- Posix.queryTerminal Posix.stdOutput
  if isTTY
    then do
      stderr "\x1b[93m"
      stderr (TL.toLazyText b)
      stderr "\x1b[39m\n"
    else TL.hPutStrLn Sys.stderr (TL.toLazyText b)

-- | Write an error message to stderr and exit. If we are connected to
-- a TTY, this message will be in red.
cError :: F.Format (IO ()) a -> a
cError msg = F.runFormat msg $ \b -> do
  isTTY <- Posix.queryTerminal Posix.stdOutput
  if isTTY
    then do
      stderr "\x1b[91m"
      stderr (TL.toLazyText b)
      stderr "\x1b[39m\n"
    else TL.hPutStrLn Sys.stderr (TL.toLazyText b)

-- | Write an error message to stderr and exit. If we are connected to
-- a TTY, this message will be in red.
cDie :: F.Format (IO r) a -> a
cDie msg = F.runFormat msg $ \b -> do
  isTTY <- Posix.queryTerminal Posix.stdOutput
  if isTTY
    then do
      stderr "\x1b[91m"
      stderr (TL.toLazyText b)
      stderr "\x1b[39m\n"
    else TL.hPutStrLn Sys.stderr (TL.toLazyText b)
  Sys.exitFailure

bsErrorLn :: BS.ByteString -> IO ()
bsErrorLn bs = do
  isTTY <- Posix.queryTerminal Posix.stdOutput
  if isTTY
    then do
      BS.hPutStr Sys.stderr "\x1b[91m"
      BS.hPutStr Sys.stderr bs
      BS.hPutStr Sys.stderr "\x1b[39m\n"
    else BS.hPutStrLn Sys.stderr bs

cOpenFile :: TL.Text -> FilePath -> IO TL.Text
cOpenFile purpose path = do
  exists <- Sys.doesFileExist path
  if exists
    then TL.readFile path
    else
      cDie
        ( "Unable to open " F.% F.text
            F.% " file at "
            F.% F.string
        )
        purpose
        path