all repos

clerk @ 15cdd169fba073f14cd005013bea135fe1ec2eb4

missing tooling for ledger/hledger
5 files changed, 47 insertions(+), 0 deletions(-)
linter: add missing-commodity
Author: Oleksandr Smirnov olexsmir@gmail.com
Committed at: 2026-06-10 21:52:35 +0300
Authored at: 2026-06-10 21:39:54 +0300
Change ID: oszvyzrrwyullqqltwommvmqsllupmku
Parent: 974dc2d
M internal/linter/linter_test.go
···
        13
        13
         	"empty-postings":    {&EmptyPostings{}},

      
        14
        14
         	"parse-error":       {&ParseError{}},

      
        15
        15
         	"omitted-precision": {&OmittedPrecision{}},

      
        
        16
        +	"missing-commodity": {&MissingCommodity{}},

      
        16
        17
         }

      
        17
        18
         

      
        18
        19
         func TestLinter(t *testing.T) {

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

      
        
        2
        +

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

      
        
        4
        +

      
        
        5
        +// MissingCommodity flags amounts with a missing commodity.

      
        
        6
        +type MissingCommodity struct{}

      
        
        7
        +

      
        
        8
        +func (MissingCommodity) ID() RuleID          { return "missing-commodity" }

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

      
        
        10
        +func (MissingCommodity) Description() string { return "amount missing commodity" }

      
        
        11
        +func (m *MissingCommodity) CheckEntry(entry ast.Entry) []Find {

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

      
        
        13
        +	if !ok || (txn.Postings != nil && len(txn.Postings) == 0) {

      
        
        14
        +		return nil

      
        
        15
        +	}

      
        
        16
        +

      
        
        17
        +	var finds []Find

      
        
        18
        +	for _, posting := range txn.Postings {

      
        
        19
        +		if posting.Amount == nil {

      
        
        20
        +			continue

      
        
        21
        +		}

      
        
        22
        +		if posting.Amount.Commodity == "" {

      
        
        23
        +			finds = append(finds, Find{

      
        
        24
        +				Code:     m.ID(),

      
        
        25
        +				Severity: m.Severity(),

      
        
        26
        +				Message:  m.Description(),

      
        
        27
        +				Span:     posting.Amount.Span,

      
        
        28
        +			})

      
        
        29
        +		}

      
        
        30
        +	}

      
        
        31
        +	return finds

      
        
        32
        +}

      
M internal/linter/rules.go
···
        28
        28
         	&ParseError{},

      
        29
        29
         	&EmptyPostings{},

      
        30
        30
         	&OmittedPrecision{},

      
        
        31
        +	&MissingCommodity{},

      
        31
        32
         }

      
A internal/linter/testdata/missing-commodity.golden
···
        
        1
        +missing-commodity.journal:2:21: missing-commodity: amount missing commodity

      
        
        2
        +missing-commodity.journal:10:21: missing-commodity: amount missing commodity

      
A internal/linter/testdata/missing-commodity.input
···
        
        1
        +2024-06-01 "no commodity"

      
        
        2
        +    expenses:food   50.00

      
        
        3
        +    assets:cash

      
        
        4
        +

      
        
        5
        +2024-06-02 "with commodity"

      
        
        6
        +    expenses:food   50.00 USD

      
        
        7
        +    assets:cash

      
        
        8
        +

      
        
        9
        +2024-06-03 "another missing"

      
        
        10
        +    expenses:food   100

      
        
        11
        +    assets:cash