Commit Graph

2729 Commits

Author SHA1 Message Date
Simon Michael
3c0a02a34a Revert "fix:lib:Hledger.Query: words'': Parse escaped quotes in quoted patterns" [#2513]
This reverts commit de900e5b24, it's not
as safe as we thought.
2026-01-06 21:55:35 -10:00
Simon Michael
3b656ff372 imp:add,import: also create directories when autocreating journal file
When autocreating a journal file specified by -f or LEDGER_FILE,
required parent directories will now also be autocreated if needed.
2026-01-06 21:39:59 -10:00
Simon Michael
e7d7c49562 imp: -f now errors if given a glob matching no files, like LEDGER_FILE
Previously LEDGER_FILE=foo hledger add did, but hledger -f foo add didn't.
Now they both consistently will error if given a glob
(a path contining [, {, *, or ?) that matches nothing,
rather than auto-creating a file with a glob-like name.

Hledger.Utils.IO:
expandPathOrGlob
2026-01-06 21:39:59 -10:00
Simon Michael
88f6c16dd5 fix:add,import: autocreate missing journal files again (but later) [#2514]
This restores the pre-1.50.3 behaviour of add and import, which once
again auto-create a missing file (specified by -f or LEDGER_FILE or
the builtin default path) rather than giving an error.
This fixes #2514 and refines the fix for [#2485].

There's also an improvement: they no longer create it unconditionally at the start;
they create lazily, when they have data to write.

Hledger.Read:
defaultExistingJournalPath
defaultExistingJournalPathSafely
readPossibleJournalFile

Hledger.Cli.Utils:
withPossibleJournal
2026-01-06 21:39:59 -10:00
Oleg Bulatov
abd7d60884 imp:lib:valuation: optimize price lookup with pre-built indexes [#2511]
Replace O(n log n) re-sorting of all prices on every valuation date
with O(log n) indexed lookups. By pre-building sorted price indexes
once at startup using O(n log n) time, we avoid redundant work
during reports.

This significantly improves performance for --value=end,COMM with daily
reports over long periods and large price databases.

Implementation:
- PriceIndex maps commodity pairs to a Map from date to effective
  price, enabling O(log n) temporal lookups via M.lookupLE.
- DefaultValuationIndex provides efficient resolution of destination
  commodities using the same temporal logic.
- makePriceGraph is updated to consume these indexes.

Signed-off-by: Oleg Bulatov <oleg@bulatov.me>
2026-01-02 17:05:24 -10:00
Simon Michael
3d85549e79 dev:Hledger.Utils.IO: clarify expandPath, expandHomePath 2025-12-31 00:28:05 -10:00
Simon Michael
60293349bb ;imp:lib:Hledger.Utils.IO.expandHomePath: handle a bare ~ 2025-12-26 15:05:34 -10:00
Tuong Nguyen Manh
de900e5b24 fix:lib:Hledger.Query: words'': Parse escaped quotes in quoted patterns 2025-12-26 12:09:49 -10:00
Simon Michael
c0971c1c09 dev: cleanup 2025-12-16 00:18:28 -10:00
Simon Michael
48620c8e8c imp:journal:include: don't read file attributes unnecessarily
When including a literal path, don't use the Glob library at all.
Glob seems to read attributes of all files in a directory,
which disturbs build tools like tup which detect dependencies
based on filesystem operations.
2025-12-15 21:54:53 -10:00
Simon Michael
ebaabe4305 imp:journal: fix a slight pessimisation of include directives
Since 1.50.3, canonicalizePath was being called wastefully when
processing journals with many nested include files and/or many matches
for include glob paths. On a slow filesystem, with unusually
many includes, this might have been quite noticeable.

Now we canonicalise each file path just once as it is encountered,
avoiding the wasted IO work.
2025-12-10 19:21:59 -10:00
Simon Michael
665e2d0a55 fix:journal:include: relative includes from a symlinked file work again [#2503] 2025-12-08 09:36:13 -10:00
Simon Michael
784bdb4637 imp:aregister: correct that comment about transaction numbering 2025-12-07 17:44:01 -10:00
Simon Michael
67b2063809 imp!:aregister, journal: same-day txns respect order of -f options
If transactions on the same date are coming from two files specified
with -f options, we expect them to be displayed in parse order, ie
respecting the order of the -f options. This wasn't always the case,
now it is.

Also, transactions' tindex field is now unique across all files,
where previously it started at 1 in each file. This affects hledger
data generally, not just the aregister command.
2025-12-07 17:21:36 -10:00
Simon Michael
f3bf7e80b9 imp:journal:include: grammar fix in "neither found" error message 2025-12-06 11:07:53 -10:00
Simon Michael
12234e0b7e ;fix:journal: including an unreadable file now shows a clearer error
showing the problem include directive (previously the line number was
off by one). Likewise for other IO errors like when resolving ~ and
a home directory can't be found.
2025-12-05 02:34:08 -10:00
Simon Michael
8cd113389a fix:journal:include: drop 1.50's exclusion of glob-matched dot paths [#2498]
1.50* attempted to work around Glob's implicit searching of non-top-level dot dirs.
This was overzealous; it meant that journal's include completely
excluded paths involving a glob and a dot dir or dot file anywhere in the path.

Now, the pre-1.50 behaviour is restored:
`*` and `**` won't implicitly match dot files or top-level dot directories.
They will implicitly search non-top-level dot directories, as before (#Glob#49).
2025-12-04 05:54:54 -10:00
Simon Michael
81744d81a1 fix:journal:include: fix some regressions with glob matching in 1.50-1.50.3
Before 1.50, journal's include directive's handling of glob patterns (*, **, ?, etc.)
had these limitations:

- ** always searched intermediate dot directories
- ** matched only directories, not files

In 1.50-1.50.3, it had different limitations, some unintended:

- it ignored all dot files, dot dirs, and symbolic links to dot dirs,
  even when explicitly mentioned in the pattern (unless using --old-glob)
- it showed symbolic links dereferenced, eg in `hledger files` output

Now it has fewer limitations, mainly this:

- it ignores all dot files and dot dirs, even when explicitly mentioned (unless using --old-glob)

Ie it no longer ignores symbolic links to dot dirs, and it no longer shows symbolic links dereferenced.
Also: including the current file is now always harmless, whether using a glob pattern or not.

Internally, file paths in the "include file stack" (jincludefilestack) are now just absolute,
but not canonicalised; showing symbolic links un-dereferenced in output and error messages seems
generally more useful. This might affect output elsewhere also.
(Those paths are still canonicalised on the fly when checking for include cycles,
not so efficiently: each time an include directive is parsed, all the current parent files
and all the new glob-matched include files will be re-canonicalised.
Hopefully this is unnoticeable.)
2025-12-01 11:28:51 -08:00
Simon Michael
00f6a832d4 fix:journal: consistent error message when include has no argument 2025-12-01 11:00:42 -08:00
Simon Michael
a280e02102 ;dev:comment 2025-11-27 12:36:14 -08:00
Simon Michael
b2a0de75e2 dev: balanceTransaction -> balanceSingleTransaction 2025-11-18 09:39:16 -10:00
Simon Michael
4087e72683 imp:lib:Hledger.Read: safer defaultJournal* functions 2025-11-17 22:26:04 -10:00
Simon Michael
9031612c30 fix!: error if LEDGER_FILE points to a nonexistent file [#2485]
Avoiding potentially confusing silent fallback. Also,

- Drop support for Ledger's legacy LEDGER environment variable;
  we now support only LEDGER_FILE, for simplicity.

- Clarify the behaviour, eg when a glob pattern matches multiple files
  or when the value is empty.
2025-11-17 21:09:55 -10:00
Simon Michael
356e2ba88a fix:journal: repair 1.50's journal reading slowness [#2493]
Since 1.50, sourceFilePath, which does IO operations, was being called for every item in the journal.
On my machine this was causing a ~40% slowdown,
but probably it could be more depending on storage system.

Now it's once again called only once per include directive.
Speed seems slightly better now than 1.43 for some reason
(eg: 13k txns/s -> 8k txns/s -> 14k txns/s).
2025-11-15 21:22:36 -10:00
Simon Michael
bd0a45d448 fix:PeriodData: simplify, use Day keys [#2479]
This is clearer and slightly better-performing than using Integer.
2025-10-11 11:27:58 -10:00
Simon Michael
438c4a0469 fix:PeriodData: use Integer keys to avoid date wraparound bugs [#2479]
PeriodData's use of Int keys caused wrong results with periodic
reports involving dates outside the machine-specific limits of Int.
Those were:

64 bits: -25252734927764696-04-22..25252734927768413-06-12
32 bits: -5877752-05-08..5881469-05-27
16 bits:  1769-02-28..1948-08-04
 8 bits:  1858-07-12..1859-03-24

32 bits is supported by MicroHS; 16 and 8 bits aren't supported by
any known haskell version, but that could change in future.

For example, on 64 bit machines we got:

25252734927768413-06-12 PeriodData's max date
   (expenses)   1

25252734927768414-01-01 next year past PeriodData's max date
   (expenses)   2

$ hledger reg -O csv --yearly
"txnidx","date","code","description","account","amount","total"
"0","-25252734927764696-11-10","","","expenses","1","1"

Now it uses Integer (like the time package), fixing the bug.
And benchmarking shows memory and time usage slightly improved
(surprisingly; tested with up to 500 subperiods, eg
hledger -f examples/10ktxns-1kaccts.journal reg -1 cur:A -D >/dev/null)
2025-10-11 11:27:58 -10:00
Simon Michael
70e9e7b060 ;dev: lookupDayPartition -> dayPartitionFind 2025-10-11 11:02:18 -10:00
Simon Michael
2e78a53931 ;dev: dayPartitionSpans -> dayPartitionStartEnd 2025-10-11 11:02:18 -10:00
Simon Michael
8779f2481a ;dev: PeriodData, DayPartition: haddock updates
Clarify some things. Also note an example of PeriodData wrapping around.
2025-10-11 11:02:18 -10:00
Stephen Morgan
4e9fa1615c dev!: lib: Refactor splitSpan to return Maybe DayPartition.
This eliminates all error calls from the chain calculating report
periods.
2025-10-09 15:31:28 -10:00
Stephen Morgan
b9caa4d948 dev!: balance: Use DayPartition for multibalance reports.
This allows us to guarantee that the report periods are well-formed and
don't contain errors (e.g. empty spans, spans not contiguous, spans not
a partition).

Note the underlying representation is now for disjoint spans, whereas
previously the end date of a span was equal to the start date of the
next span, and then was adjusted backwards one day when needed.
2025-10-09 15:31:28 -10:00
Caleb Maclennan
3c731ae2f7 fix: Only escape special characters by single quoting, not escaping *and* quoting 2025-10-09 11:52:37 -10:00
Simon Michael
e8672b3a18 fix:Hledger.Utils.String: quoteForCommandLine now quotes "&" [#2468]
This explains the mysterious "7".
2025-10-01 18:15:02 -10:00
Simon Michael
71b1293f06 fix:Hledger.Utils.String: quoteForCommandLine no longer quotes "7" [#2468]
7 is no longer considered a scary shell character.

(This appears to have been harmless, used only for formatting the
balance assertion failure message.)
2025-10-01 17:56:49 -10:00
Simon Michael
215ef5e12d fix:check accounts: don't garble non-ascii account names in errors [#2469]
This regressed in 1.27 or so.
2025-10-01 14:40:08 -10:00
Simon Michael
061d105fed dev:Hledger.Data.Journal: fix a recent ghc 9.6 / old base breakage 2025-09-29 19:31:49 -10:00
Simon Michael
2f007c93d2 dev: switch all qualifed imports to ImportQualifiedPost style 2025-09-29 19:28:59 -10:00
Simon Michael
e51e6c4e3d ;dev: remove old prototype 2025-09-29 18:35:20 -10:00
Simon Michael
a2af816611 dev:Hledger.Utils.IO: inputToHandle -> textToHandle; set utf8 not utf8_bom 2025-09-26 01:08:48 -10:00
Simon Michael
5db4ee7420 dev:Hledger.Utils.IO: readHandlePortably, readHandlePortably' -> hGetContentsPortably 2025-09-26 01:08:43 -10:00
Simon Michael
9351c70f74 fix:csv: respect encoding rule when rules file is input file [#2465] 2025-09-26 00:34:01 -10:00
Simon Michael
8542d8beba imp:errors: improve decode failure wording [#2465] 2025-09-25 01:28:32 -10:00
Simon Michael
e414446076 imp: pivoting on the type tag normalises type values to their short spelling. 2025-09-25 01:11:03 -10:00
Simon Michael
b5f954abf5 imp:errors: decode failures now also mention a possible CSV encoding [#2465] 2025-09-24 10:40:30 -10:00
Stephen Morgan
f515c5f811 fix: balance: Don't display zero rows with --no-elide (#2454)
Zero rows with --no-elide should only be displayed if either --empty is
called or they have non-zero children at some depth.
2025-09-15 15:40:32 -07:00
Simon Michael
6d164b48a0 imp:journal: in amounts, also allow and ignore empty {} (or {{}}) 2025-09-11 07:33:22 +01:00
Stephen Morgan
aad61e465d fix: balance: Correctly handle empty journals (#2452)
Eliminate several partial functions.
2025-09-11 07:29:27 +01:00
Simon Michael
bc55e1c58f dev: fix liftA2, Foldable1 build errors with ghc <9.6 [#2395] 2025-09-03 20:02:12 +01:00
Simon Michael
00fae3ac3b fix: ensure liftA2 is imported, build with ghc <9.6
This broke in 1.43.1.
2025-09-02 08:00:08 +01:00
Simon Michael
91d785aee8 dev:fix: use compatible code rather than new T.show added yesterday 2025-09-01 20:08:17 +01:00