Files
PgTidy/cmd/pgtidy/fmt.go
T
Hein 04711cf7b2
CI / Test (push) Successful in 28s
CI / Build (push) Successful in 25s
fix(cmd): handle errors and improve output formatting
* update error handling in various commands to use blank identifier
* enhance output formatting for better readability
* add golangci-lint to Makefile for linting checks
2026-07-01 12:53:25 +02:00

120 lines
2.5 KiB
Go

package main
import (
"fmt"
"io"
"os"
"git.warky.dev/wdevs/pgtidy/pkg/config"
"git.warky.dev/wdevs/pgtidy/pkg/format"
"git.warky.dev/wdevs/pgtidy/pkg/parser"
)
// cmdFmt implements `pgtidy fmt`. It follows the gofmt model: with no flags it
// prints the formatted result to stdout; -w rewrites in place; -l lists files
// that differ; --check exits non-zero if any input is unformatted; -d prints a
// unified diff for each file that would change.
func cmdFmt(args []string, stdin io.Reader, stdout, stderr io.Writer) int {
var (
write bool
list bool
check bool
diff bool
files []string
)
for _, a := range args {
switch a {
case "-w", "--write":
write = true
case "-l", "--list":
list = true
case "--check":
check = true
case "-d", "--diff":
diff = true
case "-h", "--help":
usage(stdout)
return 0
default:
if len(a) > 1 && a[0] == '-' {
_, _ = fmt.Fprintf(stderr, "pgtidy fmt: unknown flag %q\n", a)
return 2
}
files = append(files, a)
}
}
// Discover config: walk up from the working directory.
wd, err := os.Getwd()
if err != nil {
wd = "."
}
st, err := config.Load(wd)
if err != nil {
_, _ = fmt.Fprintf(stderr, "%v\n", err)
return 2
}
// stdin → stdout when no files are given.
if len(files) == 0 {
src, err := io.ReadAll(stdin)
if err != nil {
_, _ = fmt.Fprintf(stderr, "pgtidy: reading stdin: %v\n", err)
return 2
}
out := format.File(parser.Parse(string(src)), st)
switch {
case check:
if out != string(src) {
return 1
}
case diff:
_, _ = io.WriteString(stdout, unifiedDiff(string(src), out, "stdin"))
default:
_, _ = io.WriteString(stdout, out)
}
return 0
}
exit := 0
anyDiff := false
for _, path := range files {
src, err := os.ReadFile(path)
if err != nil {
_, _ = fmt.Fprintf(stderr, "pgtidy: %v\n", err)
exit = 2
continue
}
out := format.File(parser.Parse(string(src)), st)
changed := out != string(src)
if changed {
anyDiff = true
}
switch {
case write:
if changed {
if err := os.WriteFile(path, []byte(out), 0o644); err != nil {
_, _ = fmt.Fprintf(stderr, "pgtidy: writing %s: %v\n", path, err)
exit = 2
}
}
case list:
if changed {
_, _ = fmt.Fprintln(stdout, path)
}
case diff:
if changed {
_, _ = io.WriteString(stdout, unifiedDiff(string(src), out, path))
}
case check:
// handled after loop via anyDiff
default:
_, _ = io.WriteString(stdout, out)
}
}
if check && anyDiff && exit == 0 {
return 1
}
return exit
}