Merge branch 'master' into installer
This commit is contained in:
commit
efc75db8d8
@ -19,6 +19,7 @@ module Hledger.Query (
|
||||
-- * accessors
|
||||
queryIsNull,
|
||||
queryIsAcct,
|
||||
queryIsAmt,
|
||||
queryIsDepth,
|
||||
queryIsDate,
|
||||
queryIsDate2,
|
||||
@ -41,6 +42,8 @@ module Hledger.Query (
|
||||
matchesAccount,
|
||||
matchesMixedAmount,
|
||||
matchesAmount,
|
||||
matchesCommodity,
|
||||
matchesMarketPrice,
|
||||
words'',
|
||||
-- * tests
|
||||
tests_Hledger_Query
|
||||
@ -481,6 +484,10 @@ queryIsAcct :: Query -> Bool
|
||||
queryIsAcct (Acct _) = True
|
||||
queryIsAcct _ = False
|
||||
|
||||
queryIsAmt :: Query -> Bool
|
||||
queryIsAmt (Amt _ _) = True
|
||||
queryIsAmt _ = False
|
||||
|
||||
queryIsSym :: Query -> Bool
|
||||
queryIsSym (Sym _) = True
|
||||
queryIsSym _ = False
|
||||
@ -530,33 +537,27 @@ queryEndDate _ _ = Nothing
|
||||
queryTermDateSpan (Date span) = Just span
|
||||
queryTermDateSpan _ = Nothing
|
||||
|
||||
-- | What date span (or secondary date span) does this query specify ?
|
||||
-- For OR expressions, use the widest possible span. NOT is ignored.
|
||||
-- | What date span (or with a true argument, what secondary date span) does this query specify ?
|
||||
-- OR clauses specifying multiple spans return their union (the span enclosing all of them).
|
||||
-- AND clauses specifying multiple spans return their intersection.
|
||||
-- NOT clauses are ignored.
|
||||
queryDateSpan :: Bool -> Query -> DateSpan
|
||||
queryDateSpan secondary q = spansUnion $ queryDateSpans secondary q
|
||||
queryDateSpan secondary (Or qs) = spansUnion $ map (queryDateSpan secondary) qs
|
||||
queryDateSpan secondary (And qs) = spansIntersect $ map (queryDateSpan secondary) qs
|
||||
queryDateSpan False (Date span) = span
|
||||
queryDateSpan True (Date2 span) = span
|
||||
queryDateSpan _ _ = nulldatespan
|
||||
|
||||
-- | Extract all date (or secondary date) spans specified in this query.
|
||||
-- NOT is ignored.
|
||||
queryDateSpans :: Bool -> Query -> [DateSpan]
|
||||
queryDateSpans secondary (Or qs) = concatMap (queryDateSpans secondary) qs
|
||||
queryDateSpans secondary (And qs) = concatMap (queryDateSpans secondary) qs
|
||||
queryDateSpans False (Date span) = [span]
|
||||
queryDateSpans True (Date2 span) = [span]
|
||||
queryDateSpans _ _ = []
|
||||
|
||||
-- | What date span (or secondary date span) does this query specify ?
|
||||
-- For OR expressions, use the widest possible span. NOT is ignored.
|
||||
-- | What date span does this query specify, treating primary and secondary dates as equivalent ?
|
||||
-- OR clauses specifying multiple spans return their union (the span enclosing all of them).
|
||||
-- AND clauses specifying multiple spans return their intersection.
|
||||
-- NOT clauses are ignored.
|
||||
queryDateSpan' :: Query -> DateSpan
|
||||
queryDateSpan' q = spansUnion $ queryDateSpans' q
|
||||
|
||||
-- | Extract all date (or secondary date) spans specified in this query.
|
||||
-- NOT is ignored.
|
||||
queryDateSpans' :: Query -> [DateSpan]
|
||||
queryDateSpans' (Or qs) = concatMap queryDateSpans' qs
|
||||
queryDateSpans' (And qs) = concatMap queryDateSpans' qs
|
||||
queryDateSpans' (Date span) = [span]
|
||||
queryDateSpans' (Date2 span) = [span]
|
||||
queryDateSpans' _ = []
|
||||
queryDateSpan' (Or qs) = spansUnion $ map queryDateSpan' qs
|
||||
queryDateSpan' (And qs) = spansIntersect $ map queryDateSpan' qs
|
||||
queryDateSpan' (Date span) = span
|
||||
queryDateSpan' (Date2 span) = span
|
||||
queryDateSpan' _ = nulldatespan
|
||||
|
||||
-- | What is the earliest of these dates, where Nothing is latest ?
|
||||
earliestMaybeDate :: [Maybe Day] -> Maybe Day
|
||||
@ -641,6 +642,10 @@ matchesMixedAmount :: Query -> MixedAmount -> Bool
|
||||
matchesMixedAmount q (Mixed []) = q `matchesAmount` nullamt
|
||||
matchesMixedAmount q (Mixed as) = any (q `matchesAmount`) as
|
||||
|
||||
matchesCommodity :: Query -> CommoditySymbol -> Bool
|
||||
matchesCommodity (Sym r) s = regexMatchesCI ("^" ++ r ++ "$") (T.unpack s)
|
||||
matchesCommodity _ _ = True
|
||||
|
||||
-- | Does the match expression match this (simple) amount ?
|
||||
matchesAmount :: Query -> Amount -> Bool
|
||||
matchesAmount (Not q) a = not $ q `matchesAmount` a
|
||||
@ -650,7 +655,7 @@ matchesAmount (Or qs) a = any (`matchesAmount` a) qs
|
||||
matchesAmount (And qs) a = all (`matchesAmount` a) qs
|
||||
--
|
||||
matchesAmount (Amt ord n) a = compareAmount ord n a
|
||||
matchesAmount (Sym r) a = regexMatchesCI ("^" ++ r ++ "$") $ T.unpack $ acommodity a
|
||||
matchesAmount (Sym r) a = matchesCommodity (Sym r) (acommodity a)
|
||||
--
|
||||
matchesAmount _ _ = True
|
||||
|
||||
@ -694,7 +699,7 @@ matchesPosting q@(Amt _ _) Posting{pamount=amt} = q `matchesMixedAmount` amt
|
||||
-- matchesPosting (Empty False) Posting{pamount=a} = True
|
||||
-- matchesPosting (Empty True) Posting{pamount=a} = isZeroMixedAmount a
|
||||
matchesPosting (Empty _) _ = True
|
||||
matchesPosting (Sym r) Posting{pamount=Mixed as} = any (regexMatchesCI $ "^" ++ r ++ "$") $ map (T.unpack . acommodity) as
|
||||
matchesPosting (Sym r) Posting{pamount=Mixed as} = any (matchesCommodity (Sym r)) $ map acommodity as
|
||||
matchesPosting (Tag n v) p = case (n, v) of
|
||||
("payee", Just v) -> maybe False (regexMatchesCI v . T.unpack . transactionPayee) $ ptransaction p
|
||||
("note", Just v) -> maybe False (regexMatchesCI v . T.unpack . transactionNote) $ ptransaction p
|
||||
@ -777,6 +782,18 @@ matchesTags namepat valuepat = not . null . filter (match namepat valuepat)
|
||||
match npat Nothing (n,_) = regexMatchesCI npat (T.unpack n) -- XXX
|
||||
match npat (Just vpat) (n,v) = regexMatchesCI npat (T.unpack n) && regexMatchesCI vpat (T.unpack v)
|
||||
|
||||
-- | Does the query match this market price ?
|
||||
matchesMarketPrice :: Query -> MarketPrice -> Bool
|
||||
matchesMarketPrice (None) _ = False
|
||||
matchesMarketPrice (Not q) p = not $ matchesMarketPrice q p
|
||||
matchesMarketPrice (Or qs) p = any (`matchesMarketPrice` p) qs
|
||||
matchesMarketPrice (And qs) p = all (`matchesMarketPrice` p) qs
|
||||
matchesMarketPrice q@(Amt _ _) p = matchesAmount q (mpamount p)
|
||||
matchesMarketPrice q@(Sym _) p = matchesCommodity q (mpcommodity p)
|
||||
matchesMarketPrice (Date span) p = spanContainsDate span (mpdate p)
|
||||
matchesMarketPrice _ _ = True
|
||||
|
||||
|
||||
-- tests
|
||||
|
||||
tests_Hledger_Query :: Test
|
||||
|
||||
@ -17,28 +17,34 @@ import System.Console.CmdArgs.Explicit
|
||||
|
||||
pricesmode = hledgerCommandMode
|
||||
[here| prices
|
||||
Print all market prices from the journal.
|
||||
Print market price directives from the journal.
|
||||
With --costs, also print synthetic market prices based on transaction prices.
|
||||
With --inverted-costs, also print inverse prices based on transaction prices.
|
||||
Prices (and postings providing prices) can be filtered by a query.
|
||||
|]
|
||||
[flagNone ["costs"] (setboolopt "costs") "print transaction prices from postings"
|
||||
,flagNone ["inverted-costs"] (setboolopt "inverted-costs") "print transaction inverted prices from postings also"]
|
||||
[generalflagsgroup1]
|
||||
[]
|
||||
([], Nothing)
|
||||
([], Just $ argsFlag "[QUERY]")
|
||||
|
||||
prices opts j = do
|
||||
-- XXX the original hledger-prices script always ignored assertions
|
||||
let cprices = concatMap postingCosts . allPostings $ j
|
||||
icprices = concatMap postingCosts . mapAmount invertPrice . allPostings $ j
|
||||
printPrices = mapM_ (putStrLn . showPrice)
|
||||
forBoolOpt opt | boolopt opt $ rawopts_ opts = id
|
||||
prices opts j = do
|
||||
d <- getCurrentDay
|
||||
let
|
||||
q = queryFromOpts d (reportopts_ opts)
|
||||
ps = filter (matchesPosting q) $ allPostings j
|
||||
mprices = jmarketprices j
|
||||
cprices = concatMap postingCosts ps
|
||||
icprices = concatMap postingCosts . mapAmount invertPrice $ ps
|
||||
allprices = mprices ++ ifBoolOpt "costs" cprices ++ ifBoolOpt "inverted-costs" icprices
|
||||
mapM_ (putStrLn . showPrice) $
|
||||
sortOn mpdate $
|
||||
filter (matchesMarketPrice q) $
|
||||
allprices
|
||||
where
|
||||
ifBoolOpt opt | boolopt opt $ rawopts_ opts = id
|
||||
| otherwise = const []
|
||||
allPrices = sortOn mpdate . concat $
|
||||
[ jmarketprices j
|
||||
, forBoolOpt "costs" cprices
|
||||
, forBoolOpt "inverted-costs" icprices
|
||||
]
|
||||
|
||||
printPrices allPrices
|
||||
|
||||
showPrice :: MarketPrice -> String
|
||||
showPrice mp = unwords ["P", show $ mpdate mp, T.unpack . quoteCommoditySymbolIfNeeded $ mpcommodity mp, showAmountWithZeroCommodity $ mpamount mp]
|
||||
|
||||
@ -2426,7 +2426,12 @@ This command also supports output destination and output format
|
||||
selection.
|
||||
.SS prices
|
||||
.PP
|
||||
Print all market prices from the journal.
|
||||
Print market price directives from the journal.
|
||||
With \[en]costs, also print synthetic market prices based on transaction
|
||||
prices.
|
||||
With \[en]inverted\-costs, also print inverse prices based on
|
||||
transaction prices.
|
||||
Prices (and postings providing prices) can be filtered by a query.
|
||||
.SS print
|
||||
.PP
|
||||
Show transactions from the journal.
|
||||
|
||||
@ -1921,7 +1921,10 @@ File: hledger.info, Node: prices, Next: print, Prev: incomestatement, Up: CO
|
||||
4.14 prices
|
||||
===========
|
||||
|
||||
Print all market prices from the journal.
|
||||
Print market price directives from the journal. With -costs, also print
|
||||
synthetic market prices based on transaction prices. With
|
||||
-inverted-costs, also print inverse prices based on transaction prices.
|
||||
Prices (and postings providing prices) can be filtered by a query.
|
||||
|
||||
|
||||
File: hledger.info, Node: print, Next: print-unique, Prev: prices, Up: COMMANDS
|
||||
@ -2520,51 +2523,51 @@ Node: incomestatement61310
|
||||
Ref: #incomestatement61444
|
||||
Node: prices63848
|
||||
Ref: #prices63963
|
||||
Node: print64006
|
||||
Ref: #print64116
|
||||
Node: print-unique69010
|
||||
Ref: #print-unique69136
|
||||
Node: register69204
|
||||
Ref: #register69331
|
||||
Node: Custom register output73832
|
||||
Ref: #custom-register-output73961
|
||||
Node: register-match75191
|
||||
Ref: #register-match75325
|
||||
Node: rewrite75508
|
||||
Ref: #rewrite75625
|
||||
Node: stats75694
|
||||
Ref: #stats75797
|
||||
Node: tags76667
|
||||
Ref: #tags76765
|
||||
Node: test77001
|
||||
Ref: #test77085
|
||||
Node: ADD-ON COMMANDS77453
|
||||
Ref: #add-on-commands77563
|
||||
Node: Official add-ons78850
|
||||
Ref: #official-add-ons78990
|
||||
Node: api79077
|
||||
Ref: #api79166
|
||||
Node: ui79218
|
||||
Ref: #ui79317
|
||||
Node: web79375
|
||||
Ref: #web79464
|
||||
Node: Third party add-ons79510
|
||||
Ref: #third-party-add-ons79685
|
||||
Node: diff79820
|
||||
Ref: #diff79917
|
||||
Node: iadd80016
|
||||
Ref: #iadd80130
|
||||
Node: interest80213
|
||||
Ref: #interest80334
|
||||
Node: irr80429
|
||||
Ref: #irr80527
|
||||
Node: Experimental add-ons80605
|
||||
Ref: #experimental-add-ons80757
|
||||
Node: autosync81037
|
||||
Ref: #autosync81148
|
||||
Node: chart81387
|
||||
Ref: #chart81506
|
||||
Node: check81577
|
||||
Ref: #check81679
|
||||
Node: print64235
|
||||
Ref: #print64345
|
||||
Node: print-unique69239
|
||||
Ref: #print-unique69365
|
||||
Node: register69433
|
||||
Ref: #register69560
|
||||
Node: Custom register output74061
|
||||
Ref: #custom-register-output74190
|
||||
Node: register-match75420
|
||||
Ref: #register-match75554
|
||||
Node: rewrite75737
|
||||
Ref: #rewrite75854
|
||||
Node: stats75923
|
||||
Ref: #stats76026
|
||||
Node: tags76896
|
||||
Ref: #tags76994
|
||||
Node: test77230
|
||||
Ref: #test77314
|
||||
Node: ADD-ON COMMANDS77682
|
||||
Ref: #add-on-commands77792
|
||||
Node: Official add-ons79079
|
||||
Ref: #official-add-ons79219
|
||||
Node: api79306
|
||||
Ref: #api79395
|
||||
Node: ui79447
|
||||
Ref: #ui79546
|
||||
Node: web79604
|
||||
Ref: #web79693
|
||||
Node: Third party add-ons79739
|
||||
Ref: #third-party-add-ons79914
|
||||
Node: diff80049
|
||||
Ref: #diff80146
|
||||
Node: iadd80245
|
||||
Ref: #iadd80359
|
||||
Node: interest80442
|
||||
Ref: #interest80563
|
||||
Node: irr80658
|
||||
Ref: #irr80756
|
||||
Node: Experimental add-ons80834
|
||||
Ref: #experimental-add-ons80986
|
||||
Node: autosync81266
|
||||
Ref: #autosync81377
|
||||
Node: chart81616
|
||||
Ref: #chart81735
|
||||
Node: check81806
|
||||
Ref: #check81908
|
||||
|
||||
End Tag Table
|
||||
|
||||
@ -1727,7 +1727,10 @@ COMMANDS
|
||||
tion.
|
||||
|
||||
prices
|
||||
Print all market prices from the journal.
|
||||
Print market price directives from the journal. With -costs, also
|
||||
print synthetic market prices based on transaction prices. With
|
||||
-inverted-costs, also print inverse prices based on transaction prices.
|
||||
Prices (and postings providing prices) can be filtered by a query.
|
||||
|
||||
print
|
||||
Show transactions from the journal. Aliases: p, txns.
|
||||
|
||||
@ -506,7 +506,10 @@ you can alter the report mode with `--change`/`--cumulative`/`--historical`.
|
||||
This command also supports [output destination](/manual.html#output-destination) and [output format](/manual.html#output-format) selection.
|
||||
|
||||
## prices
|
||||
Print all [market prices](/manual#market-prices) from the journal.
|
||||
Print [market price directives](/manual#market-prices) from the journal.
|
||||
With --costs, also print synthetic market prices based on [transaction prices](/manual#transaction-prices).
|
||||
With --inverted-costs, also print inverse prices based on transaction prices.
|
||||
Prices (and postings providing prices) can be filtered by a query.
|
||||
|
||||
## print
|
||||
Show transactions from the journal. Aliases: p, txns.
|
||||
|
||||
@ -148,15 +148,13 @@ If you prefer more control or if hledger-install failed, here's how to use stack
|
||||
|
||||
On Windows, the 64-bit version of stack is [preferred](https://github.com/simonmichael/hledger/issues/275#issuecomment-123834252).
|
||||
|
||||
2. **`stack install --resolver=nightly-2018-06-02 hledger-lib-1.10 hledger-1.10 hledger-ui-1.10 fsnotify-0.3.0.1 hledger-web-1.10.1 hledger-api-1.10`**\
|
||||
2. **`stack install --resolver=lts-12 hledger-lib-1.10 hledger-1.10 hledger-ui-1.10.1 hledger-web-1.10 hledger-api-1.10`**\
|
||||
This installs the main hledger packages (and dependencies) from [Stackage](https://www.stackage.org) and/or [Hackage](http://hackage.haskell.org).
|
||||
You can save some time by omitting hledger-* packages you don't want.\
|
||||
<span class=warnings>([windows: hledger-ui is not available](https://github.com/jtdaugherty/vty/pull/1#issuecomment-297143444))</span>
|
||||
|
||||
The command above uses stackage's nightly snapshot.
|
||||
You might be able to reduce build time by specifying an older snapshot that you've used before (eg: `--resolver=lts-10.8`), or by omitting the --resolver option.
|
||||
To estimate the build time, add `--dry-run`.
|
||||
You can kill and restart this without losing progress.
|
||||
To estimate the build time, add `--dry-run`.
|
||||
|
||||
If you see "was generated with a newer version of hpack, please upgrade and try again" errors, you can ignore them.
|
||||
(Upgrade to the latest stack release to stop them.)
|
||||
@ -179,9 +177,7 @@ If you prefer more control or if hledger-install failed, here's how to use stack
|
||||
[hledger-iadd](http://hackage.haskell.org/package/hledger-iadd),
|
||||
[hledger-interest](http://hackage.haskell.org/package/hledger-interest),
|
||||
and [hledger-irr](http://hackage.haskell.org/package/hledger-irr)
|
||||
can be installed similarly to the above. Eg:
|
||||
|
||||
**`stack install --resolver=nightly-2018-06-02 hledger-lib-1.10 hledger-1.10 hledger-iadd-1.3.5`**
|
||||
can be installed similarly to the above.
|
||||
|
||||
6. **[Test](#test)**
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user