all repos

clerk @ cb22f86

missing tooling for ledger/hledger

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

Oleksandr Smirnov Oleksandr Smirnov
olexsmir@gmail.com
linter: add invalid-include rule, 2 months 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
// InvalidInclude flags include directives that don't point to an existing journal file.
13
type InvalidInclude struct{}
14
15
func (InvalidInclude) ID() RuleID         { return "invalid-include" }
16
func (InvalidInclude) Severity() Severity { return SeverityError }
17
func (i *InvalidInclude) CheckJournal(an *analyzer.Analysis) []Find {
18
	var finds []Find
19
	for _, pf := range an.Files {
20
		for _, entry := range pf.Ast.Entries {
21
			inc, ok := entry.(*ast.IncludeDirective)
22
			if !ok {
23
				continue
24
			}
25
			target := filepath.Clean(filepath.Join(filepath.Dir(pf.Path), inc.Path))
26
27
			if !i.resolved(target, an.Files) {
28
				finds = append(finds, Find{
29
					Code:     i.ID(),
30
					Severity: i.Severity(),
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
					Severity: i.Severity(),
40
					Message:  fmt.Sprintf("include is not a journal file: %s", inc.Path),
41
					Span:     inc.Span,
42
				})
43
			}
44
		}
45
	}
46
	return finds
47
}
48
49
func (i *InvalidInclude) resolved(target string, files []*journal.ParsedFile) bool {
50
	for _, pf := range files {
51
		if ok, _ := filepath.Match(target, pf.Path); ok {
52
			return true
53
		}
54
	}
55
	return false
56
}