From a36f835fe03e0fc9834c9b0dace7cf0bb4652829 Mon Sep 17 00:00:00 2001 From: Snider Date: Mon, 16 Mar 2026 19:44:45 +0000 Subject: [PATCH] refactor: replace os.* and fmt.Errorf with go-io/go-log conventions Co-Authored-By: Virgil --- pkg/lint/catalog.go | 23 ++++++++++++----------- pkg/lint/complexity.go | 18 ++++++++++-------- pkg/lint/coverage.go | 18 ++++++++++-------- pkg/lint/scanner.go | 17 ++++++++++------- pkg/php/security.go | 9 +++++---- 5 files changed, 47 insertions(+), 38 deletions(-) diff --git a/pkg/lint/catalog.go b/pkg/lint/catalog.go index bef4898..1f09638 100644 --- a/pkg/lint/catalog.go +++ b/pkg/lint/catalog.go @@ -1,12 +1,13 @@ package lint import ( - "fmt" "io/fs" - "os" "path/filepath" "slices" "strings" + + coreio "forge.lthn.ai/core/go-io" + coreerr "forge.lthn.ai/core/go-log" ) // severityOrder maps severity names to numeric ranks for threshold comparison. @@ -25,9 +26,9 @@ type Catalog struct { // LoadDir reads all .yaml files from the given directory and returns a Catalog. func LoadDir(dir string) (*Catalog, error) { - entries, err := os.ReadDir(dir) + entries, err := coreio.Local.List(dir) if err != nil { - return nil, fmt.Errorf("loading catalog from %s: %w", dir, err) + return nil, coreerr.E("Catalog.LoadDir", "loading catalog from "+dir, err) } var rules []Rule @@ -35,13 +36,13 @@ func LoadDir(dir string) (*Catalog, error) { if entry.IsDir() || !strings.HasSuffix(entry.Name(), ".yaml") { continue } - data, err := os.ReadFile(filepath.Join(dir, entry.Name())) + raw, err := coreio.Local.Read(filepath.Join(dir, entry.Name())) if err != nil { - return nil, fmt.Errorf("reading %s: %w", entry.Name(), err) + return nil, coreerr.E("Catalog.LoadDir", "reading "+entry.Name(), err) } - parsed, err := ParseRules(data) + parsed, err := ParseRules([]byte(raw)) if err != nil { - return nil, fmt.Errorf("parsing %s: %w", entry.Name(), err) + return nil, coreerr.E("Catalog.LoadDir", "parsing "+entry.Name(), err) } rules = append(rules, parsed...) } @@ -53,7 +54,7 @@ func LoadDir(dir string) (*Catalog, error) { func LoadFS(fsys fs.FS, dir string) (*Catalog, error) { entries, err := fs.ReadDir(fsys, dir) if err != nil { - return nil, fmt.Errorf("loading catalog from embedded %s: %w", dir, err) + return nil, coreerr.E("Catalog.LoadFS", "loading catalog from embedded "+dir, err) } var rules []Rule @@ -63,11 +64,11 @@ func LoadFS(fsys fs.FS, dir string) (*Catalog, error) { } data, err := fs.ReadFile(fsys, dir+"/"+entry.Name()) if err != nil { - return nil, fmt.Errorf("reading embedded %s: %w", entry.Name(), err) + return nil, coreerr.E("Catalog.LoadFS", "reading embedded "+entry.Name(), err) } parsed, err := ParseRules(data) if err != nil { - return nil, fmt.Errorf("parsing embedded %s: %w", entry.Name(), err) + return nil, coreerr.E("Catalog.LoadFS", "parsing embedded "+entry.Name(), err) } rules = append(rules, parsed...) } diff --git a/pkg/lint/complexity.go b/pkg/lint/complexity.go index c545424..666d477 100644 --- a/pkg/lint/complexity.go +++ b/pkg/lint/complexity.go @@ -1,13 +1,15 @@ package lint import ( - "fmt" "go/ast" "go/parser" "go/token" "os" "path/filepath" "strings" + + coreio "forge.lthn.ai/core/go-io" + coreerr "forge.lthn.ai/core/go-log" ) // ComplexityConfig controls cyclomatic complexity analysis. @@ -45,9 +47,9 @@ func AnalyseComplexity(cfg ComplexityConfig) ([]ComplexityResult, error) { var results []ComplexityResult - info, err := os.Stat(cfg.Path) + info, err := coreio.Local.Stat(cfg.Path) if err != nil { - return nil, fmt.Errorf("stat %s: %w", cfg.Path, err) + return nil, coreerr.E("AnalyseComplexity", "stat "+cfg.Path, err) } if !info.IsDir() { @@ -81,7 +83,7 @@ func AnalyseComplexity(cfg ComplexityConfig) ([]ComplexityResult, error) { return nil }) if err != nil { - return nil, fmt.Errorf("walk %s: %w", cfg.Path, err) + return nil, coreerr.E("AnalyseComplexity", "walk "+cfg.Path, err) } return results, nil @@ -97,7 +99,7 @@ func AnalyseComplexitySource(src string, filename string, threshold int) ([]Comp fset := token.NewFileSet() f, err := parser.ParseFile(fset, filename, src, parser.ParseComments) if err != nil { - return nil, fmt.Errorf("parse %s: %w", filename, err) + return nil, coreerr.E("AnalyseComplexitySource", "parse "+filename, err) } var results []ComplexityResult @@ -130,11 +132,11 @@ func AnalyseComplexitySource(src string, filename string, threshold int) ([]Comp // analyseFile parses a single Go file and returns functions exceeding the threshold. func analyseFile(path string, threshold int) ([]ComplexityResult, error) { - src, err := os.ReadFile(path) + src, err := coreio.Local.Read(path) if err != nil { - return nil, fmt.Errorf("read %s: %w", path, err) + return nil, coreerr.E("analyseFile", "read "+path, err) } - return AnalyseComplexitySource(string(src), path, threshold) + return AnalyseComplexitySource(src, path, threshold) } // calculateComplexity computes the cyclomatic complexity of a function. diff --git a/pkg/lint/coverage.go b/pkg/lint/coverage.go index 61b7aa8..02940b5 100644 --- a/pkg/lint/coverage.go +++ b/pkg/lint/coverage.go @@ -3,13 +3,15 @@ package lint import ( "bufio" "encoding/json" - "fmt" "math" "os" "regexp" "strconv" "strings" "time" + + coreio "forge.lthn.ai/core/go-io" + coreerr "forge.lthn.ai/core/go-log" ) // CoverageSnapshot represents a point-in-time coverage measurement. @@ -51,32 +53,32 @@ func NewCoverageStore(path string) *CoverageStore { func (s *CoverageStore) Append(snap CoverageSnapshot) error { snapshots, err := s.Load() if err != nil && !os.IsNotExist(err) { - return fmt.Errorf("load snapshots: %w", err) + return coreerr.E("CoverageStore.Append", "load snapshots", err) } snapshots = append(snapshots, snap) data, err := json.MarshalIndent(snapshots, "", " ") if err != nil { - return fmt.Errorf("marshal snapshots: %w", err) + return coreerr.E("CoverageStore.Append", "marshal snapshots", err) } - if err := os.WriteFile(s.Path, data, 0644); err != nil { - return fmt.Errorf("write %s: %w", s.Path, err) + if err := coreio.Local.Write(s.Path, string(data)); err != nil { + return coreerr.E("CoverageStore.Append", "write "+s.Path, err) } return nil } // Load reads all snapshots from the store. func (s *CoverageStore) Load() ([]CoverageSnapshot, error) { - data, err := os.ReadFile(s.Path) + raw, err := coreio.Local.Read(s.Path) if err != nil { return nil, err } var snapshots []CoverageSnapshot - if err := json.Unmarshal(data, &snapshots); err != nil { - return nil, fmt.Errorf("parse %s: %w", s.Path, err) + if err := json.Unmarshal([]byte(raw), &snapshots); err != nil { + return nil, coreerr.E("CoverageStore.Load", "parse "+s.Path, err) } return snapshots, nil } diff --git a/pkg/lint/scanner.go b/pkg/lint/scanner.go index 49663e0..67f62e8 100644 --- a/pkg/lint/scanner.go +++ b/pkg/lint/scanner.go @@ -1,12 +1,13 @@ package lint import ( - "fmt" "io/fs" - "os" "path/filepath" "slices" "strings" + + coreio "forge.lthn.ai/core/go-io" + coreerr "forge.lthn.ai/core/go-log" ) // extensionMap maps file extensions to language identifiers. @@ -94,10 +95,11 @@ func (s *Scanner) ScanDir(root string) ([]Finding, error) { return nil } - content, err := os.ReadFile(path) + raw, err := coreio.Local.Read(path) if err != nil { - return fmt.Errorf("reading %s: %w", path, err) + return coreerr.E("Scanner.ScanDir", "reading "+path, err) } + content := []byte(raw) // Build a matcher scoped to this file's language. m, err := NewMatcher(langRules) @@ -117,7 +119,7 @@ func (s *Scanner) ScanDir(root string) ([]Finding, error) { }) if err != nil { - return nil, fmt.Errorf("scanning %s: %w", root, err) + return nil, coreerr.E("Scanner.ScanDir", "scanning "+root, err) } return findings, nil @@ -125,10 +127,11 @@ func (s *Scanner) ScanDir(root string) ([]Finding, error) { // ScanFile scans a single file against all rules. func (s *Scanner) ScanFile(path string) ([]Finding, error) { - content, err := os.ReadFile(path) + raw, err := coreio.Local.Read(path) if err != nil { - return nil, fmt.Errorf("reading %s: %w", path, err) + return nil, coreerr.E("Scanner.ScanFile", "reading "+path, err) } + content := []byte(raw) lang := DetectLanguage(filepath.Base(path)) if lang == "" { diff --git a/pkg/php/security.go b/pkg/php/security.go index 6964cb1..bb60d34 100644 --- a/pkg/php/security.go +++ b/pkg/php/security.go @@ -6,6 +6,9 @@ import ( "os" "path/filepath" "strings" + + coreio "forge.lthn.ai/core/go-io" + coreerr "forge.lthn.ai/core/go-log" ) // SecurityOptions configures security scanning. @@ -58,7 +61,7 @@ func RunSecurityChecks(ctx context.Context, opts SecurityOptions) (*SecurityResu if opts.Dir == "" { cwd, err := os.Getwd() if err != nil { - return nil, fmt.Errorf("get working directory: %w", err) + return nil, coreerr.E("RunSecurityChecks", "get working directory", err) } opts.Dir = cwd } @@ -116,12 +119,10 @@ func runEnvSecurityChecks(dir string) []SecurityCheck { var checks []SecurityCheck envPath := filepath.Join(dir, ".env") - envBytes, err := os.ReadFile(envPath) + envContent, err := coreio.Local.Read(envPath) if err != nil { return checks } - - envContent := string(envBytes) envLines := strings.Split(envContent, "\n") envMap := make(map[string]string) for _, line := range envLines {