all repos

clerk @ 1f3a17349e37c8189adb11b8d956acbf3b2080d1

missing tooling for ledger/hledger

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

Oleksandr Smirnov Oleksandr Smirnov
olexsmir@gmail.com
improve loader, 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
		rj, err := loader.Resolve(f)
41
		if err != nil {
42
			fmt.Fprintf(os.Stderr, "error: %v\n", err)
43
			hasIssues = true
44
			continue
45
		}
46
		reporter.Collect(lint.Run(analyzer.Build(rj)))
47
	}
48
49
	if err := reporter.Flush(format); err != nil {
50
		return fmt.Errorf("flushing report: %w", err)
51
	}
52
53
	if reporter.HasIssues() || hasIssues {
54
		return cli.Exit("", 1)
55
	}
56
	return nil
57
}
58
59
func (c *Cli) lintStdin(lint *linter.Linter, reporter *linter.Reporter, format string) error {
60
	src, err := readStdin()
61
	if err != nil {
62
		return err
63
	}
64
	loader := journal.NewLoader()
65
	rj := loader.ResolveBytes("stdin", src)
66
	reporter.Collect(lint.Run(analyzer.Build(rj)))
67
68
	if err := reporter.Flush(format); err != nil {
69
		return fmt.Errorf("flushing report: %w", err)
70
	}
71
	if reporter.HasIssues() {
72
		return cli.Exit("", 1)
73
	}
74
	return nil
75
}
76
77
func parsePathStyle(s string) linter.PathStyle {
78
	switch strings.ToLower(s) {
79
	case "basename":
80
		return linter.PathBasename
81
	case "absolute":
82
		return linter.PathAbsolute
83
	default:
84
		return linter.PathRelative
85
	}
86
}