The previous cleanup defined long help separately from the usage text generated by cmdargs. This meant keeping flag descriptions synced between the two, and also the short help was often too verbose and longer than the long help. Now, the non-usage bits of long help are defined as pre and postambles within the cmdargs mode, letting cmdargs generate the long help including all flags. We derive the short help from this by truncating at the start of the hledger common flags. Most of the bundled addons (all but hledger-budget) now use the new scheme and have pretty reasonable -h and --help output. We can do more to reduce boilerplate for addon authors.
		
			
				
	
	
		
			59 lines
		
	
	
		
			1.8 KiB
		
	
	
	
		
			Haskell
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			59 lines
		
	
	
		
			1.8 KiB
		
	
	
	
		
			Haskell
		
	
	
		
			Executable File
		
	
	
	
	
| #!/usr/bin/env stack
 | |
| {- stack runghc --verbosity info
 | |
|    --package hledger-lib
 | |
|    --package here
 | |
|    --package safe
 | |
|    --package text
 | |
| -}
 | |
| 
 | |
| {-# LANGUAGE QuasiQuotes #-}
 | |
| 
 | |
| import Hledger
 | |
| import Hledger.Cli
 | |
| import Text.Printf (printf)
 | |
| import System.Environment (getArgs)
 | |
| import Safe (headDef)
 | |
| import Data.List
 | |
| import Data.Function
 | |
| import Data.String.Here
 | |
| import qualified Data.Text as T
 | |
| 
 | |
| ------------------------------------------------------------------------------
 | |
| cmdmode = (defAddonCommandMode "dupes") {
 | |
|    modeHelp = [here|
 | |
| 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
 | |
|   |]
 | |
|   ,modeHelpSuffix=lines [here|
 | |
|   |]
 | |
|   }
 | |
| ------------------------------------------------------------------------------
 | |
| 
 | |
| main = do
 | |
|   opts <- getHledgerCliOpts cmdmode
 | |
|   withJournalDo opts $ \CliOpts{rawopts_=opts,reportopts_=ropts} j -> do
 | |
|     mapM_ render $ dupes $ accountsNames j
 | |
| 
 | |
| 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))
 |