diff --git a/cmd/brief/enrich.go b/cmd/brief/enrich.go index dff7d33..3012ee3 100644 --- a/cmd/brief/enrich.go +++ b/cmd/brief/enrich.go @@ -116,29 +116,23 @@ func enrich(ctx context.Context, r *brief.Report, root string) *brief.Enrichment // Published packages purls := detectPublishedPURLs(root) if len(purls) > 0 { - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { enrichPublishedPackages(ctx, purls, info, &mu) - }() + }) } // Runtime EOL if r.Platforms != nil { - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { enrichEOL(ctx, r, info, &mu) - }() + }) } // Repo scorecard if r.Git != nil { - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { enrichScorecard(ctx, r, info, &mu) - }() + }) } wg.Wait() @@ -205,12 +199,10 @@ func goModulePURL(root string) string { if err != nil { return "" } - for _, line := range strings.Split(string(data), "\n") { + for line := range strings.SplitSeq(string(data), "\n") { line = strings.TrimSpace(line) - if strings.HasPrefix(line, "module ") { - mod := strings.TrimPrefix(line, "module ") - mod = strings.TrimSpace(mod) - return "pkg:golang/" + mod + if mod, ok := strings.CutPrefix(line, "module "); ok { + return "pkg:golang/" + strings.TrimSpace(mod) } } return "" @@ -249,7 +241,7 @@ func pythonPackagePURL(root string) string { // Try setup.cfg [metadata] name data, err = safeReadManifest(filepath.Join(root, "setup.cfg")) if err == nil { - for _, line := range strings.Split(string(data), "\n") { + for line := range strings.SplitSeq(string(data), "\n") { line = strings.TrimSpace(line) if strings.HasPrefix(line, "name") && strings.Contains(line, "=") { parts := strings.SplitN(line, "=", 2) //nolint:mnd // key=value split @@ -269,7 +261,7 @@ func gemPURL(root string) string { if len(matches) > 0 { data, err := safeReadManifest(matches[0]) if err == nil { - for _, line := range strings.Split(string(data), "\n") { + for line := range strings.SplitSeq(string(data), "\n") { line = strings.TrimSpace(line) // Match: spec.name = "foo" or s.name = "foo" if strings.Contains(line, ".name") && strings.Contains(line, "=") { diff --git a/cmd/brief/inspect.go b/cmd/brief/inspect.go index 79aea86..fb0e140 100644 --- a/cmd/brief/inspect.go +++ b/cmd/brief/inspect.go @@ -413,10 +413,7 @@ func readZIPDirectoryEnd(r io.ReaderAt, size int64) (zipDirectoryEnd, error) { if size < zipDirectoryEndLen { return zipDirectoryEnd{}, io.ErrUnexpectedEOF } - searchLen := int64(zipDirectorySearchLen + zipDirectoryEndLen) - if searchLen > size { - searchLen = size - } + searchLen := min(int64(zipDirectorySearchLen+zipDirectoryEndLen), size) buf := make([]byte, int(searchLen)) if _, err := r.ReadAt(buf, size-searchLen); err != nil && err != io.EOF { return zipDirectoryEnd{}, err diff --git a/cmd/brief/main.go b/cmd/brief/main.go index 82e0cd9..c663ba8 100644 --- a/cmd/brief/main.go +++ b/cmd/brief/main.go @@ -408,8 +408,7 @@ func schemaForStruct(t reflect.Type, defs map[string]any) map[string]any { func buildStructSchema(t reflect.Type, defs map[string]any) map[string]any { props := make(map[string]any) - for i := range t.NumField() { - f := t.Field(i) + for f := range t.Fields() { if !f.IsExported() { continue } diff --git a/cmd/brief/schema_test.go b/cmd/brief/schema_test.go index a76cae6..06aef42 100644 --- a/cmd/brief/schema_test.go +++ b/cmd/brief/schema_test.go @@ -18,8 +18,7 @@ func TestSchemaForType_CoversAllReportFields(t *testing.T) { // Every exported, JSON-tagged field on Report should appear in the schema. rt := reflect.TypeFor[brief.Report]() - for i := range rt.NumField() { - f := rt.Field(i) + for f := range rt.Fields() { if !f.IsExported() { continue } diff --git a/detect/detect.go b/detect/detect.go index 55ded06..ae76e37 100644 --- a/detect/detect.go +++ b/detect/detect.go @@ -238,10 +238,8 @@ func (e *Engine) shouldSkipDirPath(dirPath string) bool { if defaultSkipDirs[name] { return true } - for _, d := range e.SkipDirs { - if name == d { - return true - } + if slices.Contains(e.SkipDirs, name) { + return true } if name == "deps" { if e.exactFileAt(filepath.Join(filepath.Dir(dirPath), "mix.exs")) { @@ -257,12 +255,7 @@ func (e *Engine) shouldIndexHiddenRoot(dirPath string) bool { if !indexedHiddenRootDirs[name] || !e.isAnalysisRootPath(filepath.Dir(dirPath)) { return false } - for _, dir := range e.SkipDirs { - if name == dir { - return false - } - } - return true + return !slices.Contains(e.SkipDirs, name) } func (e *Engine) exactFileAt(filePath string) bool { @@ -359,21 +352,15 @@ func (e *Engine) Run() (*brief.Report, error) { // Run slow detections concurrently. var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { report.Resources = e.detectResources() - }() - wg.Add(1) - go func() { - defer wg.Done() + }) + wg.Go(func() { report.Git = e.detectGit(abs) - }() - wg.Add(1) - go func() { - defer wg.Done() + }) + wg.Go(func() { report.Lines = e.detectLineCount(abs) - }() + }) wg.Wait() // Expose parsed dependencies (loadDeps was called lazily during tool matching) @@ -582,10 +569,8 @@ func (e *Engine) detectCategory(category string) []brief.Detection { // matchTool checks if a tool definition matches the project. // Returns the confidence level, or empty string if no match. func (e *Engine) matchTool(tool *kb.ToolDef) brief.Confidence { - for _, pattern := range tool.Detect.ExcludeFiles { - if e.exists(pattern) { - return "" - } + if slices.ContainsFunc(tool.Detect.ExcludeFiles, e.exists) { + return "" } best := brief.Confidence("") @@ -608,11 +593,8 @@ func (e *Engine) matchTool(tool *kb.ToolDef) brief.Confidence { } } - for _, resource := range tool.Detect.YAMLResources { - if e.hasYAMLResource(resource) { - best = brief.ConfidenceHigh - break - } + if slices.ContainsFunc(tool.Detect.YAMLResources, e.hasYAMLResource) { + best = brief.ConfidenceHigh } if len(tool.Detect.Dependencies) > 0 || len(tool.Detect.DevDependencies) > 0 { @@ -667,12 +649,7 @@ func (e *Engine) exists(pattern string) bool { return e.globMatches(pattern, false) } - for _, candidate := range e.rootCandidates(pattern) { - if e.exactFileExists(candidate) { - return true - } - } - return false + return slices.ContainsFunc(e.rootCandidates(pattern), e.exactFileExists) } func (e *Engine) exactFileExists(file string) bool { @@ -1334,8 +1311,8 @@ func (e *Engine) addPnpmWorkspaceManifestsFrom(base string, add func(string)) { var includes []string var excludes []string for _, pattern := range root.Packages { - if strings.HasPrefix(pattern, "!") { - excludes = append(excludes, strings.TrimPrefix(pattern, "!")) + if after, ok := strings.CutPrefix(pattern, "!"); ok { + excludes = append(excludes, after) continue } includes = append(includes, pattern) @@ -1381,7 +1358,7 @@ func packageWorkspacePatterns(workspaces any) []string { func parseGoWorkUsePaths(content string) []string { var paths []string inUseBlock := false - for _, line := range strings.Split(content, "\n") { + for line := range strings.SplitSeq(content, "\n") { line = stripGoWorkComment(line) fields := strings.Fields(line) if len(fields) == 0 { @@ -1625,9 +1602,9 @@ func parseYAMLTasks(data []byte, sourceName string, cmd string) []brief.Script { // parseTargets extracts targets from files with "target:" syntax (Makefile, Justfile). func parseTargets(data []byte, sourceName string, cmd string) []brief.Script { var scripts []brief.Script - lines := strings.Split(string(data), "\n") + lines := strings.SplitSeq(string(data), "\n") - for _, line := range lines { + for line := range lines { line = strings.TrimSpace(line) if strings.HasPrefix(line, "#") || strings.HasPrefix(line, ".") { continue @@ -1711,7 +1688,7 @@ type styleCounts struct { func (sc *styleCounts) addFile(data []byte) { sc.sampled++ content := string(data) - for _, line := range strings.Split(content, "\n") { + for line := range strings.SplitSeq(content, "\n") { if len(line) == 0 { continue } @@ -2075,12 +2052,12 @@ func (e *Engine) parseSkill(rel string) brief.Skill { return skill } rest := bytes.TrimLeft(data[len(skillFrontmatterDelim):], "\r\n") - end := bytes.Index(rest, []byte("\n---")) - if end == -1 { + before, _, ok := bytes.Cut(rest, []byte("\n---")) + if !ok { return skill } var fm skillFrontmatter - if yaml.Unmarshal(rest[:end], &fm) == nil { + if yaml.Unmarshal(before, &fm) == nil { if fm.Name != "" { skill.Name = fm.Name } @@ -2267,19 +2244,15 @@ func (e *Engine) detectGit(absPath string) *brief.GitInfo { var wg sync.WaitGroup var mu sync.Mutex - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { if out, err := e.git(absPath, "branch", "--show-current"); err == nil { mu.Lock() info.Branch = strings.TrimSpace(string(out)) mu.Unlock() } - }() + }) - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { if out, err := e.git(absPath, "rev-parse", "--abbrev-ref", "origin/HEAD"); err == nil { ref := strings.TrimSpace(string(out)) if after, ok := strings.CutPrefix(ref, "origin/"); ok { @@ -2288,13 +2261,11 @@ func (e *Engine) detectGit(absPath string) *brief.GitInfo { mu.Unlock() } } - }() + }) - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { if out, err := e.git(absPath, "remote"); err == nil { - for _, name := range strings.Fields(string(out)) { + for name := range strings.FieldsSeq(string(out)) { if url, err := e.git(absPath, "remote", "get-url", name); err == nil { mu.Lock() info.Remotes[name] = redactURL(strings.TrimSpace(string(url))) @@ -2302,11 +2273,9 @@ func (e *Engine) detectGit(absPath string) *brief.GitInfo { } } } - }() + }) - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { if out, err := e.git(absPath, "rev-list", "--count", "HEAD"); err == nil { var count int if _, err := fmt.Sscanf(strings.TrimSpace(string(out)), "%d", &count); err == nil { @@ -2315,7 +2284,7 @@ func (e *Engine) detectGit(absPath string) *brief.GitInfo { mu.Unlock() } } - }() + }) wg.Wait() diff --git a/kb/kb.go b/kb/kb.go index 18b51a4..381cfc7 100644 --- a/kb/kb.go +++ b/kb/kb.go @@ -561,7 +561,7 @@ func validatePathPattern(pattern string) error { return fmt.Errorf("must stay within the project root") } doublestar := 0 - for _, segment := range strings.Split(trimmed, "/") { + for segment := range strings.SplitSeq(trimmed, "/") { if strings.Contains(segment, "**") { if segment != "**" { return fmt.Errorf("** must occupy a complete path segment")