all repos

clerk @ 7b8e468208b6ef8bf9db2b5f2f8c1f01b22cb31a

missing tooling for ledger/hledger

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

Oleksandr Smirnov Oleksandr Smirnov
olexsmir@gmail.com
feat: config (#6), 1 month ago
1
package linter
2
3
import (
4
	"fmt"
5
	"path/filepath"
6
7
	"olexsmir.xyz/clerk/internal/analyzer"
8
	"olexsmir.xyz/clerk/journal"
9
	"olexsmir.xyz/clerk/journal/ast"
10
)
11
12
const InvalidIncludeID RuleID = "invalid-include"
13
14
// InvalidInclude flags include directives that don't point to an existing journal file.
15
type InvalidInclude struct{}
16
17
func (InvalidInclude) ID() RuleID { return InvalidIncludeID }
18
func (i *InvalidInclude) CheckJournal(an *analyzer.Analysis) []Find {
19
	var finds []Find
20
	for _, pf := range an.Files {
21
		for _, entry := range pf.Ast.Entries {
22
			inc, ok := entry.(*ast.IncludeDirective)
23
			if !ok {
24
				continue
25
			}
26
			target := filepath.Clean(filepath.Join(filepath.Dir(pf.Path), inc.Path))
27
28
			if !i.resolved(target, an.Files) {
29
				finds = append(finds, Find{
30
					Code:    i.ID(),
31
					Message: fmt.Sprintf("include not found: %s", inc.Path),
32
					Span:    inc.Span,
33
				})
34
				continue
35
			}
36
			if !journal.IsJournalFile(target) {
37
				finds = append(finds, Find{
38
					Code:    i.ID(),
39
					Message: fmt.Sprintf("include is not a journal file: %s", inc.Path),
40
					Span:    inc.Span,
41
				})
42
			}
43
		}
44
	}
45
	return finds
46
}
47
48
func (i *InvalidInclude) resolved(target string, files []*journal.ParsedFile) bool {
49
	for _, pf := range files {
50
		if ok, _ := filepath.Match(target, pf.Path); ok {
51
			return true
52
		}
53
	}
54
	return false
55
}