all repos

clerk @ 549106949384b5856034829d8d10ac55e42c116c

missing tooling for ledger/hledger
6 files changed, 43 insertions(+), 5 deletions(-)
linter: add missing-payee rule
Author: Oleksandr Smirnov olexsmir@gmail.com
Committed at: 2026-06-27 17:53:42 +0300
Authored at: 2026-06-27 17:01:21 +0300
Change ID: spxxllzozqrnqvtnvmpxqrtksnpmskpr
Parent: 3fa39df
M internal/linter/linter_test.go
···
        16
        16
         	"omitted-precision":        {&OmittedPrecision{}},

      
        17
        17
         	"missing-commodity":        {&MissingCommodity{}},

      
        18
        18
         	"missing-status":           {&MissingStatus{}},

      
        
        19
        +	"missing-payee":            {&MissingPayee{}},

      
        19
        20
         	"account-depth":            {&AccountDepthLimit{MaxDepth: 3}},

      
        20
        21
         	"multiple-omitted-amounts": {&MultipleOmittedAmounts{}},

      
        21
        22
         	"orderdate":                {&OrderDate{}},

      
A internal/linter/rule_missing_payee.go
···
        
        1
        +package linter

      
        
        2
        +

      
        
        3
        +import "olexsmir.xyz/clerk/journal/ast"

      
        
        4
        +

      
        
        5
        +// MissingPayee flags transactions with missing payee.

      
        
        6
        +type MissingPayee struct{}

      
        
        7
        +

      
        
        8
        +func (MissingPayee) ID() RuleID         { return "missing-payee" }

      
        
        9
        +func (MissingPayee) Severity() Severity { return SeverityWarning }

      
        
        10
        +func (m *MissingPayee) CheckEntry(entry ast.Entry) []Find {

      
        
        11
        +	txn, ok := entry.(*ast.Transaction)

      
        
        12
        +	if !ok {

      
        
        13
        +		return nil

      
        
        14
        +	}

      
        
        15
        +	if txn.Payee == nil {

      
        
        16
        +		return []Find{{

      
        
        17
        +			Code:     m.ID(),

      
        
        18
        +			Severity: m.Severity(),

      
        
        19
        +			Message:  "transaction has no payee",

      
        
        20
        +			Span:     txn.Date.Span,

      
        
        21
        +		}}

      
        
        22
        +	}

      
        
        23
        +	return nil

      
        
        24
        +}

      
M internal/linter/rules.go
···
        33
        33
         	&OmittedPrecision{},

      
        34
        34
         	&MissingCommodity{},

      
        35
        35
         	&MissingStatus{},

      
        
        36
        +	&MissingPayee{},

      
        36
        37
         	&AccountDepthLimit{MaxDepth: 4},

      
        37
        38
         	&MultipleOmittedAmounts{},

      
        38
        39
         	&OrderDate{},

      
A internal/linter/testdata/missing-payee.golden
···
        
        1
        +missing-payee.journal:5:1: missing-payee: transaction has no payee

      
A internal/linter/testdata/missing-payee.input
···
        
        1
        +2024-05-01 "groceries"

      
        
        2
        +  expenses:food  50.00 USD

      
        
        3
        +  assets:cash

      
        
        4
        +

      
        
        5
        +2024-05-02 *

      
        
        6
        +  expenses:food  50.00 USD

      
        
        7
        +  assets:cash

      
        
        8
        +

      
        
        9
        +2024-05-03 * "groceries"

      
        
        10
        +  expenses:food  50.00 USD

      
        
        11
        +  assets:cash

      
M journal/ast/entries.go
···
        11
        11
         

      
        12
        12
         type Transaction struct {

      
        13
        13
         	Date           Date

      
        14
        
        -	SecondDate     *Date    // optional =2026-05-18 date

      
        15
        
        -	Status         Status   // optional */! status

      
        16
        
        -	Code           *string  // optional (123) code

      
        17
        
        -	Payee          *Payee   // optional payee

      
        18
        
        -	Note           *string  // part after |

      
        
        14
        +	SecondDate     *Date      // optional =2026-05-18 date

      
        
        15
        +	Status         Status     // optional */! status

      
        
        16
        +	Code           *string    // optional (123) code

      
        
        17
        +	Payee          *Payee     // optional payee

      
        
        18
        +	Note           *string    // part after |

      
        19
        19
         	Comment        *Comment   // inline ; on header line

      
        20
        20
         	HeaderComments []*Comment // indented ; lines before first posting

      
        21
        21
         	Postings       []*Posting