csv: create default rules file only if CSV reader succeeds

This commit is contained in:
Simon Michael 2016-11-22 13:59:31 -08:00
parent 283cda9303
commit a1411768e5

View File

@ -99,14 +99,12 @@ readJournalFromCsv mrulesfile csvfile csvdata =
-- parse rules -- parse rules
let rulesfile = fromMaybe (rulesFileFor csvfile) mrulesfile let rulesfile = fromMaybe (rulesFileFor csvfile) mrulesfile
created <- ensureRulesFileExists rulesfile rulesfileexists <- doesFileExist rulesfile
if created when rulesfileexists $ hPrintf stderr "using conversion rules file %s\n" rulesfile
then hPrintf stderr "creating default conversion rules file %s, edit this file for better results\n" rulesfile rules <-
else hPrintf stderr "using conversion rules file %s\n" rulesfile if rulesfileexists
rules_ <- liftIO $ runExceptT $ parseRulesFile rulesfile then liftIO (runExceptT $ parseRulesFile rulesfile) >>= either throwerr return
let rules = case rules_ of else return defaultRules
Right (t::CsvRules) -> t
Left err -> throwerr err
dbg2IO "rules" rules dbg2IO "rules" rules
-- apply skip directive -- apply skip directive
@ -143,6 +141,11 @@ readJournalFromCsv mrulesfile csvfile csvdata =
-- so that same-day txns' original order is preserved -- so that same-day txns' original order is preserved
txns' | length txns > 1 && tdate (head txns) > tdate (last txns) = reverse txns txns' | length txns > 1 && tdate (head txns) > tdate (last txns) = reverse txns
| otherwise = txns | otherwise = txns
when (not rulesfileexists) $ do
hPrintf stderr "created default conversion rules file %s, edit this for better results\n" rulesfile
writeFile rulesfile $ T.unpack $ defaultRulesText rulesfile
return $ Right nulljournal{jtxns=sortBy (comparing tdate) txns'} return $ Right nulljournal{jtxns=sortBy (comparing tdate) txns'}
parseCsv :: FilePath -> String -> IO (Either Parsec.ParseError CSV) parseCsv :: FilePath -> String -> IO (Either Parsec.ParseError CSV)
@ -192,22 +195,9 @@ rulesFileFor = (++ ".rules")
csvFileFor :: FilePath -> FilePath csvFileFor :: FilePath -> FilePath
csvFileFor = reverse . drop 6 . reverse csvFileFor = reverse . drop 6 . reverse
-- | Ensure there is a conversion rules file at the given path, creating a defaultRulesText :: FilePath -> Text
-- default one if needed and returning True in this case. defaultRulesText csvfile = T.pack $ unlines
ensureRulesFileExists :: FilePath -> IO Bool ["# hledger csv conversion rules for " ++ csvFileFor (takeFileName csvfile)
ensureRulesFileExists f = do
exists <- doesFileExist f
if exists
then return False
else do
-- note Hledger.Utils.UTF8.* do no line ending conversion on windows,
-- we currently require unix line endings on all platforms.
writeFile f $ newRulesFileContent f
return True
newRulesFileContent :: FilePath -> String
newRulesFileContent f = unlines
["# hledger csv conversion rules for " ++ csvFileFor (takeFileName f)
,"# cf http://hledger.org/manual#csv-files" ,"# cf http://hledger.org/manual#csv-files"
,"" ,""
,"account1 assets:bank:checking" ,"account1 assets:bank:checking"
@ -229,6 +219,12 @@ newRulesFileContent f = unlines
," account2 assets:bank:savings\n" ," account2 assets:bank:savings\n"
] ]
defaultRules :: CsvRules
defaultRules =
either
(error' "Could not parse the default CSV rules, this should not happen")
id
$ parseCsvRules "" $ defaultRulesText ""
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
-- Conversion rules parsing -- Conversion rules parsing