all repos

clerk @ 8575d55

missing tooling for ledger/hledger
5 files changed, 43 insertions(+), 0 deletions(-)
lint: add unused-account rule
Author: Oleksandr Smirnov olexsmir@gmail.com
Committed at: 2026-07-12 13:17:39 +0300
Authored at: 2026-07-11 21:20:54 +0300
Change ID: kyvpswyvlosltwkvrykzzurnvrwrqolu
Parent: 624171a
M internal/linter/linter_test.go
···
        25
        25
         	"undeclared-commodity":     {&UndeclaredCommodity{}},

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

      
        27
        27
         	"unbalanced-transaction":   {&UnbalancedTransaction{}},

      
        
        28
        +	"unused-account":           {&UnusedAccount{}},

      
        28
        29
         }

      
        29
        30
         

      
        30
        31
         func TestLinter(t *testing.T) {

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

      
        
        2
        +

      
        
        3
        +import (

      
        
        4
        +	"fmt"

      
        
        5
        +

      
        
        6
        +	"olexsmir.xyz/clerk/journal/semantic"

      
        
        7
        +)

      
        
        8
        +

      
        
        9
        +// UnusedAccount flags declared accounts that are not used.

      
        
        10
        +type UnusedAccount struct{}

      
        
        11
        +

      
        
        12
        +func (UnusedAccount) ID() RuleID         { return "unused-account" }

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

      
        
        14
        +func (a *UnusedAccount) CheckJournal(ctx *semantic.Context) []Find {

      
        
        15
        +	var finds []Find

      
        
        16
        +	for name, info := range ctx.Accounts {

      
        
        17
        +		if len(info.Directives) == 0 {

      
        
        18
        +			continue

      
        
        19
        +		}

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

      
        
        21
        +			continue

      
        
        22
        +		}

      
        
        23
        +		for _, d := range info.Directives {

      
        
        24
        +			finds = append(finds, Find{

      
        
        25
        +				Code:     a.ID(),

      
        
        26
        +				Severity: a.Severity(),

      
        
        27
        +				Span:     d.Account.Span,

      
        
        28
        +				Message:  fmt.Sprintf("unused account: %s", name),

      
        
        29
        +			})

      
        
        30
        +		}

      
        
        31
        +	}

      
        
        32
        +	return finds

      
        
        33
        +}

      
M internal/linter/rules.go
···
        42
        42
         	&UndeclaredCommodity{},

      
        43
        43
         	&UndeclaredAccount{},

      
        44
        44
         	&UnbalancedTransaction{},

      
        
        45
        +	&UnusedAccount{},

      
        45
        46
         }

      
A internal/linter/testdata/unused-account.golden
···
        
        1
        +unused-account.journal:2:9: unused-account: unused account: equity:opening

      
A internal/linter/testdata/unused-account.input
···
        
        1
        +account assets:cash

      
        
        2
        +account equity:opening

      
        
        3
        +account assets:cash

      
        
        4
        +

      
        
        5
        +2024-05-02 * "groceries"

      
        
        6
        +    expenses:food   40.00 USD

      
        
        7
        +    assets:cash