From a1b68009da934226e4823c815b338ce2bcc92f2b Mon Sep 17 00:00:00 2001 From: Simon Michael Date: Tue, 24 May 2016 18:28:26 -0700 Subject: [PATCH] lib: fix tests; always try parsing stdin as journal --- hledger-lib/Hledger/Read.hs | 24 +++++++++++------------ hledger-lib/Hledger/Read/Common.hs | 7 ++++--- hledger-lib/Hledger/Read/JournalReader.hs | 8 +++++--- 3 files changed, 20 insertions(+), 19 deletions(-) diff --git a/hledger-lib/Hledger/Read.hs b/hledger-lib/Hledger/Read.hs index b23c51e12..59ca84abd 100644 --- a/hledger-lib/Hledger/Read.hs +++ b/hledger-lib/Hledger/Read.hs @@ -99,7 +99,7 @@ readerForStorageFormat s | null rs = Nothing -- | Find the readers which think they can handle the given file path and data, if any. readersForPathAndData :: (FilePath,Text) -> [Reader] -readersForPathAndData (f,t) = filter (\r -> (rDetector r) f t) readers +readersForPathAndData (f,t) = filter (\r -> dbg1 ("try "++rFormat r++" format") $ (rDetector r) f t) readers -- try each reader in turn, returning the error of the first if all fail tryReaders :: [Reader] -> Maybe FilePath -> Bool -> Maybe FilePath -> Text -> IO (Either String Journal) @@ -116,7 +116,6 @@ tryReaders readers mrulesfile assrt path t = firstSuccessOrBestError [] readers firstSuccessOrBestError (e:_) [] = return $ Left e -- none left, return first error path' = fromMaybe "(string)" path - -- | Read a journal from this string, trying whatever readers seem appropriate: -- -- - if a format is specified, try that reader only @@ -130,16 +129,6 @@ tryReaders readers mrulesfile assrt path t = firstSuccessOrBestError [] readers readJournal :: Maybe StorageFormat -> Maybe FilePath -> Bool -> Maybe FilePath -> Text -> IO (Either String Journal) readJournal mformat mrulesfile assrt mpath t = tryReaders (readersFor (mformat, mpath, t)) mrulesfile assrt mpath t --- | Read a Journal from this file (or stdin if the filename is -) or give --- an error message, using the specified data format or trying all known --- formats. A CSV conversion rules file may be specified for better --- conversion of that format. Also there is a flag specifying whether --- to check or ignore balance assertions in the journal. -readJournalFile :: Maybe StorageFormat -> Maybe FilePath -> Bool -> FilePath -> IO (Either String Journal) -readJournalFile mformat mrulesfile assrt f = do - -- requireJournalFileExists f -- XXX ? - readFileOrStdinAnyLineEnding f >>= readJournal mformat mrulesfile assrt (Just f) - -- | Call readJournalFile on each specified file path, and combine the -- resulting journals into one. If there are any errors, the first is -- returned, otherwise they are combined per Journal's monoid instance @@ -152,6 +141,16 @@ readJournalFiles mformat mrulesfile assrt fs = do (either Left (Right . mconcat) . sequence) <$> mapM (readJournalFile mformat mrulesfile assrt) fs +-- | Read a Journal from this file (or stdin if the filename is -) or give +-- an error message, using the specified data format or trying all known +-- formats. A CSV conversion rules file may be specified for better +-- conversion of that format. Also there is a flag specifying whether +-- to check or ignore balance assertions in the journal. +readJournalFile :: Maybe StorageFormat -> Maybe FilePath -> Bool -> FilePath -> IO (Either String Journal) +readJournalFile mformat mrulesfile assrt f = do + requireJournalFileExists f + readFileOrStdinAnyLineEnding f >>= readJournal mformat mrulesfile assrt (Just f) + -- | If the specified journal file does not exist, give a helpful error and quit. requireJournalFileExists :: FilePath -> IO () requireJournalFileExists "-" = return () @@ -163,7 +162,6 @@ requireJournalFileExists f = do hPrintf stderr "Or, specify an existing journal file with -f or LEDGER_FILE.\n" exitFailure - -- | Ensure there is a journal file at the given path, creating an empty one if needed. ensureJournalFileExists :: FilePath -> IO () ensureJournalFileExists f = do diff --git a/hledger-lib/Hledger/Read/Common.hs b/hledger-lib/Hledger/Read/Common.hs index ec5915bec..8d36f4683 100644 --- a/hledger-lib/Hledger/Read/Common.hs +++ b/hledger-lib/Hledger/Read/Common.hs @@ -39,6 +39,7 @@ import Text.Parsec hiding (parse) import Hledger.Data import Hledger.Utils +-- $setup --- * parsing utils @@ -668,7 +669,7 @@ tagsp = -- do -- | Parse everything up till the first tag. -- --- >>> rsp nontagp "\na b:, \nd:e, f" +-- >>> rtp nontagp "\na b:, \nd:e, f" -- Right "\na " nontagp :: TextParser u Identity String nontagp = -- do @@ -681,7 +682,7 @@ nontagp = -- do -- a letter) and are followed by a tag value (any text up to a comma -- or newline, whitespace-stripped). -- --- >>> rsp tagp "a:b b , c AuxDate: 4/2" +-- >>> rtp tagp "a:b b , c AuxDate: 4/2" -- Right ("a","b b") -- tagp :: Monad m => TextParser u m Tag @@ -692,7 +693,7 @@ tagp = do return (n,v) -- | --- >>> rsp tagnamep "a:" +-- >>> rtp tagnamep "a:" -- Right "a" tagnamep :: Monad m => TextParser u m Text tagnamep = -- do diff --git a/hledger-lib/Hledger/Read/JournalReader.hs b/hledger-lib/Hledger/Read/JournalReader.hs index cc443beca..af82b5181 100644 --- a/hledger-lib/Hledger/Read/JournalReader.hs +++ b/hledger-lib/Hledger/Read/JournalReader.hs @@ -32,7 +32,6 @@ import cycles. {-# LANGUAGE CPP, RecordWildCards, NamedFieldPuns, NoMonoLocalBinds, ScopedTypeVariables, FlexibleContexts, TupleSections, OverloadedStrings #-} module Hledger.Read.JournalReader ( - --- * exports -- * Reader @@ -102,6 +101,8 @@ import Hledger.Read.TimeclockReader (timeclockfilep) import Hledger.Read.TimedotReader (timedotfilep) import Hledger.Utils +-- $setup +-- >>> :set -XOverloadedStrings --- * reader @@ -113,9 +114,10 @@ format = "journal" -- | Does the given file path and data look like it might be hledger's journal format ? detect :: FilePath -> Text -> Bool -detect f t +detect f _t | f /= "-" = takeExtension f `elem` ['.':format, ".j"] -- from a known file name: yes if the extension is this format's name or .j - | otherwise = regexMatches "(^|\n)[0-9]+.*\n[ \t]+" $ T.unpack t -- from stdin: yes if we can see something that looks like a journal entry (digits in column 0 with the next line indented) + | otherwise = True -- from stdin: yes, always attempt to parse stdin as journal data + -- otherwise = regexMatches "(^|\n)[0-9]+.*\n[ \t]+" $ T.unpack t -- from stdin: yes if we can see something that looks like a journal entry (digits in column 0 with the next line indented) -- | Parse and post-process a "Journal" from hledger's journal file -- format, or give an error.