all repos

clerk @ 1f3a17349e37c8189adb11b8d956acbf3b2080d1

missing tooling for ledger/hledger

clerk/internal/linter/rule_account_depth.go (view raw)

Oleksandr Smirnov Oleksandr Smirnov
olexsmir@gmail.com
improve analyzer, 1 day ago
1
package linter
2
3
import (
4
	"fmt"
5
6
	"olexsmir.xyz/clerk/internal/analyzer"
7
	"olexsmir.xyz/clerk/journal/ast"
8
)
9
10
// AccountDepthLimit checks that account names don't exceed MaxDepth
11
type AccountDepthLimit struct {
12
	MaxDepth int
13
}
14
15
func (AccountDepthLimit) ID() RuleID         { return "account-depth" }
16
func (AccountDepthLimit) Severity() Severity { return SeverityWarning }
17
func (a *AccountDepthLimit) CheckJournal(an *analyzer.Analysis) []Find {
18
	var finds []Find
19
20
	for _, txn := range an.Transactions {
21
		for _, p := range txn.Postings {
22
			a.check(&finds, p.Account)
23
		}
24
	}
25
	for _, ptx := range an.PeriodicTransactions {
26
		for _, p := range ptx.Postings {
27
			a.check(&finds, p.Account)
28
		}
29
	}
30
	for _, atx := range an.AutomatedTransactions {
31
		for _, p := range atx.Postings {
32
			a.check(&finds, p.Account)
33
		}
34
	}
35
36
	for _, d := range an.Directives {
37
		switch e := d.(type) {
38
		case *ast.AccountDirective:
39
			a.check(&finds, e.Account)
40
		case *ast.AliasDirective:
41
			a.check(&finds, e.From)
42
			a.check(&finds, e.To)
43
		}
44
	}
45
46
	return finds
47
}
48
49
func (a *AccountDepthLimit) check(finds *[]Find, acc ast.Account) {
50
	if depth := len(acc.Name); depth > a.MaxDepth {
51
		*finds = append(*finds, Find{
52
			Code:     a.ID(),
53
			Severity: a.Severity(),
54
			Message: fmt.Sprintf("account %q depth (%d) exceeds max allowed depth (%d)",
55
				acc.String(), depth, a.MaxDepth),
56
			Span: acc.Span,
57
		})
58
	}
59
}