Files
kandev/apps/backend/cmd/sqlguard/main.go
T
2026-09-07 19:28:31 +01:00

84 lines
2.0 KiB
Go

package main
import (
"errors"
"flag"
"fmt"
"io/fs"
"os"
"path/filepath"
"sort"
"strings"
"github.com/kandev/kandev/internal/db/sqlguard"
)
func main() {
if err := run(os.Args[1:]); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
func run(args []string) error {
flags := flag.NewFlagSet("sqlguard", flag.ContinueOnError)
exemptionsPath := flags.String("exemptions", "internal/db/sqlguard/exemptions.json", "exact exemption registry")
if err := flags.Parse(args); err != nil {
return err
}
paths := flags.Args()
if len(paths) == 0 {
return errors.New("usage: sqlguard [-exemptions path] file-or-directory")
}
exemptions, err := sqlguard.LoadExemptions(*exemptionsPath)
if err != nil {
return err
}
files, err := goFiles(paths)
if err != nil {
return err
}
findings, err := sqlguard.CheckFiles(files, exemptions)
if err != nil {
return err
}
for _, finding := range findings {
fmt.Printf("%s:%d:%d: %s [%s] (%s)\n", finding.File, finding.Line, finding.Column, finding.Message, finding.Rule, finding.Symbol)
}
if len(findings) > 0 {
return fmt.Errorf("sqlguard found %d violation(s)", len(findings))
}
return nil
}
func goFiles(paths []string) ([]string, error) {
files := make([]string, 0)
for _, path := range paths {
info, err := os.Stat(path)
if err != nil {
return nil, fmt.Errorf("stat %s: %w", path, err)
}
if !info.IsDir() {
if filepath.Ext(path) == ".go" && !strings.HasSuffix(path, "_test.go") {
files = append(files, filepath.ToSlash(path))
}
continue
}
err = filepath.WalkDir(path, func(candidate string, entry fs.DirEntry, walkErr error) error {
if walkErr != nil {
return walkErr
}
if entry.IsDir() || filepath.Ext(candidate) != ".go" || strings.HasSuffix(candidate, "_test.go") {
return nil
}
files = append(files, filepath.ToSlash(candidate))
return nil
})
if err != nil {
return nil, fmt.Errorf("walk %s: %w", path, err)
}
}
sort.Strings(files)
return files, nil
}