packages feed

hledger-lib 1.50.5 → 1.51

raw patch · 10 files changed

+86/−84 lines, 10 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- Hledger.Data: boundariesToDayPartition :: NonEmpty Day -> DayPartition
- Hledger.Data: boundariesToMaybeDayPartition :: [Day] -> Maybe DayPartition
- Hledger.Data: data DayPartition
- Hledger.Data: dayPartitionFind :: Day -> DayPartition -> (Maybe Day, Day)
- Hledger.Data: dayPartitionStartEnd :: DayPartition -> (Day, Day)
- Hledger.Data: dayPartitionToDateSpans :: DayPartition -> [DateSpan]
- Hledger.Data: dayPartitionToList :: DayPartition -> [(Day, Day)]
- Hledger.Data: dayPartitionToNonEmpty :: DayPartition -> NonEmpty (Day, Day)
- Hledger.Data: insertPeriodData :: Semigroup a => Maybe Day -> a -> PeriodData a -> PeriodData a
- Hledger.Data: intervalBoundaryBefore :: Interval -> Day -> Day
- Hledger.Data: lookupPeriodData :: Day -> PeriodData a -> Maybe (Day, a)
- Hledger.Data: lookupPeriodDataOrHistorical :: Day -> PeriodData a -> (Maybe Day, a)
- Hledger.Data: mapBalanceData :: (MixedAmount -> MixedAmount) -> BalanceData -> BalanceData
- Hledger.Data: maybeDayPartitionToDateSpans :: Maybe DayPartition -> [DateSpan]
- Hledger.Data: mergePeriodData :: (a -> c) -> (b -> c) -> (a -> b -> c) -> PeriodData a -> PeriodData b -> PeriodData c
- Hledger.Data: opBalanceData :: (MixedAmount -> MixedAmount -> MixedAmount) -> BalanceData -> BalanceData -> BalanceData
- Hledger.Data: opPeriodData :: (a -> b -> c) -> PeriodData a -> PeriodData b -> PeriodData c
- Hledger.Data: padPeriodData :: a -> PeriodData b -> PeriodData a -> PeriodData a
- Hledger.Data: periodDataFromList :: a -> [(Day, a)] -> PeriodData a
- Hledger.Data: periodDataToList :: PeriodData a -> (a, [(Day, a)])
- Hledger.Data: splitSpan :: Bool -> Interval -> DateSpan -> Maybe DayPartition
- Hledger.Data: tests_BalanceData :: TestTree
- Hledger.Data: tests_DayPartition :: TestTree
- Hledger.Data: tests_PeriodData :: TestTree
- Hledger.Data: unionDayPartitions :: DayPartition -> DayPartition -> Maybe DayPartition
- Hledger.Data.Balancing: balanceTransaction :: BalancingOpts -> Transaction -> Either String Transaction
- Hledger.Utils.IO: inputToHandle :: Text -> IO Handle
- Hledger.Utils.IO: readHandlePortably :: Handle -> IO Text
- Hledger.Utils.IO: readHandlePortably' :: Maybe DynEncoding -> Handle -> IO Text
+ Hledger.Data.BalanceData: instance GHC.Base.Monoid Hledger.Data.Types.BalanceData
+ Hledger.Data.BalanceData: instance GHC.Base.Semigroup Hledger.Data.Types.BalanceData
+ Hledger.Data.BalanceData: instance GHC.Show.Show Hledger.Data.Types.BalanceData
+ Hledger.Data.BalanceData: mapBalanceData :: (MixedAmount -> MixedAmount) -> BalanceData -> BalanceData
+ Hledger.Data.BalanceData: opBalanceData :: (MixedAmount -> MixedAmount -> MixedAmount) -> BalanceData -> BalanceData -> BalanceData
+ Hledger.Data.BalanceData: tests_BalanceData :: TestTree
+ Hledger.Data.Balancing: balanceSingleTransaction :: BalancingOpts -> Transaction -> Either String Transaction
+ Hledger.Data.DayPartition: boundariesToDayPartition :: NonEmpty Day -> DayPartition
+ Hledger.Data.DayPartition: boundariesToMaybeDayPartition :: [Day] -> Maybe DayPartition
+ Hledger.Data.DayPartition: data DayPartition
+ Hledger.Data.DayPartition: dayPartitionFind :: Day -> DayPartition -> (Maybe Day, Day)
+ Hledger.Data.DayPartition: dayPartitionStartEnd :: DayPartition -> (Day, Day)
+ Hledger.Data.DayPartition: dayPartitionToDateSpans :: DayPartition -> [DateSpan]
+ Hledger.Data.DayPartition: dayPartitionToList :: DayPartition -> [(Day, Day)]
+ Hledger.Data.DayPartition: dayPartitionToNonEmpty :: DayPartition -> NonEmpty (Day, Day)
+ Hledger.Data.DayPartition: dayPartitionToPeriodData :: DayPartition -> PeriodData Day
+ Hledger.Data.DayPartition: instance GHC.Classes.Eq Hledger.Data.DayPartition.DayPartition
+ Hledger.Data.DayPartition: instance GHC.Classes.Ord Hledger.Data.DayPartition.DayPartition
+ Hledger.Data.DayPartition: instance GHC.Show.Show Hledger.Data.DayPartition.DayPartition
+ Hledger.Data.DayPartition: intervalBoundaryBefore :: Interval -> Day -> Day
+ Hledger.Data.DayPartition: maybeDayPartitionToDateSpans :: Maybe DayPartition -> [DateSpan]
+ Hledger.Data.DayPartition: splitSpan :: Bool -> Interval -> DateSpan -> Maybe DayPartition
+ Hledger.Data.DayPartition: tests_DayPartition :: TestTree
+ Hledger.Data.DayPartition: unionDayPartitions :: DayPartition -> DayPartition -> Maybe DayPartition
+ Hledger.Data.PeriodData: insertPeriodData :: Semigroup a => Maybe Day -> a -> PeriodData a -> PeriodData a
+ Hledger.Data.PeriodData: instance Data.Foldable.Foldable Hledger.Data.Types.PeriodData
+ Hledger.Data.PeriodData: instance Data.Foldable1.Foldable1 Hledger.Data.Types.PeriodData
+ Hledger.Data.PeriodData: instance Data.Traversable.Traversable Hledger.Data.Types.PeriodData
+ Hledger.Data.PeriodData: instance GHC.Base.Monoid a => GHC.Base.Monoid (Hledger.Data.Types.PeriodData a)
+ Hledger.Data.PeriodData: instance GHC.Base.Semigroup a => GHC.Base.Semigroup (Hledger.Data.Types.PeriodData a)
+ Hledger.Data.PeriodData: instance GHC.Show.Show a => GHC.Show.Show (Hledger.Data.Types.PeriodData a)
+ Hledger.Data.PeriodData: lookupPeriodData :: Day -> PeriodData a -> Maybe (Day, a)
+ Hledger.Data.PeriodData: lookupPeriodDataOrHistorical :: Day -> PeriodData a -> (Maybe Day, a)
+ Hledger.Data.PeriodData: mergePeriodData :: (a -> c) -> (b -> c) -> (a -> b -> c) -> PeriodData a -> PeriodData b -> PeriodData c
+ Hledger.Data.PeriodData: opPeriodData :: (a -> b -> c) -> PeriodData a -> PeriodData b -> PeriodData c
+ Hledger.Data.PeriodData: padPeriodData :: a -> PeriodData b -> PeriodData a -> PeriodData a
+ Hledger.Data.PeriodData: periodDataFromList :: a -> [(Day, a)] -> PeriodData a
+ Hledger.Data.PeriodData: periodDataToList :: PeriodData a -> (a, [(Day, a)])
+ Hledger.Data.PeriodData: tests_PeriodData :: TestTree
+ Hledger.Utils.IO: hGetContentsPortably :: Maybe DynEncoding -> Handle -> IO Text
+ Hledger.Utils.IO: textToHandle :: Text -> IO Handle

Files

CHANGES.md view
@@ -13,11 +13,25 @@  --> -Internal/api/developer-ish changes in the hledger-lib (and hledger) packages.+API/developer-ish changes in hledger-lib. For user-visible changes, see the hledger package changelog.  -# 1.50.5 2025-12-08+# 1.51 2025-12-05++Breaking changes++- Hledger.Data.Balancing: balanceTransaction -> balanceSingleTransaction+- Hledger.Utils.IO:+  - inputToHandle -> textToHandle; set utf8 not utf8_bom+  - readHandlePortably, readHandlePortably' -> hGetContentsPortably++Improvements++- Hledger.Utils.String:+  quoteForCommandLine now quotes some additional problem characters, and no longer quotes "7".+  [#2468]+  # 1.50.4 2025-12-04 
Hledger/Data/Balancing.hs view
@@ -16,7 +16,7 @@ , defbalancingopts   -- * transaction balancing , isTransactionBalanced-, balanceTransaction+, balanceSingleTransaction , balanceTransactionHelper   -- * assertion validation , transactionCheckAssertions@@ -173,32 +173,21 @@       Right _ -> Right t       Left e -> Left e --- | Balance this transaction, ensuring that its postings+-- | Balance this isolated transaction, ensuring that its postings -- (and its balanced virtual postings) sum to 0, -- by inferring a missing amount or conversion price(s) if needed. -- Or if balancing is not possible, because the amounts don't sum to 0 or -- because there's more than one missing amount, return an error message. ----- Transactions with balance assignments can have more than one--- missing amount; to balance those you should use the more powerful--- journalBalanceTransactions.------ The "sum to 0" test is done using commodity display precisions,--- if provided, so that the result agrees with the numbers users can see.----balanceTransaction ::-     BalancingOpts-  -> Transaction-  -> Either String Transaction-balanceTransaction bopts = fmap fst . balanceTransactionHelper bopts+-- Note this is not as accurate as @balanceTransactionInJournal@,+-- which considers the whole journal when calculating balance assignments and balance assertions.+balanceSingleTransaction :: BalancingOpts -> Transaction -> Either String Transaction+balanceSingleTransaction bopts = fmap fst . balanceTransactionHelper bopts --- | Helper used by balanceTransaction and balanceTransactionWithBalanceAssignmentAndCheckAssertionsB;+-- | Helper used by balanceSingleTransaction and balanceTransactionWithBalanceAssignmentAndCheckAssertionsB; -- use one of those instead. -- It also returns a list of accounts and amounts that were inferred.-balanceTransactionHelper ::-     BalancingOpts-  -> Transaction-  -> Either String (Transaction, [(AccountName, MixedAmount)])+balanceTransactionHelper :: BalancingOpts -> Transaction -> Either String (Transaction, [(AccountName, MixedAmount)]) balanceTransactionHelper bopts t = do   let lbl = lbl_ "balanceTransactionHelper"   (t', inferredamtsandaccts) <- t@@ -411,7 +400,7 @@ --   journalBalanceTransactions --    runST --     runExceptT---      balanceTransaction (Transaction.hs)+--      balanceSingleTransaction (Transaction.hs) --       balanceTransactionHelper --      runReaderT --       balanceTransactionAndCheckAssertionsB@@ -422,7 +411,7 @@ --   journalCheckBalanceAssertions --    journalBalanceTransactions --  transactionWizard, postingsBalanced (Add.hs), tests (Transaction.hs)---   balanceTransaction (Transaction.hs)  XXX hledger add won't allow balance assignments + missing amount ?+--   balanceSingleTransaction (Transaction.hs)  XXX hledger add won't allow balance assignments + missing amount ?  -- | Monad used for statefully balancing/amount-inferring/assertion-checking -- a sequence of transactions.@@ -532,7 +521,7 @@         -- postponing those which do until later. The balanced ones are split into their postings,         -- keeping these and the not-yet-balanced transactions in the same relative order.         psandts :: [Either Posting Transaction] <- fmap concat $ forM ts $ \case-          t | null $ assignmentPostings t -> case balanceTransaction bopts t of+          t | null $ assignmentPostings t -> case balanceSingleTransaction bopts t of               Left  e  -> throwError e               Right t' -> do                 lift $ writeArray balancedtxns (tindex t') t'@@ -810,10 +799,10 @@          (fst <$> transactionInferBalancingAmount M.empty nulltransaction{tpostings = ["a" `post` usd (-5), "b" `post` (eur 3 @@ usd 4), "c" `post` missingamt]}) @?=            Right nulltransaction{tpostings = ["a" `post` usd (-5), "b" `post` (eur 3 @@ usd 4), "c" `post` usd 1]} -    , testGroup "balanceTransaction" [+    , testGroup "balanceSingleTransaction" [          testCase "detect unbalanced entry, sign error" $           assertLeft-            (balanceTransaction defbalancingopts+            (balanceSingleTransaction defbalancingopts                (Transaction                   0                   ""@@ -828,7 +817,7 @@                   [posting {paccount = "a", pamount = mixedAmount (usd 1)}, posting {paccount = "b", pamount = mixedAmount (usd 1)}]))         ,testCase "detect unbalanced entry, multiple missing amounts" $           assertLeft $-             balanceTransaction defbalancingopts+             balanceSingleTransaction defbalancingopts                (Transaction                   0                   ""@@ -845,7 +834,7 @@                   ])         ,testCase "one missing amount is inferred" $           (pamount . last . tpostings <$>-           balanceTransaction defbalancingopts+           balanceSingleTransaction defbalancingopts              (Transaction                 0                 ""@@ -861,7 +850,7 @@           Right (mixedAmount $ usd (-1))         ,testCase "conversion price is inferred" $           (pamount . headErr . tpostings <$>  -- PARTIAL headErr succeeds because non-null postings list-           balanceTransaction defbalancingopts+           balanceSingleTransaction defbalancingopts              (Transaction                 0                 ""@@ -877,9 +866,9 @@                 , posting {paccount = "b", pamount = mixedAmount (eur (-1))}                 ])) @?=           Right (mixedAmount $ usd 1.35 @@ eur 1)-        ,testCase "balanceTransaction balances based on cost if there are unit prices" $+        ,testCase "balanceSingleTransaction balances based on cost if there are unit prices" $           assertRight $-          balanceTransaction defbalancingopts+          balanceSingleTransaction defbalancingopts             (Transaction                0                ""@@ -894,9 +883,9 @@                [ posting {paccount = "a", pamount = mixedAmount $ usd 1 `at` eur 2}                , posting {paccount = "a", pamount = mixedAmount $ usd (-2) `at` eur 1}                ])-        ,testCase "balanceTransaction balances based on cost if there are total prices" $+        ,testCase "balanceSingleTransaction balances based on cost if there are total prices" $           assertRight $-          balanceTransaction defbalancingopts+          balanceSingleTransaction defbalancingopts             (Transaction                0                ""
Hledger/Data/Journal.hs view
@@ -1153,6 +1153,7 @@ -- "comm" and "cur" are accepted as synonyms meaning the commodity symbol. -- Pivoting on an unknown field or tag, or on commodity when there are multiple commodities, returns "". -- Pivoting on a tag when there are multiple values for that tag, returns the first value.+-- Pivoting on the "type" tag normalises type values to their short spelling. pivotComponent :: Text -> Posting -> Text pivotComponent fieldortagname p   | fieldortagname == "code",        Just t <- ptransaction p = tcode t@@ -1164,7 +1165,10 @@   | fieldortagname `elem` commnames = case map acommodity $ amounts $ pamount p of [s] -> s; _ -> unknown   | fieldortagname == "amt"         = case amounts $ pamount p of [a] -> T.pack $ show $ aquantity a; _ -> unknown   | fieldortagname == "cost"        = case amounts $ pamount p of [a@Amount{acost=Just _}] -> T.pack $ lstrip $ showAmountCost a; _ -> unknown-  | Just (_, tagvalue) <- postingFindTag fieldortagname p = tagvalue+  | Just (_, tagvalue) <- postingFindTag fieldortagname p =+      if fieldortagname == "type"+      then either (const tagvalue) (T.pack . show) $ parseAccountType True tagvalue+      else tagvalue   | otherwise = unknown   where     descnames = ["desc", "description"]   -- allow "description" for hledger <=1.30 compat
Hledger/Read.hs view
@@ -133,7 +133,7 @@  --- ** imports import Control.Exception qualified as C-import Control.Monad (unless, when, forM, (<=<))+import Control.Monad (unless, when, forM, (>=>)) import "mtl" Control.Monad.Except (ExceptT(..), runExceptT, liftEither) import Control.Monad.IO.Class (MonadIO, liftIO) import Data.Default (def)@@ -361,7 +361,7 @@  -- | An even easier version of readJournal' which takes a 'Text' instead of a 'Handle'. readJournal'' :: Text -> IO Journal-readJournal'' = readJournal' <=< inputToHandle+readJournal'' = textToHandle >=> readJournal'  -- | An easy version of 'readJournalFile' which assumes default options, and fails -- in the IO monad.
Hledger/Read/Common.hs view
@@ -262,7 +262,7 @@  handleReadFnToTextReadFn :: (InputOpts -> FilePath -> Text -> ExceptT String IO Journal) -> InputOpts -> FilePath -> Handle -> ExceptT String IO Journal handleReadFnToTextReadFn p iopts fp =-  p iopts fp <=< lift . readHandlePortably+  p iopts fp <=< lift . hGetContentsPortably Nothing  -- | Get the date span from --forecast's PERIODEXPR argument, if any. -- This will fail with a usage error if the period expression cannot be parsed,
Hledger/Read/CsvReader.hs view
@@ -63,7 +63,7 @@ parse sep iopts f h = do   rules <- readRules $ getRulesFile f (mrules_file_ iopts)   mencoding <- rulesEncoding rules-  csvtext <- lift $ readHandlePortably' mencoding h+  csvtext <- lift $ hGetContentsPortably mencoding h   readJournalFromCsv rules f csvtext (Just sep)   -- apply any command line account aliases. Can fail with a bad replacement pattern.   >>= liftEither . journalApplyAliases (aliasesFromOpts iopts)
Hledger/Read/JournalReader.hs view
@@ -318,7 +318,7 @@     ) <|> errorNoArg    let (mprefix,glb) = splitReaderPrefix prefixedglob-  parentf <- sourcePosFilePath pos+  parentf <- sourcePosFilePath pos   -- a little slow, don't do too often   when (null $ dbg6 (parentf <> " include: glob pattern") glb) errorNoArg    -- Find the file or glob-matched files (just the ones from this include directive), with some IO error checking.@@ -378,8 +378,7 @@       expandedglob <- lift $ expandHomePath globpattern `orRethrowIOError` "failed to expand ~"        -- get the directory of the including file-      -- need to canonicalise a symlink parentf so takeDirectory works correctly [#2503]-      cwd <- fmap takeDirectory <$> liftIO $ canonicalizePath parentf+      let cwd = takeDirectory parentf        -- Don't allow 3 or more stars.       when ("***" `isInfixOf` expandedglob) $
Hledger/Read/RulesReader.hs view
@@ -235,7 +235,7 @@     (_, Just f,  mc) -> do  -- trace "file found" $       mencoding <- rulesEncoding rules       liftIO $ do-        raw <- openFileOrStdin f >>= readHandlePortably' mencoding+        raw <- openFileOrStdin f >>= hGetContentsPortably mencoding         maybe (return raw) (\c -> runCommandAsFilter rulesfile (dbg0Msg ("running: "++c) c) raw) mc      -- no file pattern, but a data generating command
Hledger/Utils/IO.hs view
@@ -46,10 +46,9 @@   readFileOrStdinPortably',   readFileStrictly,   readFilePortably,-  readHandlePortably,-  readHandlePortably',+  hGetContentsPortably,   -- hereFileRelative,-  inputToHandle,+  textToHandle,    -- * Command line parsing   progArgs,@@ -154,7 +153,7 @@ import           System.FilePath (isRelative, (</>)) import "Glob"    System.FilePath.Glob (glob) import           System.Info (os)-import           System.IO (Handle, IOMode (..), hClose, hGetEncoding, hIsTerminalDevice, hPutStr, hPutStrLn, hSetNewlineMode, hSetEncoding, openFile, stderr, stdin, stdout, universalNewlineMode, utf8_bom)+import           System.IO (Handle, IOMode (..), hClose, hGetEncoding, hIsTerminalDevice, hPutStr, hPutStrLn, hSetNewlineMode, hSetEncoding, openFile, stderr, stdin, stdout, universalNewlineMode, utf8_bom, utf8) import System.IO.Encoding qualified as Enc import           System.IO.Unsafe (unsafePerformIO) import           System.Process (CreateProcess(..), StdStream(CreatePipe), createPipe, shell, waitForProcess, withCreateProcess)@@ -417,6 +416,7 @@ -- | Like expandPath, but treats the expanded path as a glob, and returns -- zero or more matched absolute file paths, alphabetically sorted. -- Can raise an error.+-- For a more elaborate glob expander, see 'findMatchedFiles' (used by the include directive). expandGlob :: FilePath -> FilePath -> IO [FilePath] expandGlob curdir p = expandPath curdir p >>= glob <&> sort  -- PARTIAL: @@ -435,7 +435,7 @@ -- using the system locale's text encoding, -- ignoring any utf8 BOM prefix (as seen in paypal's 2018 CSV, eg) if that encoding is utf8. readFilePortably :: FilePath -> IO T.Text-readFilePortably f =  openFile f ReadMode >>= readHandlePortably+readFilePortably f = openFile f ReadMode >>= hGetContentsPortably Nothing  -- | Like readFilePortably, but read from standard input if the path is "-". readFileOrStdinPortably :: String -> IO T.Text@@ -443,7 +443,7 @@  -- | Like readFileOrStdinPortably, but take an optional converter. readFileOrStdinPortably' :: Maybe DynEncoding -> String -> IO T.Text-readFileOrStdinPortably' c f = openFileOrStdin f >>= readHandlePortably' c+readFileOrStdinPortably' c f = openFileOrStdin f >>= hGetContentsPortably c  -- | Open a file for reading, using the standard System.IO.openFile. -- This opens the handle in text mode, using the initial system locale's text encoding.@@ -451,32 +451,27 @@ openFileOrStdin "-" = return stdin openFileOrStdin f' = openFile f' ReadMode --- readHandlePortably' with no text encoding specified.-readHandlePortably :: Handle -> IO T.Text-readHandlePortably = readHandlePortably' Nothing---- | Read text from a handle with a specified encoding, using the encoding package.--- Or if no encoding is specified, it uses the handle's current encoding,--- after first changing it to UTF-8BOM if it was UTF-8, to allow a Byte Order Mark at the start.+-- | Read text from a handle, perhaps using a specified encoding from the encoding package.+-- Or if no encoding is specified, using the handle's current encoding,+-- changing it to UTF-8BOM if it was UTF-8, to ignore any Byte Order Mark at the start. -- Also it converts Windows line endings to newlines. -- If decoding fails, this throws an IOException (or possibly a UnicodeException or something else from the encoding package).-readHandlePortably' :: Maybe DynEncoding -> Handle -> IO T.Text-readHandlePortably' Nothing h = do+hGetContentsPortably :: Maybe DynEncoding -> Handle -> IO T.Text+hGetContentsPortably Nothing h = do   hSetNewlineMode h universalNewlineMode   menc <- hGetEncoding h   when (fmap show menc == Just "UTF-8") $ hSetEncoding h utf8_bom   T.hGetContents h-readHandlePortably' (Just e) h =+hGetContentsPortably (Just e) h =   -- convert newlines manually, because Enc.hGetContents uses bytestring's hGetContents   T.replace "\r\n" "\n" . T.pack <$> let ?enc = e in Enc.hGetContents h --- | Create a handle from which the given text can be read.--- Its encoding will be UTF-8BOM.-inputToHandle :: T.Text -> IO Handle-inputToHandle t = do+-- | Create a handle from which the given text can be read. Its encoding will be UTF-8.+textToHandle :: T.Text -> IO Handle+textToHandle t = do   (r, w) <- createPipe-  hSetEncoding r utf8_bom-  hSetEncoding w utf8_bom+  hSetEncoding r utf8+  hSetEncoding w utf8   -- use a separate thread so that we don't deadlock if we can't write all of the text at once   forkIO $ T.hPutStr w t >> hClose w   return r
hledger-lib.cabal view
@@ -5,7 +5,7 @@ -- see: https://github.com/sol/hpack  name:           hledger-lib-version:        1.50.5+version:        1.51 synopsis:       A library providing the core functionality of hledger description:    This library contains hledger's core functionality.                 It is used by most hledger* packages so that they support the same@@ -46,7 +46,7 @@   location: https://github.com/simonmichael/hledger  flag debug-  description: Build with GHC 9.10+'s stack traces enabled+  description: Build with GHC 9.10+ stack traces enabled   manual: True   default: False @@ -57,9 +57,11 @@       Hledger.Data.Account       Hledger.Data.AccountName       Hledger.Data.Amount+      Hledger.Data.BalanceData       Hledger.Data.Balancing       Hledger.Data.Currency       Hledger.Data.Dates+      Hledger.Data.DayPartition       Hledger.Data.Errors       Hledger.Data.Journal       Hledger.Data.JournalChecks@@ -68,10 +70,11 @@       Hledger.Data.Json       Hledger.Data.Ledger       Hledger.Data.Period+      Hledger.Data.PeriodData       Hledger.Data.PeriodicTransaction-      Hledger.Data.StringFormat       Hledger.Data.Posting       Hledger.Data.RawOptions+      Hledger.Data.StringFormat       Hledger.Data.Timeclock       Hledger.Data.Transaction       Hledger.Data.TransactionModifier@@ -84,26 +87,17 @@       Hledger.Read.InputOptions       Hledger.Read.JournalReader       Hledger.Read.RulesReader-      Hledger.Read.TimedotReader       Hledger.Read.TimeclockReader-      Hledger.Write.Beancount-      Hledger.Write.Csv-      Hledger.Write.Ods-      Hledger.Write.Html-      Hledger.Write.Html.Attribute-      Hledger.Write.Html.Blaze-      Hledger.Write.Html.Lucid-      Hledger.Write.Html.HtmlCommon-      Hledger.Write.Spreadsheet+      Hledger.Read.TimedotReader       Hledger.Reports-      Hledger.Reports.ReportOptions-      Hledger.Reports.ReportTypes       Hledger.Reports.AccountTransactionsReport       Hledger.Reports.BalanceReport       Hledger.Reports.BudgetReport       Hledger.Reports.EntriesReport       Hledger.Reports.MultiBalanceReport       Hledger.Reports.PostingsReport+      Hledger.Reports.ReportOptions+      Hledger.Reports.ReportTypes       Hledger.Utils       Hledger.Utils.Debug       Hledger.Utils.IO@@ -112,18 +106,25 @@       Hledger.Utils.String       Hledger.Utils.Test       Hledger.Utils.Text+      Hledger.Write.Beancount+      Hledger.Write.Csv+      Hledger.Write.Html+      Hledger.Write.Html.Attribute+      Hledger.Write.Html.Blaze+      Hledger.Write.Html.HtmlCommon+      Hledger.Write.Html.Lucid+      Hledger.Write.Ods+      Hledger.Write.Spreadsheet       Text.Tabular.AsciiWide       Text.WideString   other-modules:-      Hledger.Data.BalanceData-      Hledger.Data.DayPartition-      Hledger.Data.PeriodData       Paths_hledger_lib   autogen-modules:       Paths_hledger_lib   hs-source-dirs:       ./   ghc-options: -Wall -Wno-incomplete-uni-patterns -Wno-missing-signatures -Wno-orphans -Wno-type-defaults -Wno-unused-do-bind+  cpp-options: -DVERSION="1.51"   build-depends:       Decimal >=0.5.1     , Glob >=0.9@@ -183,6 +184,7 @@   hs-source-dirs:       test   ghc-options: -Wall -Wno-incomplete-uni-patterns -Wno-missing-signatures -Wno-orphans -Wno-type-defaults -Wno-unused-do-bind+  cpp-options: -DVERSION="1.51"   build-depends:       Decimal >=0.5.1     , Glob >=0.7@@ -236,8 +238,6 @@   default-language: GHC2021   if (flag(debug))     cpp-options: -DDEBUG-  if impl(ghc >= 9.0) && impl(ghc < 9.2)-    buildable: False  test-suite unittest   type: exitcode-stdio-1.0@@ -245,6 +245,7 @@   hs-source-dirs:       test   ghc-options: -Wall -Wno-incomplete-uni-patterns -Wno-missing-signatures -Wno-orphans -Wno-type-defaults -Wno-unused-do-bind+  cpp-options: -DVERSION="1.51"   build-depends:       Decimal >=0.5.1     , Glob >=0.9