932c83dbad
* Implemented `-d`/`--diff` flag to print unified diffs. * Added `unifiedDiff` function for generating diffs. * Config discovery now merges fields from `.pgtidy.yaml`.
120 lines
2.4 KiB
Go
120 lines
2.4 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
|
|
"github.com/hein/pgtidy/pkg/config"
|
|
"github.com/hein/pgtidy/pkg/format"
|
|
"github.com/hein/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
|
|
}
|