check-safety/pathutil.go
Alex Dunmow c4d01de82c feat: concise output + diff-scoped any check
Reporter is now a collector: checks declare a verdict (OK/Skip/Warn/Fail/
Fatal) plus findings, and a single central render() prints output. Default
output is silent on pass/skip — only FAIL/WARN/ERR checks print, followed by
one tally line, so a clean run is two lines. --verbose restores full per-check
output. All ~30 checks were converted to this API; orphaned guidance/label
helpers (printPerTargetOKLines, per-check *Help blocks, colors_format.go) were
removed.

The any-usage check (2e) now defaults to only the unstaged working-tree diff
(changed lines), via a new per-repo git-diff index in changedlines.go; --all-any
restores the full scan. Not-a-git-repo / no-diff warns on nothing.

Golden fixtures regenerated; integration tests updated to the new format; added
unit tests for the diff index.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-04 01:16:56 +08:00

114 lines
2.1 KiB
Go

package main
import (
"os"
"path/filepath"
"slices"
"strings"
)
func expandPath(path string) (string, error) {
if path == "~" || strings.HasPrefix(path, "~/") {
home, err := os.UserHomeDir()
if err != nil {
return "", err
}
if path == "~" {
return home, nil
}
return filepath.Join(home, strings.TrimPrefix(path, "~/")), nil
}
return path, nil
}
func dirLooksLikeFrontendSource(path string) bool {
info, err := os.Stat(path)
if err != nil || !info.IsDir() {
return false
}
entries, err := os.ReadDir(path)
if err != nil {
return false
}
for _, entry := range entries {
if entry.IsDir() {
continue
}
name := entry.Name()
if strings.HasSuffix(name, ".ts") || strings.HasSuffix(name, ".tsx") || strings.HasSuffix(name, ".js") || strings.HasSuffix(name, ".jsx") {
return true
}
}
return false
}
func dirExists(path string) bool {
info, err := os.Stat(path)
return err == nil && info.IsDir()
}
func samePath(a, b string) bool {
if a == "" || b == "" {
return false
}
absA, err := filepath.Abs(a)
if err != nil {
return false
}
absB, err := filepath.Abs(b)
if err != nil {
return false
}
return absA == absB
}
func normalizeDisplayLabel(label string) string {
if label == "." {
return ""
}
return label
}
func fileExists(path string) bool {
info, err := os.Stat(path)
return err == nil && !info.IsDir()
}
func prefixDisplayPath(prefix, path string) string {
if prefix == "" || prefix == "." {
return path
}
if path == "" {
return prefix
}
return prefix + "/" + filepath.ToSlash(path)
}
func shortPluginLabel(path string) string {
cleaned := filepath.Clean(path)
base := filepath.Base(cleaned)
if base == "." || base == string(filepath.Separator) || base == "" {
return path
}
return base
}
func isPluginModuleRoot(root string) bool {
modulePath, err := readModulePath(root)
if err != nil {
return fileExists(filepath.Join(root, "plugin.mod"))
}
return strings.Contains(modulePath, "/internal/plugins/") || fileExists(filepath.Join(root, "plugin.mod"))
}
func containsString(values []string, target string) bool {
return slices.Contains(values, target)
}