all repos

clerk @ 23d0a0d

missing tooling for ledger/hledger

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

Oleksandr Smirnov Oleksandr Smirnov
olexsmir@gmail.com
feat: config (#6), 1 month 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
	set, warns, err := loadConfig(cmd)
21
	if err != nil {
22
		return err
23
	}
24
25
	for _, w := range warns {
26
		fmt.Fprintln(os.Stderr, "warning:", w)
27
	}
28
29
	lint, err := linter.NewLinter(set.Linter)
30
	if err != nil {
31
		return err
32
	}
33
	reporter := linter.NewReporter(os.Stdout, parsePathStyle(pathStyle), set.Linter)
34
35
	journals := cmd.StringArgs("journals")
36
	if len(journals) == 0 {
37
		return c.lintStdin(lint, reporter, format)
38
	}
39
40
	journalFiles, err := resolvePaths(journals)
41
	if err != nil {
42
		return err
43
	}
44
	if len(journalFiles) == 0 {
45
		return nil
46
	}
47
48
	loader := journal.NewLoader()
49
50
	var hasFailures bool
51
	for _, f := range journalFiles {
52
		rj, err := loader.Resolve(f)
53
		if err != nil {
54
			fmt.Fprintf(os.Stderr, "error: %v\n", err)
55
			hasFailures = true
56
			continue
57
		}
58
		reporter.Collect(lint.Run(analyzer.Build(rj)))
59
	}
60
61
	if err := reporter.Flush(format); err != nil {
62
		return fmt.Errorf("flushing report: %w", err)
63
	}
64
65
	if reporter.HasFailures() || hasFailures {
66
		return cli.Exit("", 1)
67
	}
68
	return nil
69
}
70
71
func (c *Cli) lintStdin(lint *linter.Linter, reporter *linter.Reporter, format string) error {
72
	src, err := readStdin()
73
	if err != nil {
74
		return err
75
	}
76
	loader := journal.NewLoader()
77
	rj := loader.ResolveBytes("stdin", src)
78
	reporter.Collect(lint.Run(analyzer.Build(rj)))
79
80
	if err := reporter.Flush(format); err != nil {
81
		return fmt.Errorf("flushing report: %w", err)
82
	}
83
	if reporter.HasFailures() {
84
		return cli.Exit("", 1)
85
	}
86
	return nil
87
}
88
89
func parsePathStyle(s string) linter.PathStyle {
90
	switch strings.ToLower(s) {
91
	case "basename":
92
		return linter.PathBasename
93
	case "absolute":
94
		return linter.PathAbsolute
95
	default:
96
		return linter.PathRelative
97
	}
98
}