packages feed

hledger-lib 1.52 → 1.52.1

raw patch · 11 files changed

+99/−81 lines, 11 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

+ Hledger.Data: UnrealisedGain :: AccountType
+ Hledger.Data.Balancing: [account_types_] :: BalancingOpts -> Map AccountName AccountType
+ Hledger.Data.Balancing: account_types :: HasBalancingOpts c => Lens' c (Map AccountName AccountType)
+ Hledger.Data.Types: UnrealisedGain :: AccountType
+ Hledger.Utils.Test: dependentTestGroup :: TestName -> DependencyType -> [TestTree] -> TestTree
+ Hledger.Utils.Test: inOrderTestGroup :: TestName -> [TestTree] -> TestTree
- Hledger.Data.Balancing: BalancingOpts :: Bool -> Bool -> Maybe (Map CommoditySymbol AmountStyle) -> TransactionBalancingPrecision -> BalancingOpts
+ Hledger.Data.Balancing: BalancingOpts :: Bool -> Bool -> Maybe (Map CommoditySymbol AmountStyle) -> TransactionBalancingPrecision -> Map AccountName AccountType -> BalancingOpts

Files

CHANGES.md view
@@ -17,6 +17,9 @@ For user-visible changes, see the hledger package changelog.  +# 1.52.1 2026-04-28+ +  # 1.52 2026-03-20  Breaking changes
Hledger/Data/AccountName.hs view
@@ -112,7 +112,6 @@   | regexMatchText liabilityAccountRegex  a = Just Liability   | regexMatchText conversionAccountRegex a = Just Conversion   | regexMatchText equityAccountRegex     a = Just Equity-  | regexMatchText gainAccountRegex       a = Just Gain   | regexMatchText revenueAccountRegex    a = Just Revenue   | regexMatchText expenseAccountRegex    a = Just Expense   | otherwise                               = Nothing@@ -450,13 +449,14 @@     accountNameInferType "revenues"          @?= Just Revenue     accountNameInferType "revenue"           @?= Just Revenue     accountNameInferType "income"            @?= Just Revenue-    accountNameInferType "income:gains"          @?= Just Gain-    accountNameInferType "revenue:gain"          @?= Just Gain-    accountNameInferType "revenues:capital-gains" @?= Just Gain-    accountNameInferType "income:capitalgain"    @?= Just Gain-    accountNameInferType "income:losses"         @?= Just Gain-    accountNameInferType "revenue:capital-loss"  @?= Just Gain-    accountNameInferType "income:gains:realized" @?= Just Gain+    -- Gain type is no longer inferred from names; these are now Revenue+    accountNameInferType "income:gains"          @?= Just Revenue+    accountNameInferType "revenue:gain"          @?= Just Revenue+    accountNameInferType "revenues:capital-gains" @?= Just Revenue+    accountNameInferType "income:capitalgain"    @?= Just Revenue+    accountNameInferType "income:losses"         @?= Just Revenue+    accountNameInferType "revenue:capital-loss"  @?= Just Revenue+    accountNameInferType "income:gains:realized" @?= Just Revenue   ,testCase "joinAccountNames" $ do     joinAccountNames "assets" "cash"     @?= "assets:cash"     joinAccountNames "assets:cash" "a"   @?= "assets:cash:a"
Hledger/Data/Balancing.hs view
@@ -66,6 +66,7 @@                                     --   Distinct from InputOpts{infer_costs_}.   , commodity_styles_      :: Maybe (M.Map CommoditySymbol AmountStyle)  -- ^ commodity display styles   , txn_balancing_         :: TransactionBalancingPrecision+  , account_types_         :: M.Map AccountName AccountType  -- ^ account type map, passed through for any balancing helpers that need it   } deriving (Eq, Ord, Show)  defbalancingopts :: BalancingOpts@@ -74,6 +75,7 @@   , infer_balancing_costs_ = True   , commodity_styles_      = Nothing   , txn_balancing_         = TBPExact+  , account_types_         = M.empty   }  -- | Check that this transaction would appear balanced to a human when displayed.@@ -193,7 +195,7 @@   (t', inferredamtsandaccts) <- t     & (if infer_balancing_costs_ bopts then transactionInferBalancingCosts else id)     & dbg9With (lbl "amounts after balancing-cost-inferring".show.map showMixedAmountOneLine.transactionAmounts)-    & transactionInferBalancingAmount (fromMaybe M.empty $ commodity_styles_ bopts)+    & transactionInferBalancingAmount (fromMaybe M.empty $ commodity_styles_ bopts) (account_types_ bopts)     <&> dbg9With (lbl "balancing amounts inferred".show.map (second showMixedAmountOneLine).snd)   case transactionCheckBalanced bopts t' of     []   -> Right (txnTieKnot t', inferredamtsandaccts)@@ -242,9 +244,10 @@ -- have the same price(s), and will be converted to the price commodity. transactionInferBalancingAmount ::      M.Map CommoditySymbol AmountStyle -- ^ commodity display styles+  -> M.Map AccountName AccountType     -- ^ account type map (passed through; reserved for future use)   -> Transaction   -> Either String (Transaction, [(AccountName, MixedAmount)])-transactionInferBalancingAmount styles t@Transaction{tpostings=ps}+transactionInferBalancingAmount styles _atypes t@Transaction{tpostings=ps}   | length amountlessrealps > 1       = Left $ transactionBalanceError t         ["There can't be more than one real posting with no amount."@@ -793,10 +796,10 @@   testGroup "Balancing" [        testCase "transactionInferBalancingAmount" $ do-         (fst <$> transactionInferBalancingAmount M.empty nulltransaction) @?= Right nulltransaction-         (fst <$> transactionInferBalancingAmount M.empty nulltransaction{tpostings = ["a" `post` usd (-5), "b" `post` missingamt]}) @?=+         (fst <$> transactionInferBalancingAmount M.empty M.empty nulltransaction) @?= Right nulltransaction+         (fst <$> transactionInferBalancingAmount M.empty M.empty nulltransaction{tpostings = ["a" `post` usd (-5), "b" `post` missingamt]}) @?=            Right nulltransaction{tpostings = ["a" `post` usd (-5), "b" `post` usd 5]}-         (fst <$> transactionInferBalancingAmount M.empty nulltransaction{tpostings = ["a" `post` usd (-5), "b" `post` (eur 3 @@ usd 4), "c" `post` missingamt]}) @?=+         (fst <$> transactionInferBalancingAmount M.empty 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 "balanceSingleTransaction" [
Hledger/Data/Types.hs view
@@ -187,20 +187,22 @@   | Equity   | Revenue   | Expense-  | Cash  -- ^ a subtype of Asset - liquid assets to show in cashflow report-  | Conversion -- ^ a subtype of Equity - account with which to balance commodity conversions-  | Gain      -- ^ a subtype of Revenue - capital gains/losses+  | Cash            -- ^ a subtype of Asset - liquid assets to show in cashflow report+  | Conversion      -- ^ a subtype of Equity - account with which to balance commodity conversions+  | Gain            -- ^ a subtype of Revenue - realised capital gains/losses+  | UnrealisedGain  -- ^ a subtype of Equity - accumulated unrealised capital gains/losses (used by hledger 2)   deriving (Eq,Ord,Generic)  instance Show AccountType where-  show Asset      = "A"-  show Liability  = "L"-  show Equity     = "E"-  show Revenue    = "R"-  show Expense    = "X"-  show Cash       = "C"-  show Conversion = "V"-  show Gain       = "G"+  show Asset          = "A"+  show Liability      = "L"+  show Equity         = "E"+  show Revenue        = "R"+  show Expense        = "X"+  show Cash           = "C"+  show Conversion     = "V"+  show Gain           = "G"+  show UnrealisedGain = "U"  isBalanceSheetAccountType :: AccountType -> Bool isBalanceSheetAccountType t = t `elem` [@@ -208,7 +210,8 @@   Liability,   Equity,   Cash,-  Conversion+  Conversion,+  UnrealisedGain   ]  isIncomeStatementAccountType :: AccountType -> Bool@@ -221,18 +224,20 @@ -- | Check whether the first argument is a subtype of the second: either equal -- or one of the defined subtypes. isAccountSubtypeOf :: AccountType -> AccountType -> Bool-isAccountSubtypeOf Asset      Asset      = True-isAccountSubtypeOf Liability  Liability  = True-isAccountSubtypeOf Equity     Equity     = True-isAccountSubtypeOf Revenue    Revenue    = True-isAccountSubtypeOf Expense    Expense    = True-isAccountSubtypeOf Cash       Cash       = True-isAccountSubtypeOf Cash       Asset      = True-isAccountSubtypeOf Conversion Conversion = True-isAccountSubtypeOf Conversion Equity     = True-isAccountSubtypeOf Gain       Gain       = True-isAccountSubtypeOf Gain       Revenue    = True-isAccountSubtypeOf _          _          = False+isAccountSubtypeOf Asset          Asset          = True+isAccountSubtypeOf Liability      Liability      = True+isAccountSubtypeOf Equity         Equity         = True+isAccountSubtypeOf Revenue        Revenue        = True+isAccountSubtypeOf Expense        Expense        = True+isAccountSubtypeOf Cash           Cash           = True+isAccountSubtypeOf Cash           Asset          = True+isAccountSubtypeOf Conversion     Conversion     = True+isAccountSubtypeOf Conversion     Equity         = True+isAccountSubtypeOf Gain           Gain           = True+isAccountSubtypeOf Gain           Revenue        = True+isAccountSubtypeOf UnrealisedGain UnrealisedGain = True+isAccountSubtypeOf UnrealisedGain Equity         = True+isAccountSubtypeOf _              _              = False  -- not worth the trouble, letters defined in accountdirectivep for now --instance Read AccountType
Hledger/Query.hs view
@@ -519,8 +519,8 @@ accountTypeChoices allowlongform =   intercalate ", "     -- keep synced with parseAccountType-    $ ["A","L","E","R","X","C","V","G"]-    ++ if allowlongform then ["Asset","Liability","Equity","Revenue","Expense","Cash","Conversion","Gain"] else []+    $ ["A","L","E","R","X","C","V","G","U"]+    ++ if allowlongform then ["Asset","Liability","Equity","Revenue","Expense","Cash","Conversion","Gain","UnrealisedGain"] else []  -- | Case-insensitively parse one single-letter code, or one long-form word if permitted, to an account type. -- On failure, returns the unparseable text.@@ -528,23 +528,26 @@ parseAccountType allowlongform s =   case T.toLower s of     -- keep synced with accountTypeChoices-    "a"                          -> Right Asset-    "l"                          -> Right Liability-    "e"                          -> Right Equity-    "r"                          -> Right Revenue-    "x"                          -> Right Expense-    "c"                          -> Right Cash-    "v"                          -> Right Conversion-    "g"                          -> Right Gain-    "asset"      | allowlongform -> Right Asset-    "liability"  | allowlongform -> Right Liability-    "equity"     | allowlongform -> Right Equity-    "revenue"    | allowlongform -> Right Revenue-    "expense"    | allowlongform -> Right Expense-    "cash"       | allowlongform -> Right Cash-    "conversion" | allowlongform -> Right Conversion-    "gains"      | allowlongform -> Right Gain-    _                            -> Left $ T.unpack s+    "a"                               -> Right Asset+    "l"                               -> Right Liability+    "e"                               -> Right Equity+    "r"                               -> Right Revenue+    "x"                               -> Right Expense+    "c"                               -> Right Cash+    "v"                               -> Right Conversion+    "g"                               -> Right Gain+    "u"                               -> Right UnrealisedGain+    "asset"          | allowlongform  -> Right Asset+    "liability"      | allowlongform  -> Right Liability+    "equity"         | allowlongform  -> Right Equity+    "revenue"        | allowlongform  -> Right Revenue+    "expense"        | allowlongform  -> Right Expense+    "cash"           | allowlongform  -> Right Cash+    "conversion"     | allowlongform  -> Right Conversion+    "gain"           | allowlongform  -> Right Gain+    "unrealisedgain" | allowlongform  -> Right UnrealisedGain+    "unrealizedgain" | allowlongform  -> Right UnrealisedGain+    _                                 -> Left $ T.unpack s  -- | Parse the value part of a "status:" query, or return an error. parseStatus :: T.Text -> Either String Status
Hledger/Read/Common.hs view
@@ -404,7 +404,7 @@        -- >>= \j -> deepseq (concatMap (T.unpack.showTransaction).jtxns $ j) (return j)       <&> dbg9With (lbl "amounts after styling, forecasting, auto-posting".showJournalPostingAmountsDebug)       >>= (\j -> if checkordereddates then journalCheckOrdereddates j $> j else Right j)  -- check ordereddates before assertions. The outer parentheses are needed.-      >>= journalBalanceTransactions balancingopts_{ignore_assertions_=not checkassertions}  -- infer balance assignments and missing amounts, and maybe check balance assertions.+      >>= (\j -> journalBalanceTransactions balancingopts_{ignore_assertions_=not checkassertions, account_types_ = jaccounttypes j} j)  -- infer balance assignments and missing amounts, and maybe check balance assertions.       <&> dbg9With (lbl "amounts after transaction-balancing".showJournalPostingAmountsDebug)       -- <&> dbg9With (("journalFinalise amounts after styling, forecasting, auto postings, transaction balancing"<>).showJournalPostingAmountsDebug)       >>= journalInferCommodityStyles                    -- infer commodity styles once more now that all posting amounts are present
Hledger/Read/JournalReader.hs view
@@ -549,26 +549,28 @@ parseAccountTypeCode :: Text -> Either String AccountType parseAccountTypeCode s =   case T.toLower s of-    "asset"      -> Right Asset-    "a"          -> Right Asset-    "liability"  -> Right Liability-    "l"          -> Right Liability-    "equity"     -> Right Equity-    "e"          -> Right Equity-    "revenue"    -> Right Revenue-    "r"          -> Right Revenue-    "expense"    -> Right Expense-    "x"          -> Right Expense-    "cash"       -> Right Cash-    "c"          -> Right Cash-    "conversion" -> Right Conversion-    "v"          -> Right Conversion-    "gains"      -> Right Gain-    "g"          -> Right Gain-    _            -> Left err+    "asset"            -> Right Asset+    "a"                -> Right Asset+    "liability"        -> Right Liability+    "l"                -> Right Liability+    "equity"           -> Right Equity+    "e"                -> Right Equity+    "revenue"          -> Right Revenue+    "r"                -> Right Revenue+    "expense"          -> Right Expense+    "x"                -> Right Expense+    "cash"             -> Right Cash+    "c"                -> Right Cash+    "conversion"       -> Right Conversion+    "v"                -> Right Conversion+    "gain"             -> Right Gain+    "g"                -> Right Gain+    "unrealisedgain"   -> Right UnrealisedGain+    "u"                -> Right UnrealisedGain+    _                  -> Left err   where     err = T.unpack $ "invalid account type code "<>s<>", should be one of " <>-            T.intercalate ", " ["A","L","E","R","X","C","V","G","Asset","Liability","Equity","Revenue","Expense","Cash","Conversion","Gain"]+            T.intercalate ", " ["A","L","E","R","X","C","V","G","U","Asset","Liability","Equity","Revenue","Expense","Cash","Conversion","Gain","UnrealisedGain"]  -- Add an account declaration to the journal, auto-numbering it. addAccountDeclaration :: (AccountName,Text,[Tag],SourcePos) -> JournalParser m ()
Hledger/Reports/AccountTransactionsReport.hs view
@@ -146,7 +146,7 @@       | balanceaccum_ ropts == Historical = sumPostings priorps       | otherwise                         = nullmixedamt       where-        priorps = dbg5 "priorps" . journalPostings $ filterJournalPostings priorq acctJournal+        priorps = dbg5 "priorps" . filter hasAmount . journalPostings $ filterJournalPostings priorq acctJournal         priorq = dbg5 "priorq" $ And [thisacctq, tostartdateq, datelessreportq]         tostartdateq =           case mstartdate of
Hledger/Reports/MultiBalanceReport.hs view
@@ -183,6 +183,7 @@ getPostings :: ReportSpec -> Journal -> PriceOracle -> DateSpan -> [Posting] getPostings rspec@ReportSpec{_rsQuery=query, _rsReportOpts=ropts} j priceoracle reportspan =     setPostingsCount+    . filter hasAmount  -- omit postings with no definite amount     . journalPostings     $ journalValueAndFilterPostingsWith rspec' j priceoracle   where
Hledger/Reports/PostingsReport.hs view
@@ -156,9 +156,10 @@     dbg5 "beforeps, duringps" $ span (beforestartq `matchesPosting`) beforeandduringps   where     beforestartq = dbg3 "beforestartq" $ dateqtype $ DateSpan Nothing (Exact <$> spanStart reportspan)-    beforeandduringps = +    beforeandduringps =         sortOn (postingDateOrDate2 (whichDate ropts))            -- sort postings by date or date2       . (if invert_ ropts then map postingNegateMainAmount else id)  -- with --invert, invert amounts+      . filter hasAmount                                         -- omit postings with no definite amount       . journalPostings       -- With most calls we will not require transaction prices past this point, and can get a big       -- speed improvement by stripping them early. In some cases, such as in hledger-ui, we still
hledger-lib.cabal view
@@ -5,7 +5,7 @@ -- see: https://github.com/sol/hpack  name:           hledger-lib-version:        1.52+version:        1.52.1 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@@ -124,7 +124,7 @@   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.52"+  cpp-options: -DVERSION="1.52.1"   build-depends:       Decimal >=0.5.1     , Glob >=0.9@@ -184,7 +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.52"+  cpp-options: -DVERSION="1.52.1"   build-depends:       Decimal >=0.5.1     , Glob >=0.7@@ -245,7 +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.52"+  cpp-options: -DVERSION="1.52.1"   build-depends:       Decimal >=0.5.1     , Glob >=0.9