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 }