-
Notifications
You must be signed in to change notification settings - Fork 2
/
hledger-dupes.hs
51 lines (42 loc) · 1.49 KB
/
hledger-dupes.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#!/usr/bin/env stack
{- stack runghc --verbosity info
--package hledger-lib
--package safe
--package text
-}
{-
hledger-dupes [FILE]
Reports duplicates in the account tree: account names having the same leaf
but different prefixes. In other words, two or more leaves that are
categorized differently.
Reads the default journal file, or another specified as an argument.
http://stefanorodighiero.net/software/hledger-dupes.html
-}
import Hledger
import Text.Printf (printf)
import System.Environment (getArgs)
import Safe (headDef)
import Data.List
import Data.Function
import qualified Data.Text as T
accountsNames :: Journal -> [(String, AccountName)]
accountsNames j = map leafAndAccountName as
where leafAndAccountName a = (T.unpack $ accountLeafName a, a)
ps = journalPostings j
as = nub $ sort $ map paccount ps
dupes :: (Ord k, Eq k) => [(k, v)] -> [(k, [v])]
dupes l = zip dupLeafs dupAccountNames
where dupLeafs = map (fst . head) d
dupAccountNames = map (map snd) d
d = dupes' l
dupes' = filter ((> 1) . length)
. groupBy ((==) `on` fst)
. sortBy (compare `on` fst)
render :: (String, [AccountName]) -> IO ()
render (leafName, accountNameL) = printf "%s as %s\n" leafName (concat $ intersperse ", " (map T.unpack accountNameL))
main = do
args <- getArgs
deffile <- defaultJournalPath
let file = headDef deffile args
j <- readJournalFile Nothing Nothing True file >>= either error' return
mapM_ render $ dupes $ accountsNames j