auto-create missing journal files rather than giving an error
This commit is contained in:
parent
50aeb272b0
commit
eefb04abfe
@ -28,13 +28,14 @@ import qualified Data.Foldable as Foldable (find)
|
||||
-- command has no effect.
|
||||
add :: [Opt] -> [String] -> Journal -> IO ()
|
||||
add opts args j
|
||||
| filepath j == "-" = return ()
|
||||
| f == "-" = return ()
|
||||
| otherwise = do
|
||||
hPutStrLn stderr $
|
||||
"Enter one or more transactions, which will be added to your journal file.\n"
|
||||
++"To complete a transaction, enter . as account name. To quit, press control-c."
|
||||
today <- getCurrentDay
|
||||
getAndAddTransactions j opts args today `catch` (\e -> unless (isEOFError e) $ ioError e)
|
||||
where f = filepath j
|
||||
|
||||
-- | Read a number of transactions from the command line, prompting,
|
||||
-- validating, displaying and appending them to the journal file, until
|
||||
|
||||
@ -23,7 +23,7 @@ import Hledger.Data
|
||||
import Hledger.Read
|
||||
import Hledger.Cli.Options (Opt(..),journalFilePathFromOpts) -- ,optsToFilterSpec)
|
||||
import Safe (readMay)
|
||||
import System.Directory (doesFileExist, getModificationTime, getDirectoryContents, copyFile)
|
||||
import System.Directory (getModificationTime, getDirectoryContents, copyFile)
|
||||
import System.Exit
|
||||
import System.FilePath ((</>), splitFileName, takeDirectory)
|
||||
import System.Info (os)
|
||||
@ -34,25 +34,21 @@ import System.Time (ClockTime, getClockTime, diffClockTimes, TimeDiff(TimeDiff))
|
||||
-- | Parse the user's specified journal file and run a hledger command on
|
||||
-- it, or throw an error.
|
||||
withJournalDo :: [Opt] -> [String] -> String -> ([Opt] -> [String] -> Journal -> IO ()) -> IO ()
|
||||
withJournalDo opts args cmdname cmd = do
|
||||
withJournalDo opts args _ cmd = do
|
||||
-- We kludgily read the file before parsing to grab the full text, unless
|
||||
-- it's stdin, or it doesn't exist and we are adding. We read it strictly
|
||||
-- to let the add command work.
|
||||
f <- journalFilePathFromOpts opts
|
||||
fileexists <- doesFileExist f
|
||||
let creating = not fileexists && cmdname == "add"
|
||||
journalFilePathFromOpts opts >>= readJournalFile Nothing >>= either error runcmd
|
||||
where
|
||||
costify = (if CostBasis `elem` opts then journalConvertAmountsToCost else id)
|
||||
runcmd = cmd opts args . costify
|
||||
if creating
|
||||
then runcmd nulljournal
|
||||
else readJournalFile Nothing f >>= either error runcmd
|
||||
|
||||
-- | Get a journal from the given string and options, or throw an error.
|
||||
readJournalWithOpts :: [Opt] -> String -> IO Journal
|
||||
readJournalWithOpts opts s = do
|
||||
j <- readJournal Nothing s >>= either error return
|
||||
let cost = CostBasis `elem` opts
|
||||
return $ (if cost then journalConvertAmountsToCost else id) j
|
||||
where cost = CostBasis `elem` opts
|
||||
|
||||
-- | Re-read a journal from its data file, or return an error string.
|
||||
journalReload :: Journal -> IO (Either String Journal)
|
||||
|
||||
@ -16,16 +16,18 @@ module Hledger.Read (
|
||||
myTimelog,
|
||||
)
|
||||
where
|
||||
import Hledger.Data.Dates (getCurrentDay)
|
||||
import Hledger.Data.Types (Journal(..))
|
||||
import Hledger.Data.Utils
|
||||
import Hledger.Read.Common
|
||||
import Hledger.Read.Journal as Journal
|
||||
import Hledger.Read.Timelog as Timelog
|
||||
import Hledger.Cli.Version (version)
|
||||
|
||||
import Control.Monad.Error
|
||||
import Data.Either (partitionEithers)
|
||||
import Safe (headDef)
|
||||
import System.Directory (getHomeDirectory)
|
||||
import System.Directory (doesFileExist, getHomeDirectory)
|
||||
import System.Environment (getEnv)
|
||||
import System.FilePath ((</>))
|
||||
import System.IO (IOMode(..), withFile, hGetContents, stderr)
|
||||
@ -82,10 +84,28 @@ journalFromPathAndString format fp s = do
|
||||
fmt fs = intercalate ", " (init fs) ++ " or " ++ last fs ++ " "
|
||||
|
||||
-- | Read a journal from this file, using the specified data format or
|
||||
-- trying all known formats, or give an error string.
|
||||
-- trying all known formats, or give an error string; also create the file
|
||||
-- if it doesn't exist.
|
||||
readJournalFile :: Maybe String -> FilePath -> IO (Either String Journal)
|
||||
readJournalFile format "-" = getContents >>= journalFromPathAndString format "(stdin)"
|
||||
readJournalFile format f = withFile f ReadMode $ \h -> hGetContents h >>= journalFromPathAndString format f
|
||||
readJournalFile format f = do
|
||||
ensureJournalFile f
|
||||
withFile f ReadMode $ \h -> hGetContents h >>= journalFromPathAndString format f
|
||||
|
||||
-- | Ensure there is a journal at the given file path, creating an empty one if needed.
|
||||
ensureJournalFile :: FilePath -> IO ()
|
||||
ensureJournalFile f = do
|
||||
exists <- doesFileExist f
|
||||
when (not exists) $ do
|
||||
printf "No journal file at %s, creating...\n" f
|
||||
printf "Edit this file or use hledger add or hledger web to add transactions.\n"
|
||||
emptyJournal >>= writeFile f
|
||||
|
||||
-- | Give the content for a new auto-created journal file.
|
||||
emptyJournal :: IO String
|
||||
emptyJournal = do
|
||||
d <- getCurrentDay
|
||||
return $ printf "; journal created by hledger %s on %s\n; see http://hledger.org/MANUAL.html#file-format\n\n" version (show d)
|
||||
|
||||
-- | Read a Journal from this string, using the specified data format or
|
||||
-- trying all known formats, or give an error string.
|
||||
|
||||
Loading…
Reference in New Issue
Block a user