refactor: replace os.* and fmt.Errorf with go-io/go-log conventions

Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
Snider 2026-03-16 19:44:45 +00:00
parent b0bb2de141
commit a36f835fe0
5 changed files with 47 additions and 38 deletions

View file

@ -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...)
}

View file

@ -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.

View file

@ -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
}

View file

@ -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 == "" {

View file

@ -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 {