processor/result.go GO 138 lines View on github.com → Search inside
1// SPDX-License-Identifier: MIT23package processor45import (6	"fmt"7	"os"8	"path/filepath"9	"regexp"10	"runtime"11	"strings"1213	"github.com/boyter/gocodewalker"14)1516// ProcessResult runs the same pipeline as Process but returns structured results17// instead of formatting to stdout. Useful for programmatic consumers like MCP servers.18func ProcessResult() ([]LanguageSummary, error) {19	ProcessConstants()20	processFlags()21	cleanVisitedPaths()2223	if len(DirFilePaths) == 0 {24		DirFilePaths = append(DirFilePaths, ".")25	}2627	filePaths := []string{}28	dirPaths := []string{}2930	for _, f := range DirFilePaths {31		fpath := filepath.Clean(f)3233		s, err := os.Stat(fpath)34		if err != nil {35			return nil, fmt.Errorf("file or directory could not be read: %s", fpath)36		}3738		if s.IsDir() {39			dirPaths = append(dirPaths, fpath)40		} else {41			filePaths = append(filePaths, fpath)42		}43	}4445	SortBy = strings.ToLower(SortBy)46	ctx := processorContext{remap: newRemapConfig(RemapAll, RemapUnknown)}4748	printDebugF("NumCPU: %d", runtime.NumCPU())49	printDebugF("SortBy: %s", SortBy)50	printDebugF("PathDenyList: %v", PathDenyList)5152	potentialFilesQueue := make(chan *gocodewalker.File, FileListQueueSize)53	fileListQueue := make(chan *FileJob, FileListQueueSize)54	fileSummaryJobQueue := make(chan *FileJob, FileSummaryJobQueueSize)5556	fileWalker := gocodewalker.NewParallelFileWalker(dirPaths, potentialFilesQueue)57	fileWalker.SetErrorHandler(func(e error) bool {58		printError(e.Error())59		return true60	})61	fileWalker.IgnoreGitIgnore = GitIgnore62	fileWalker.IgnoreIgnoreFile = Ignore63	fileWalker.IgnoreGitModules = GitModuleIgnore64	fileWalker.IncludeHidden = true65	fileWalker.ExcludeDirectory = PathDenyList66	fileWalker.SetConcurrency(DirectoryWalkerJobWorkers)6768	if !SccIgnore {69		fileWalker.CustomIgnore = []string{".sccignore"}70	}7172	var excludePathRegexes []*regexp.Regexp73	for _, exclude := range Exclude {74		regexpResult, err := regexp.Compile(exclude)75		if err == nil {76			fileWalker.ExcludeFilenameRegex = append(fileWalker.ExcludeFilenameRegex, regexpResult)77			fileWalker.ExcludeDirectoryRegex = append(fileWalker.ExcludeDirectoryRegex, regexpResult)78			excludePathRegexes = append(excludePathRegexes, regexpResult)79		} else {80			printError(err.Error())81		}82	}8384	go func() {85		err := fileWalker.Start()86		if err != nil {87			printError(err.Error())88		}89	}()9091	go func() {92		for _, f := range filePaths {93			fileInfo, err := os.Lstat(f)94			if err != nil {95				continue96			}9798			fileJob := newFileJob(f, f, fileInfo)99			if fileJob != nil {100				fileListQueue <- fileJob101			}102		}103104		for fi := range potentialFilesQueue {105			shouldExclude := false106			for _, re := range excludePathRegexes {107				if re.MatchString(fi.Location) {108					shouldExclude = true109					break110				}111			}112			if shouldExclude {113				continue114			}115116			fileInfo, err := os.Lstat(fi.Location)117			if err != nil {118				continue119			}120121			if !fileInfo.IsDir() {122				fileJob := newFileJob(fi.Location, fi.Filename, fileInfo)123				if fileJob != nil {124					fileListQueue <- fileJob125				}126			}127		}128		close(fileListQueue)129	}()130131	go ctx.fileProcessorWorker(fileListQueue, fileSummaryJobQueue)132133	language := aggregateLanguageSummary(fileSummaryJobQueue)134	language = sortLanguageSummary(language)135136	return language, nil137}

Code quality findings 7

Goroutine without waitgroup or channel; risks resource leaks or race conditions
warning correctness goroutine-without-sync
go func() {
Ensure errors are handled or logged
warning correctness unhandled-error
if err != nil {
Multiple appends without pre-allocation; use make() with capacity when size is known
info performance append-without-prealloc
DirFilePaths = append(DirFilePaths, ".")
Multiple appends without pre-allocation; use make() with capacity when size is known
info performance append-without-prealloc
dirPaths = append(dirPaths, fpath)
Multiple appends without pre-allocation; use make() with capacity when size is known
info performance append-without-prealloc
fileWalker.ExcludeFilenameRegex = append(fileWalker.ExcludeFilenameRegex, regexpResult)
Multiple appends without pre-allocation; use make() with capacity when size is known
info performance append-without-prealloc
fileWalker.ExcludeDirectoryRegex = append(fileWalker.ExcludeDirectoryRegex, regexpResult)
Multiple appends without pre-allocation; use make() with capacity when size is known
info performance append-without-prealloc
excludePathRegexes = append(excludePathRegexes, regexpResult)

Get this view in your editor

Same data, no extra tab — call code_get_file + code_get_findings over MCP from Claude/Cursor/Copilot.