Utils.hs 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. {-# LANGUAGE OverloadedStrings #-}
  2. module Bricoleur.Utils
  3. ( cOutput
  4. , cDebug
  5. , cWarn
  6. , cError
  7. , cDie
  8. , bsErrorLn
  9. , cOpenFile
  10. , throw
  11. , F.format
  12. , (F.%)
  13. , F.stext
  14. , F.text
  15. , F.string
  16. , F.shown
  17. ) where
  18. import qualified Formatting as F
  19. import qualified Data.ByteString.Lazy.Char8 as BS
  20. import qualified Data.Text.Lazy as TL
  21. import qualified Data.Text.Lazy.Builder as TL
  22. import qualified Data.Text.Lazy.IO as TL
  23. import qualified System.Directory as Sys
  24. import qualified System.Exit as Sys
  25. import qualified System.IO as Sys
  26. import qualified System.Posix.IO as Posix
  27. import qualified System.Posix.Terminal as Posix
  28. import Prelude (FilePath, IO, Either(Left), ($))
  29. -- | Produce a 'Left' value from a format string
  30. throw :: F.Format (Either TL.Text r) a -> a
  31. throw f =
  32. F.runFormat f (\ b -> Left (TL.toLazyText b))
  33. stderr :: TL.Text -> IO ()
  34. stderr = TL.hPutStr Sys.stderr
  35. -- | Write output to stdout
  36. cOutput :: TL.Text -> IO ()
  37. cOutput = TL.putStrLn
  38. -- | Write a debug message to stderr.
  39. cDebug :: F.Format (IO ()) a -> a
  40. cDebug msg = F.runFormat msg $ \ b ->
  41. TL.hPutStrLn Sys.stderr (TL.toLazyText b)
  42. -- | Write a warning message to stderr. If we are connected to a TTY,
  43. -- then this will write in an orange color.
  44. cWarn :: F.Format (IO ()) a -> a
  45. cWarn msg = F.runFormat msg $ \b -> do
  46. isTTY <- Posix.queryTerminal Posix.stdOutput
  47. if isTTY
  48. then do stderr "\x1b[93m"
  49. stderr (TL.toLazyText b)
  50. stderr "\x1b[39m\n"
  51. else TL.hPutStrLn Sys.stderr (TL.toLazyText b)
  52. -- | Write an error message to stderr and exit. If we are connected to
  53. -- a TTY, this message will be in red.
  54. cError :: F.Format (IO ()) a -> a
  55. cError msg = F.runFormat msg $ \b -> do
  56. isTTY <- Posix.queryTerminal Posix.stdOutput
  57. if isTTY
  58. then do stderr "\x1b[91m"
  59. stderr (TL.toLazyText b)
  60. stderr "\x1b[39m\n"
  61. else TL.hPutStrLn Sys.stderr (TL.toLazyText b)
  62. -- | Write an error message to stderr and exit. If we are connected to
  63. -- a TTY, this message will be in red.
  64. cDie :: F.Format (IO r) a -> a
  65. cDie msg = F.runFormat msg $ \ b -> do
  66. isTTY <- Posix.queryTerminal Posix.stdOutput
  67. if isTTY
  68. then do stderr "\x1b[91m"
  69. stderr (TL.toLazyText b)
  70. stderr "\x1b[39m\n"
  71. else TL.hPutStrLn Sys.stderr (TL.toLazyText b)
  72. Sys.exitFailure
  73. bsErrorLn :: BS.ByteString -> IO ()
  74. bsErrorLn bs = do
  75. isTTY <- Posix.queryTerminal Posix.stdOutput
  76. if isTTY
  77. then do BS.hPutStr Sys.stderr "\x1b[91m"
  78. BS.hPutStr Sys.stderr bs
  79. BS.hPutStr Sys.stderr "\x1b[39m\n"
  80. else BS.hPutStrLn Sys.stderr bs
  81. cOpenFile :: TL.Text -> FilePath -> IO TL.Text
  82. cOpenFile purpose path = do
  83. exists <- Sys.doesFileExist path
  84. if exists
  85. then TL.readFile path
  86. else cDie ("Unable to open " F.% F.text F.%
  87. " file at " F.% F.string) purpose path