all repos

clerk @ ecc31e9

missing tooling for ledger/hledger

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

Oleksandr Smirnov Oleksandr Smirnov
olexsmir@gmail.com
implement basic linter, 1 month ago
1
package linter
2
3
import (
4
	"encoding/json"
5
	"fmt"
6
	"io"
7
	"os"
8
	"path/filepath"
9
)
10
11
// PathStyle controls how file paths are shown in output.
12
type PathStyle int
13
14
const (
15
	PathBasename PathStyle = iota // just the filename (e.g. "entry.journal")
16
	PathAbsolute                  // full absolute path
17
	PathRelative                  // relative to current directory
18
)
19
20
// Fprint writes finds in text format: file:line:col code: message.
21
func Fprint(w io.Writer, style PathStyle, finds []Find) {
22
	for _, find := range finds {
23
		fmt.Fprintf(w, "%s:%d:%d: %s: %s\n",
24
			formatPath(style, find.Span.Start.File),
25
			find.Span.Start.Line, find.Span.Start.Col,
26
			find.Code, find.Message)
27
	}
28
}
29
30
type FindJSON struct {
31
	Message  string `json:"message"`
32
	Severity string `json:"severity"`
33
	Code     string `json:"code"`
34
	File     string `json:"file"`
35
	Line     int    `json:"line"`
36
	Column   int    `json:"column"`
37
}
38
39
// FprintJSON writes finds as [FindJSON] array.
40
func FprintJSON(w io.Writer, style PathStyle, finds []Find) error {
41
	jsonFinds := make([]FindJSON, len(finds))
42
	for i, find := range finds {
43
		jsonFinds[i] = FindJSON{
44
			Message:  find.Message,
45
			Severity: find.Severity.String(),
46
			Code:     string(find.Code),
47
			File:     formatPath(style, find.Span.Start.File),
48
			Line:     find.Span.Start.Line,
49
			Column:   find.Span.Start.Col,
50
		}
51
	}
52
	return json.NewEncoder(w).Encode(jsonFinds)
53
}
54
55
func formatPath(style PathStyle, p string) string {
56
	switch style {
57
	case PathBasename:
58
		return filepath.Base(p)
59
	case PathAbsolute:
60
		return p
61
	case PathRelative:
62
		wd, err := os.Getwd()
63
		if err == nil {
64
			if rel, err := filepath.Rel(wd, p); err == nil {
65
				return rel
66
			}
67
		}
68
		return p
69
	default:
70
		panic("impossible PathStyle value")
71
	}
72
}