Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

imp:cli: show first line of error messages in red #2303

Merged
merged 2 commits into from
Dec 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions hledger-lib/Hledger/Reports/ReportOptions.hs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,6 @@ import Hledger.Query
import Hledger.Utils
import Data.Function ((&))


-- | What to calculate for each cell in a balance report.
-- "Balance report types -> Calculation type" in the hledger manual.
data BalanceCalculation =
Expand Down Expand Up @@ -890,10 +889,13 @@ makeHledgerClassyLenses ''ReportSpec
-- Left "This regular expression is invalid or unsupported, please correct it:\n(assets"
-- >>> _rsQuery $ set querystring ["assets"] defreportspec
-- Acct (RegexpCI "assets")
-- >>> _rsQuery $ set querystring ["(assets"] defreportspec
-- *** Exception: Error: Updating ReportSpec failed: try using overEither instead of over or setEither instead of set
-- >>> _rsQuery $ set period (MonthPeriod 2021 08) defreportspec
-- Date DateSpan 2021-08
--
-- XXX testing error output isn't working since adding color to it:
-- > import System.Environment
-- > setEnv "NO_COLOR" "1" >> return (_rsQuery $ set querystring ["(assets"] defreportspec)
-- *** Exception: Error: Updating ReportSpec failed: try using overEither instead of over or setEither instead of set
class HasReportOptsNoUpdate a => HasReportOpts a where
reportOpts :: ReportableLens' a ReportOpts
reportOpts = reportOptsNoUpdate
Expand Down
38 changes: 29 additions & 9 deletions hledger-lib/Hledger/Utils/IO.hs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ module Hledger.Utils.IO (
brightCyan',
brightWhite',
rgb',
sgrresetall,

-- ** Generic

Expand Down Expand Up @@ -186,22 +187,39 @@ pprint' = pPrintOpt NoCheckColorTty prettyoptsNoColor

-- Errors

-- | Simpler alias for errorWithoutStackTrace
-- | Call errorWithoutStackTrace, prepending a "Error:" label.
-- Also do some ANSI styling of the first line when allowed (using unsafe IO).
error' :: String -> a
error' = errorWithoutStackTrace . ("Error: " <>)
error' =
if useColorOnStderrUnsafe
then -- color the program name as well
unsafePerformIO $ do
putStr fmt
return $ errorWithoutStackTrace . modifyFirstLine ((<>sgrresetall) . (label<>))
else
errorWithoutStackTrace . modifyFirstLine (label<>)
where
label = "Error: "
fmt = sgrbrightred <> sgrbold

-- | A version of errorWithoutStackTrace that adds a usage hint.
-- | Like error', but add a hint about using -h.
usageError :: String -> a
usageError = error' . (++ " (use -h to see usage)")

-- | Show a warning message on stderr before returning the given value.
-- Use this when you want to show the user a message on stderr, without stopping the program.
-- Currently we do this very sparingly in hledger; we prefer to either quietly work,
-- or loudly raise an error. Variable output can make scripting harder.
-- | Show a message, with "Warning:" label, on stderr before returning the given value.
-- Also do some ANSI styling of the first line when we detect that's supported (using unsafe IO).
-- Currently we use this very sparingly in hledger; we prefer to either quietly work,
-- or loudly raise an error. (Varying output can make scripting harder.)
warn :: String -> a -> a
warn msg = trace ("Warning: " <> msg)

warn msg = trace (modifyFirstLine f (label <> msg))
where
label = "Warning: "
f = if useColorOnStderrUnsafe then ((<>sgrresetall).(fmt<>)) else id
where
fmt = sgrbrightyellow <> sgrbold

-- Transform a string's first line.
modifyFirstLine f s = unlines $ map f l <> ls where (l,ls) = splitAt 1 $ lines s -- total

-- Time

Expand Down Expand Up @@ -554,6 +572,8 @@ sgrbold = setSGRCode [SetConsoleIntensity BoldIntensity]
sgrfaint = setSGRCode [SetConsoleIntensity FaintIntensity]
sgrnormal = setSGRCode [SetConsoleIntensity NormalIntensity]
sgrresetfg = setSGRCode [SetDefaultColor Foreground]
sgrresetbg = setSGRCode [SetDefaultColor Background]
sgrresetall = sgrresetfg <> sgrresetbg <> sgrnormal
sgrblack = setSGRCode [SetColor Foreground Dull Black]
sgrred = setSGRCode [SetColor Foreground Dull Red]
sgrgreen = setSGRCode [SetColor Foreground Dull Green]
Expand Down