--alias command-line option
This commit is contained in:
		
							parent
							
								
									30b7448f45
								
							
						
					
					
						commit
						957c349780
					
				
							
								
								
									
										18
									
								
								MANUAL.md
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								MANUAL.md
									
									
									
									
									
								
							| @ -439,7 +439,8 @@ Included files are also affected, eg: | ||||
| ### Account aliases | ||||
| 
 | ||||
| You can define account aliases to rewrite certain account names (and their subaccounts). | ||||
| The format is `alias ORIGACCT = ALIAS`. Use `end aliases` to forget all previously defined aliases. | ||||
| The format is `alias ORIG = ALIAS`, where ORIG and ALIAS are full account names. | ||||
| To forget all aliases defined to this point, use `end aliases`. | ||||
| 
 | ||||
| Here's an example: say a sole proprietor has a personal.journal: | ||||
| 
 | ||||
| @ -475,6 +476,21 @@ giving: | ||||
|         expenses:office supplies            $1 | ||||
|         assets:business checking           $-1 | ||||
| 
 | ||||
| You can also specify aliases on the command line. This could be useful to | ||||
| rewrite account names when sharing a report with someone else, such as | ||||
| your accountant: | ||||
| 
 | ||||
|     $ hledger --alias 'my earning=income:business' | ||||
| 
 | ||||
| Command-line alias options are applied after any alias directives in the | ||||
| journal.  At most one alias directive and one alias option will be applied | ||||
| to each account name. | ||||
| 
 | ||||
| Aliases tend to be a little more reliable than post-processing with sed or | ||||
| similar, as they know about account name syntax, posting type indicators | ||||
| etc. Note aliases only change the displayed names, not the account | ||||
| hierarchy - aliasing two accounts to the same name does not merge them | ||||
| into one account. | ||||
| 
 | ||||
| ## Core commands | ||||
| 
 | ||||
|  | ||||
| @ -242,6 +242,13 @@ journalSelectingDate ActualDate j = j | ||||
| journalSelectingDate EffectiveDate j = | ||||
|     j{jtxns=map (journalTransactionWithDate EffectiveDate) $ jtxns j} | ||||
| 
 | ||||
| -- | Apply additional account aliases (eg from the command-line) to all postings in a journal. | ||||
| journalApplyAliases :: [(AccountName,AccountName)] -> Journal -> Journal | ||||
| journalApplyAliases aliases j@Journal{jtxns=ts} = j{jtxns=map fixtransaction ts} | ||||
|     where | ||||
|       fixtransaction t@Transaction{tpostings=ps} = t{tpostings=map fixposting ps} | ||||
|       fixposting p@Posting{paccount=a} = p{paccount=accountNameApplyAliases aliases a} | ||||
| 
 | ||||
| -- | Do post-parse processing on a journal, to make it ready for use. | ||||
| journalFinalise :: ClockTime -> LocalTime -> FilePath -> String -> JournalContext -> Journal -> Either String Journal | ||||
| journalFinalise tclock tlocal path txt ctx j@Journal{files=fs} = | ||||
|  | ||||
| @ -99,7 +99,7 @@ postingsDateSpan [] = DateSpan Nothing Nothing | ||||
| postingsDateSpan ps = DateSpan (Just $ postingDate $ head ps') (Just $ addDays 1 $ postingDate $ last ps') | ||||
|     where ps' = sortBy (comparing postingDate) ps | ||||
| 
 | ||||
| -- balanced/non-balanced posting indicators | ||||
| -- AccountName stuff that depends on PostingType | ||||
| 
 | ||||
| accountNamePostingType :: AccountName -> PostingType | ||||
| accountNamePostingType a | ||||
| @ -131,6 +131,15 @@ concatAccountNames :: [AccountName] -> AccountName | ||||
| concatAccountNames as = accountNameWithPostingType t $ intercalate ":" $ map accountNameWithoutPostingType as | ||||
|     where t = headDef RegularPosting $ filter (/= RegularPosting) $ map accountNamePostingType as | ||||
| 
 | ||||
| -- | Rewrite an account name using the first applicable alias from the given list, if any. | ||||
| accountNameApplyAliases :: [(AccountName,AccountName)] -> AccountName -> AccountName | ||||
| accountNameApplyAliases aliases a = withorigtype | ||||
|     where | ||||
|       (a',t) = (accountNameWithoutPostingType a, accountNamePostingType a) | ||||
|       firstmatchingalias = headDef Nothing $ map Just $ filter (\(orig,_) -> orig == a' || orig `isAccountNamePrefixOf` a') aliases | ||||
|       rewritten = maybe a' (\(orig,alias) -> alias++drop (length orig) a') firstmatchingalias | ||||
|       withorigtype = accountNameWithPostingType t rewritten | ||||
| 
 | ||||
| tests_Hledger_Data_Posting = TestList [ | ||||
| 
 | ||||
|   "accountNamePostingType" ~: do | ||||
|  | ||||
| @ -482,12 +482,7 @@ modifiedaccountname = do | ||||
|   prefix <- getParentAccount | ||||
|   let prefixed = prefix `joinAccountNames` a | ||||
|   aliases <- getAccountAliases | ||||
|   let t = accountNamePostingType prefixed | ||||
|       a' = accountNameWithoutPostingType prefixed | ||||
|       match = headDef Nothing $ map Just $ filter (\(orig,_) -> orig == a' || orig `isAccountNamePrefixOf` a') aliases | ||||
|       rewritten = maybe a' (\(orig,alias) -> alias++drop (length orig) a') match | ||||
|       withtype = accountNameWithPostingType t rewritten | ||||
|   return withtype | ||||
|   return $ accountNameApplyAliases aliases prefixed | ||||
| 
 | ||||
| -- | Parse an account name. Account names may have single spaces inside | ||||
| -- them, and are terminated by two or more spaces. They should have one or | ||||
|  | ||||
| @ -62,6 +62,7 @@ options_cli :: [OptDescr Opt] | ||||
| options_cli = [ | ||||
|   Option "f" ["file"]         (ReqArg File "FILE")   "use a different journal/timelog file; - means stdin" | ||||
|  ,Option ""  ["no-new-accounts"] (NoArg NoNewAccts)  "don't allow to create new accounts" | ||||
|  ,Option ""  ["alias"]        (ReqArg Alias "ACCT=ALIAS")  "display ACCT's name as ALIAS instead" | ||||
|  ,Option "b" ["begin"]        (ReqArg Begin "DATE")  "report on transactions on or after this date" | ||||
|  ,Option "e" ["end"]          (ReqArg End "DATE")    "report on transactions before this date" | ||||
|  ,Option "p" ["period"]       (ReqArg Period "EXPR") ("report on transactions during the specified period\n" ++ | ||||
| @ -96,6 +97,7 @@ options_cli = [ | ||||
| data Opt =  | ||||
|     File          {value::String} | ||||
|     | NoNewAccts | ||||
|     | Alias       {value::String} | ||||
|     | Begin       {value::String} | ||||
|     | End         {value::String} | ||||
|     | Period      {value::String} | ||||
| @ -306,6 +308,18 @@ journalFilePathFromOpts opts = do | ||||
|   f <- if istimequery then myTimelogPath else myJournalPath | ||||
|   return $ last $ f : optValuesForConstructor File opts | ||||
| 
 | ||||
| aliasesFromOpts :: [Opt] -> [(AccountName,AccountName)] | ||||
| aliasesFromOpts opts = map parseAlias $ optValuesForConstructor Alias opts | ||||
|     where | ||||
|       -- similar to ledgerAlias | ||||
|       parseAlias :: String -> (AccountName,AccountName) | ||||
|       parseAlias s = (accountNameWithoutPostingType $ strip orig | ||||
|                      ,accountNameWithoutPostingType $ strip alias') | ||||
|           where | ||||
|             (orig, alias) = break (=='=') s | ||||
|             alias' = case alias of ('=':rest) -> rest | ||||
|                                    _ -> orig | ||||
| 
 | ||||
| -- | Gather filter pattern arguments into a list of account patterns and a | ||||
| -- list of description patterns. We interpret pattern arguments as | ||||
| -- follows: those prefixed with "desc:" are description patterns, all | ||||
|  | ||||
| @ -38,7 +38,7 @@ import System.Time (ClockTime, getClockTime, diffClockTimes, TimeDiff(TimeDiff)) | ||||
| import Test.HUnit | ||||
| import Text.Printf | ||||
| 
 | ||||
| import Hledger.Cli.Options (Opt(..),journalFilePathFromOpts,whichDateFromOpts) | ||||
| import Hledger.Cli.Options | ||||
| import Hledger.Data | ||||
| import Hledger.Read | ||||
| import Hledger.Utils | ||||
| @ -51,7 +51,8 @@ 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. | ||||
|   journalFilePathFromOpts opts >>= readJournalFile Nothing >>= either error' (cmd opts args) | ||||
|   journalFilePathFromOpts opts >>= readJournalFile Nothing >>= | ||||
|     either error' (cmd opts args . journalApplyAliases (aliasesFromOpts opts)) | ||||
| 
 | ||||
| -- -- | Get a journal from the given string and options, or throw an error. | ||||
| -- readJournalWithOpts :: [Opt] -> String -> IO Journal | ||||
|  | ||||
							
								
								
									
										49
									
								
								tests/aliases.test
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								tests/aliases.test
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,49 @@ | ||||
| # alias-related tests | ||||
| 
 | ||||
| # 1. command-line --alias option.  Note multiple applicable aliases, but | ||||
| # only one is applied per account name.  Spaces are allowed if quoted. | ||||
| bin/hledger -f- print --alias 'a a=A' --alias b=B | ||||
| <<< | ||||
| 2011/01/01 | ||||
|     a a  1 | ||||
|     c | ||||
| 
 | ||||
| >>> | ||||
| 2011/01/01 | ||||
|     A             1 | ||||
|     c            -1 | ||||
| 
 | ||||
| >>>=0 | ||||
| 
 | ||||
| # 2. alias directive, and an account with unbalanced posting indicators. | ||||
| bin/hledger -f- print | ||||
| <<< | ||||
| alias b=B | ||||
| 
 | ||||
| 2011/01/01 | ||||
|     (b)  1 | ||||
| 
 | ||||
| >>> | ||||
| 2011/01/01 | ||||
|     (B)             1 | ||||
| 
 | ||||
| >>>=0 | ||||
| 
 | ||||
| # 3. --alias options run after alias directives. Subaccounts are also | ||||
| # matched and rewritten. Accounts with an internal part matching the alias | ||||
| # are ignored. | ||||
| bin/hledger -f- print --alias a=A --alias B=C | ||||
| <<< | ||||
| alias a=B | ||||
| 
 | ||||
| 2011/01/01 | ||||
|     [a:x]    1 | ||||
|     [x:a:x] | ||||
| 
 | ||||
| >>> | ||||
| 2011/01/01 | ||||
|     [C:x]             1 | ||||
|     [x:a:x]            -1 | ||||
| 
 | ||||
| >>>2 | ||||
| >>>=0 | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user