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 | ||||
|   j <- readJournal Nothing s >>= either error return | ||||
|   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