1 {-|
    2 
    3 Utilities for top-level modules and ghci. See also "Ledger.IO" and
    4 "Ledger.Utils".
    5 
    6 -}
    7 
    8 module Utils
    9 where
   10 import Control.Monad.Error
   11 import Data.Time.Clock
   12 import Ledger
   13 import Options (Opt,ledgerFilePathFromOpts,optsToIOArgs)
   14 import System.Directory (doesFileExist)
   15 import System.IO
   16 import Text.ParserCombinators.Parsec
   17 import qualified Data.Map as Map (lookup)
   18 
   19 
   20 -- | Parse the user's specified ledger file and run a hledger command on
   21 -- it, or report a parse error. This function makes the whole thing go.
   22 withLedgerDo :: [Opt] -> [String] -> String -> ([Opt] -> [String] -> Ledger -> IO ()) -> IO ()
   23 withLedgerDo opts args cmdname cmd = do
   24   -- We kludgily read the file before parsing to grab the full text, unless
   25   -- it's stdin, or it doesn't exist and we are adding. We read it strictly
   26   -- to let the add command work.
   27   f <- ledgerFilePathFromOpts opts
   28   let f' = if f == "-" then "/dev/null" else f
   29   fileexists <- doesFileExist f
   30   let creating = not fileexists && cmdname == "add"
   31   rawtext <-  if creating then return "" else strictReadFile f'
   32   t <- getCurrentLocalTime
   33   let go = cmd opts args . filterAndCacheLedgerWithOpts opts args t rawtext . (\rl -> rl{filepath=f})
   34   case creating of
   35     True -> return rawLedgerEmpty >>= go
   36     False -> return f >>= runErrorT . parseLedgerFile t >>= either (hPutStrLn stderr) go
   37 
   38 -- | Get a Ledger from the given string and options, or raise an error.
   39 ledgerFromStringWithOpts :: [Opt] -> [String] -> LocalTime -> String -> IO Ledger
   40 ledgerFromStringWithOpts opts args reftime s =
   41     liftM (filterAndCacheLedgerWithOpts opts args reftime s) $ rawLedgerFromString s
   42 
   43 -- | Read a Ledger from the given file, filtering according to the
   44 -- options, or give an error.
   45 readLedgerWithOpts :: [Opt] -> [String] -> FilePath -> IO Ledger
   46 readLedgerWithOpts opts args f = do
   47   t <- getCurrentLocalTime
   48   readLedgerWithIOArgs (optsToIOArgs opts args t) f
   49            
   50 -- | Convert a RawLedger to a canonicalised, cached and filtered Ledger
   51 -- based on the command-line options/arguments and a reference time.
   52 filterAndCacheLedgerWithOpts ::  [Opt] -> [String] -> LocalTime -> String -> RawLedger -> Ledger
   53 filterAndCacheLedgerWithOpts opts args t = filterAndCacheLedger (optsToIOArgs opts args t)
   54