all repos

clerk @ 907ec027d0258eebc2a7fffe118438a8bbf7018e

missing tooling for ledger/hledger
5 files changed, 55 insertions(+), 0 deletions(-)
linter: add undeclared-payee rule
Author: Oleksandr Smirnov olexsmir@gmail.com
Committed at: 2026-08-06 16:58:06 +0300
Authored at: 2026-08-06 16:57:41 +0300
Change ID: ruwokolqmyrpoqqtupvpwwnnlvkrqzsk
Parent: e3c8c08
M internal/linter/linter_test.go
···
        28
        28
         	"undeclared-tag":           {&UndeclaredTag{}},

      
        29
        29
         	"undeclared-commodity":     {&UndeclaredCommodity{}},

      
        30
        30
         	"undeclared-account":       {&UndeclaredAccount{}},

      
        
        31
        +	"undeclared-payee":         {&UndeclaredPayee{}},

      
        31
        32
         	"unbalanced-transaction":   {&UnbalancedTransaction{}},

      
        32
        33
         	"unused-account":           {&UnusedAccount{}},

      
        33
        34
         	"unused-tag":               {&UnusedTag{}},

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

      
        
        2
        +

      
        
        3
        +import (

      
        
        4
        +	"fmt"

      
        
        5
        +

      
        
        6
        +	"olexsmir.xyz/clerk/internal/analyzer"

      
        
        7
        +)

      
        
        8
        +

      
        
        9
        +// UndeclaredPayee flags transactions that reference a payee not declared via `payee` directive.

      
        
        10
        +type UndeclaredPayee struct{}

      
        
        11
        +

      
        
        12
        +func (UndeclaredPayee) ID() RuleID         { return "undeclared-payee" }

      
        
        13
        +func (UndeclaredPayee) Severity() Severity { return SeverityWarning }

      
        
        14
        +func (u *UndeclaredPayee) CheckJournal(an *analyzer.Analysis) []Find {

      
        
        15
        +	var finds []Find

      
        
        16
        +	for name, info := range an.Payees {

      
        
        17
        +		if name == "" {

      
        
        18
        +			continue

      
        
        19
        +		}

      
        
        20
        +		if len(info.Directives) > 0 {

      
        
        21
        +			continue

      
        
        22
        +		}

      
        
        23
        +		for _, usage := range info.Usage {

      
        
        24
        +			finds = append(finds, Find{

      
        
        25
        +				Code:     u.ID(),

      
        
        26
        +				Severity: u.Severity(),

      
        
        27
        +				Span:     usage.Payee.Span,

      
        
        28
        +				Message:  fmt.Sprintf("undeclared payee: %s", name),

      
        
        29
        +			})

      
        
        30
        +		}

      
        
        31
        +	}

      
        
        32
        +	return finds

      
        
        33
        +}

      
M internal/linter/rules.go
···
        29
        29
         	&DuplicatedTag{},

      
        30
        30
         	&UndeclaredCommodity{},

      
        31
        31
         	&UndeclaredAccount{},

      
        
        32
        +	&UndeclaredPayee{},

      
        32
        33
         	&UnbalancedTransaction{},

      
        33
        34
         	&UndeclaredTag{},

      
        34
        35
         	&InvalidDateTag{},

      
M internal/linter/testdata/correct.txtar
···
        6
        6
         commodity 1,000.00 UAH

      
        7
        7
         commodity 1000.00 USD

      
        8
        8
         

      
        
        9
        +payee groceries

      
        
        10
        +

      
        9
        11
         2024-05-01 * "groceries"

      
        10
        12
             expenses:food   50.00 USD

      
        11
        13
             assets:cash

      
A internal/linter/testdata/undeclared-payee.txtar
···
        
        1
        +-- in.journal --

      
        
        2
        +payee "Groceries"

      
        
        3
        +

      
        
        4
        +2024-05-01 * "Groceries"

      
        
        5
        +    expenses:food   50.00 USD

      
        
        6
        +    assets:cash

      
        
        7
        +

      
        
        8
        +2024-05-02 * "Cafe"

      
        
        9
        +    expenses:food   15.00 USD

      
        
        10
        +    assets:cash

      
        
        11
        +

      
        
        12
        +2024-05-03 * "Cafe"

      
        
        13
        +    expenses:food   20.00 USD

      
        
        14
        +    assets:cash

      
        
        15
        +

      
        
        16
        +-- expect --

      
        
        17
        +in.journal:7:14: undeclared-payee: undeclared payee: Cafe

      
        
        18
        +in.journal:11:14: undeclared-payee: undeclared payee: Cafe