diff --git a/lib/SlackBuilder/Trans.hs b/lib/SlackBuilder/Trans.hs index 3ab162c..515c1d4 100644 --- a/lib/SlackBuilder/Trans.hs +++ b/lib/SlackBuilder/Trans.hs @@ -11,12 +11,14 @@ module SlackBuilder.Trans import Control.Monad.Trans.Reader (ReaderT(..), asks) import Data.Text (Text) +import qualified Data.Text as Text import SlackBuilder.Config import Control.Monad.IO.Class (MonadIO(..)) import Control.Monad.Catch (MonadCatch(..), MonadThrow(..)) import Control.Exception (Exception(..)) import System.FilePath (()) import Text.URI (URI) +import qualified Text.URI as URI import qualified Codec.Compression.Lzma as Lzma data SlackBuilderException @@ -26,7 +28,34 @@ data SlackBuilderException deriving Show instance Exception SlackBuilderException - + where + displayException (UpdaterNotFound updateName) = Text.unpack + $ Text.concat ["Requested package \"", updateName, "\" was not found"] + displayException (HttpsUrlExpected givenURI) = Text.unpack + $ "Only https URLs are supported, got: " <> URI.render givenURI + displayException (LzmaDecompressionFailed Lzma.LzmaRetOK) = + "Operation completed successfully" + displayException (LzmaDecompressionFailed Lzma.LzmaRetStreamEnd) = + "End of stream was reached" + displayException (LzmaDecompressionFailed Lzma.LzmaRetUnsupportedCheck) = + "Cannot calculate the integrity check" + displayException (LzmaDecompressionFailed Lzma.LzmaRetGetCheck) = + "Integrity check type is now available" + displayException (LzmaDecompressionFailed Lzma.LzmaRetMemError) = + "Cannot allocate memory" + displayException (LzmaDecompressionFailed Lzma.LzmaRetMemlimitError) = + "Memory usage limit was reached" + displayException (LzmaDecompressionFailed Lzma.LzmaRetFormatError) = + "File format not recognized" + displayException (LzmaDecompressionFailed Lzma.LzmaRetOptionsError) = + "Invalid or unsupported options" + displayException (LzmaDecompressionFailed Lzma.LzmaRetDataError) = + "Data is corrupt" + displayException (LzmaDecompressionFailed Lzma.LzmaRetBufError) = + "No progress is possible" + displayException (LzmaDecompressionFailed Lzma.LzmaRetProgError) = + "Programming error" + newtype SlackBuilderT a = SlackBuilderT { runSlackBuilderT :: ReaderT Settings IO a } diff --git a/src/Main.hs b/src/Main.hs index ec74432..ba7dc54 100644 --- a/src/Main.hs +++ b/src/Main.hs @@ -6,6 +6,7 @@ module Main ( main ) where +import Control.Exception (Exception(..), handle) import Data.Char (isNumber) import Data.List.NonEmpty (NonEmpty(..)) import Control.Monad.Catch (MonadThrow(..)) @@ -20,7 +21,6 @@ import SlackBuilder.Update import qualified Toml import Data.Text (Text) import qualified Data.Text as Text -import qualified Data.Text.IO as Text.IO import Control.Monad.Trans.Reader (ReaderT(..)) import SlackBuilder.Package (PackageDescription(..)) import qualified SlackBuilder.Package as Package @@ -28,6 +28,13 @@ import Text.URI.QQ (uri) import Data.Foldable (for_, find) import GHC.Records (HasField(..)) import System.Process (CmdSpec(..)) +import System.Console.ANSI + ( setSGR + , SGR(..) + , ColorIntensity(..) + , Color(..) + , ConsoleLayer(..) + ) autoUpdatable :: [PackageDescription] autoUpdatable = @@ -294,17 +301,20 @@ check = for_ autoUpdatable go >>= mapM_ checkUpdateAvailability >> liftIO (putStrLn "") - main :: IO () main = do programCommand <- execParser slackBuilderParser settings <- Toml.decodeFile settingsCodec "config/config.toml" - latestVersion <- flip runReaderT settings + handle handleException + $ flip runReaderT settings $ runSlackBuilderT $ executeCommand programCommand - - maybe (pure ()) Text.IO.putStrLn latestVersion where + handleException :: SlackBuilderException -> IO () + handleException slackBuilderException + = setSGR [SetColor Foreground Dull Red] + >> putStrLn (displayException slackBuilderException) + >> setSGR [Reset] executeCommand = \case - CheckCommand -> check >> pure Nothing - Up2DateCommand packageName -> up2Date packageName >> pure Nothing + CheckCommand -> check + Up2DateCommand packageName -> up2Date packageName