more convenient timelog querying when invoked as "hours"
This commit is contained in:
parent
f733a3de80
commit
a26a56eafe
61
Options.hs
61
Options.hs
@ -3,7 +3,9 @@ where
|
||||
import System
|
||||
import System.Console.GetOpt
|
||||
import System.Directory
|
||||
import System.Environment
|
||||
import Text.Printf
|
||||
import Data.Char (toLower)
|
||||
import Ledger.Parse
|
||||
import Ledger.Utils
|
||||
import Ledger.Types
|
||||
@ -12,9 +14,13 @@ import Ledger.Dates
|
||||
|
||||
versionno = "0.3"
|
||||
version = printf "hledger version %s \n" versionno :: String
|
||||
defaultfile = "~/.ledger"
|
||||
fileenvvar = "LEDGER"
|
||||
usagehdr = "Usage: hledger [OPTS] COMMAND [ACCTPATTERNS] [-- DESCPATTERNS]\n" ++
|
||||
ledgerdefault = "~/.ledger"
|
||||
ledgerenvvar = "LEDGER"
|
||||
timelogdefault = "~/.timelog"
|
||||
timelogenvvar = "TIMELOG"
|
||||
timeprogname = "hours"
|
||||
usagehdr = "Usage: hledger [OPTION] COMMAND [ACCTPATTERNS] [-- DESCPATTERNS]\n" ++
|
||||
"or: hours [OPTIONS] [PERIOD [COMMAND]]\n" ++
|
||||
"\n" ++
|
||||
"Options (before command, unless using --options-anywhere):"
|
||||
usageftr = "\n" ++
|
||||
@ -27,7 +33,7 @@ usageftr = "\n" ++
|
||||
"Account and description patterns are regular expressions which filter by\n" ++
|
||||
"account name and entry description. Prefix a pattern with - to negate it,\n" ++
|
||||
"and separate account and description patterns with --.\n" ++
|
||||
"(With --options-anywhere, use ^ and ^^.)\n" ++
|
||||
"(With --options-anywhere, use ^ and ^^. \"hours\" implies --options-anywhere.)\n" ++
|
||||
"\n" ++
|
||||
"Also: hledger [-v] test [TESTPATTERNS] to run self-tests.\n" ++
|
||||
"\n"
|
||||
@ -61,7 +67,7 @@ options = [
|
||||
]
|
||||
where
|
||||
filehelp = printf "ledger file; - means use standard input. Defaults\nto the %s environment variable or %s"
|
||||
fileenvvar defaultfile
|
||||
ledgerenvvar ledgerdefault
|
||||
|
||||
-- | An option value from a command-line flag.
|
||||
data Opt =
|
||||
@ -97,18 +103,33 @@ optValuesForConstructor f opts = concatMap get opts
|
||||
optValuesForConstructors fs opts = concatMap get opts
|
||||
where get o = if any (\f -> f v == o) fs then [v] else [] where v = value o
|
||||
|
||||
-- | Parse the command-line arguments into ledger options, ledger command
|
||||
-- name, and ledger command arguments. Also any dates in the options are
|
||||
-- converted to full YYYY/MM/DD format, while we are in the IO monad
|
||||
-- and can get the current time.
|
||||
-- | Parse the command-line arguments into options, command name, and
|
||||
-- command arguments. Any dates in the options are converted to full
|
||||
-- YYYY/MM/DD format, while we are in the IO monad and can get the current
|
||||
-- time. Arguments are parsed differently if the program was invoked as
|
||||
-- "hours".
|
||||
parseArguments :: IO ([Opt], String, [String])
|
||||
parseArguments = do
|
||||
args <- getArgs
|
||||
let order = if "--options-anywhere" `elem` args then Permute else RequireOrder
|
||||
case (getOpt order options args) of
|
||||
(opts,cmd:args,[]) -> do {opts' <- fixOptDates opts; return (opts',cmd,args)}
|
||||
(opts,[],[]) -> do {opts' <- fixOptDates opts; return (opts',[],[])}
|
||||
(opts,_,errs) -> ioError (userError (concat errs ++ usage))
|
||||
istimequery <- usingTimeProgramName
|
||||
let order = if "--options-anywhere" `elem` args || istimequery
|
||||
then Permute
|
||||
else RequireOrder
|
||||
let (os,as,es) = getOpt order options args
|
||||
os' <- fixOptDates os
|
||||
case istimequery of
|
||||
False ->
|
||||
case (os,as,es) of
|
||||
(opts,cmd:args,[]) -> return (os',cmd,args)
|
||||
(opts,[],[]) -> return (os',"",[])
|
||||
(opts,_,errs) -> ioError (userError (concat errs ++ usage))
|
||||
True ->
|
||||
case (os,as,es) of
|
||||
(opts,p:cmd:args,[]) -> return (os' ++ [Period p],cmd,args)
|
||||
(opts,p:args,[]) -> return ([Period p,SubTotal] ++ os',"balance",args)
|
||||
(opts,[],[]) -> return ([Period "today",SubTotal] ++ os',"balance",[])
|
||||
(opts,_,errs) -> ioError (userError (concat errs ++ usage))
|
||||
|
||||
|
||||
-- | Convert any fuzzy dates within these option values to explicit ones,
|
||||
-- based on today's date.
|
||||
@ -170,10 +191,20 @@ displayFromOpts opts = listtomaybe $ optValuesForConstructor Display opts
|
||||
listtomaybe [] = Nothing
|
||||
listtomaybe vs = Just $ last vs
|
||||
|
||||
-- | Was the program invoked via the \"hours\" alias ?
|
||||
usingTimeProgramName :: IO Bool
|
||||
usingTimeProgramName = do
|
||||
progname <- getProgName
|
||||
return $ map toLower progname == timeprogname
|
||||
|
||||
-- | Get the ledger file path from options, an environment variable, or a default
|
||||
ledgerFilePathFromOpts :: [Opt] -> IO String
|
||||
ledgerFilePathFromOpts opts = do
|
||||
envordefault <- getEnv fileenvvar `catch` \_ -> return defaultfile
|
||||
istimequery <- usingTimeProgramName
|
||||
let (e,d) = if istimequery
|
||||
then (timelogenvvar,timelogdefault)
|
||||
else (ledgerenvvar,ledgerdefault)
|
||||
envordefault <- getEnv e `catch` \_ -> return d
|
||||
paths <- mapM tildeExpand $ [envordefault] ++ optValuesForConstructor File opts
|
||||
return $ last paths
|
||||
|
||||
|
||||
31
README
31
README
@ -37,9 +37,12 @@ To get the latest development code do::
|
||||
darcs get http://joyful.com/repos/hledger
|
||||
|
||||
|
||||
Examples
|
||||
--------
|
||||
Here are some commands to try::
|
||||
Usage
|
||||
-----
|
||||
hledger looks for your ledger file at ~/.ledger by default. To use a
|
||||
different file, specify it with the LEDGER environment variable or -f
|
||||
option (which may be - for standard input). Here are some commands to
|
||||
try::
|
||||
|
||||
hledger --help
|
||||
hledger -f sample.ledger balance
|
||||
@ -50,9 +53,27 @@ Here are some commands to try::
|
||||
hledger reg -- shop
|
||||
hledger ui
|
||||
|
||||
hledger looks for your ledger file at ~/.ledger by default. To use a different file,
|
||||
specify it with -f or the LEDGER environment variable.
|
||||
|
||||
Time reporting
|
||||
--------------
|
||||
hledger can parse a timelog file in timeclock.el's format, treating time
|
||||
categories as accounts. If hledger is invoked by the "hours" alias it
|
||||
looks for your timelog, and parses arguments slightly differently for
|
||||
convenient querying:
|
||||
|
||||
hours [OPTIONS] [PERIOD [COMMAND]]
|
||||
|
||||
PERIOD and COMMAND default to "today" and "balance --subtotal"
|
||||
respectively, and --options-anywhere is assumed. The timelog is found in
|
||||
the same way as your ledger: ~/.timelog or the file specified by $TIMELOG
|
||||
or an -f option. Examples:
|
||||
|
||||
hours # today's balances
|
||||
hours today # the same
|
||||
hours 'this week' # so far this week
|
||||
hours week # the same
|
||||
hours lastmonth # last month, the space is optional
|
||||
hours 'monthly in 2008' reg --depth 1 # monthly register, top-level only
|
||||
|
||||
Features
|
||||
--------
|
||||
|
||||
Loading…
Reference in New Issue
Block a user