Skip to content

rules: directives are evaluated "first wins", contra Manual description #2539

@kpewing

Description

@kpewing

Per https://hledger.org/1.51/hledger.html?search=#how-csv-rules-are-evaluated:

  1. Top level rules (date-format, fields, newest-first, skip etc) are read, top to bottom. "Top level rules" means non-conditional rules. If a rule occurs more than once, the last one wins; except for skip/end rules, where the first one wins.

In fact the first one wins.

Example:

> >Savings.csv cat <<EOS
2000-01-01,withdraw,1.00
EOS
> >test.rules cat<<EOS
fields date,description,amount
date-format %m/%d/%Y
date-format %Y-%m-%d
EOS
> hledger -f Savings.csv --rules test.rules print
hledger: Error: could not parse "2000-01-01" as a date using date format "%m/%d/%Y"
record: 2000-01-01,test transaction,1.00
the date rule is:   %1
the date-format is: %m/%d/%Y
you may need to change your date rule, change your date-format rule, or add a skip rule
for m/d/y or d/m/y dates, use date-format %-m/%-d/%Y or date-format %-d/%-m/%Y

This complicates using a hierarchy of rule inclusions to provide a hierarchy of default directives, e.g., a general date-format for Assets, a different one for Assets:BankOne, and yet a different one for Assets:BankOne:Savings.

A work-around is to adopt self-discipline of specifying directives as a group before any conditionals and to put any include directive between the local directives and the local conditionals, as in this contrived example:

> >BankOne.rules cat <<EOS
fields date,description,amount
date-format  %m/%d/%Y

if %description withdraw
    account1       BankOne
EOS
> >Savings.rules cat <<EOS
date-format %Y-%m-%d

include BankOne.rules

if %description withdraw
    account1       BankOne:Savings
EOS
> hledger -f Savings.csv --rules Savings.rules print

Given the explanation in the Manual, however, I assume the current behavior is a bug. Perhaps it can be resolved by removing the reverse inside mkrules for rdirectives at

rdirectives=reverse $ rdirectives rules,
.

Seeing the code, I assume a similar issue arises for field assignments, which could be resolved by removing the reverse for rassignments at line 624.

My system:

> hledger --version
hledger 1.51.2, mac-aarch64
> sw_vers
ProductName:		macOS
ProductVersion:		26.2
BuildVersion:		25C56

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-BUGSomething wrong, confusing or sub-standard in the software, docs, or user experience.affects4-manyAffects potentially a significant number of users.annoyance2-minorMinor to moderate usability/doc bug, reasonably easy to avoid or tolerate.csvThe csv file format, csv output format, or generally CSV-related.docsDocumentation-related.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions