all repos

clerk @ f3b258b

missing tooling for ledger/hledger

clerk/internal/cli/cmd_lint.go (view raw)

Oleksandr Smirnov Oleksandr Smirnov
olexsmir@gmail.com
improve analyzer, 1 day ago
1
package cli
2
3
import (
4
	"context"
5
	"fmt"
6
	"os"
7
	"strings"
8
9
	"github.com/urfave/cli/v3"
10
11
	"olexsmir.xyz/clerk/internal/analyzer"
12
	"olexsmir.xyz/clerk/internal/linter"
13
	"olexsmir.xyz/clerk/journal"
14
)
15
16
func (c *Cli) lintAction(ctx context.Context, cmd *cli.Command) error {
17
	format := cmd.String("format")
18
	pathStyle := cmd.String("path-style")
19
20
	lint := linter.NewLinter(linter.Rules)
21
	reporter := linter.NewReporter(os.Stdout, parsePathStyle(pathStyle))
22
23
	journals := cmd.StringArgs("journals")
24
	if len(journals) == 0 {
25
		return c.lintStdin(lint, reporter, format)
26
	}
27
28
	journalFiles, err := resolvePaths(journals)
29
	if err != nil {
30
		return err
31
	}
32
	if len(journalFiles) == 0 {
33
		return nil
34
	}
35
36
	loader := journal.NewLoader()
37
38
	var hasIssues bool
39
	for _, f := range journalFiles {
40
		if _, err := loadFile(loader, f); err != nil {
41
			fmt.Fprintf(os.Stderr, "error: %v\n", err)
42
			hasIssues = true
43
		}
44
	}
45
46
	for _, root := range loader.Roots() {
47
		reporter.Collect(lint.Run(analyzer.Build(journal.CollectFiles(root))))
48
	}
49
50
	if err := reporter.Flush(format); err != nil {
51
		return fmt.Errorf("flushing report: %w", err)
52
	}
53
54
	if reporter.HasIssues() || hasIssues {
55
		return cli.Exit("", 1)
56
	}
57
	return nil
58
}
59
60
func (c *Cli) lintStdin(lint *linter.Linter, reporter *linter.Reporter, format string) error {
61
	loader := journal.NewLoader()
62
	if _, err := loadStdin(loader); err != nil {
63
		return err
64
	}
65
66
	for _, root := range loader.Roots() {
67
		reporter.Collect(lint.Run(analyzer.Build(journal.CollectFiles(root))))
68
	}
69
70
	if err := reporter.Flush(format); err != nil {
71
		return fmt.Errorf("flushing report: %w", err)
72
	}
73
	if reporter.HasIssues() {
74
		return cli.Exit("", 1)
75
	}
76
	return nil
77
}
78
79
func parsePathStyle(s string) linter.PathStyle {
80
	switch strings.ToLower(s) {
81
	case "basename":
82
		return linter.PathBasename
83
	case "absolute":
84
		return linter.PathAbsolute
85
	default:
86
		return linter.PathRelative
87
	}
88
}