diff options
| author | Fuwn <[email protected]> | 2026-02-10 10:58:50 +0000 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2026-02-10 10:58:50 +0000 |
| commit | 5b0be377ff7731bf4e5402afe14df2121031ed90 (patch) | |
| tree | 06b79c9a432ff23d576d0a9f4ef3955ee9896c6a /scanner.go | |
| download | deppa-5b0be377ff7731bf4e5402afe14df2121031ed90.tar.xz deppa-5b0be377ff7731bf4e5402afe14df2121031ed90.zip | |
feat: Initial commit
Diffstat (limited to 'scanner.go')
| -rw-r--r-- | scanner.go | 133 |
1 files changed, 133 insertions, 0 deletions
diff --git a/scanner.go b/scanner.go new file mode 100644 index 0000000..f9d3ff4 --- /dev/null +++ b/scanner.go @@ -0,0 +1,133 @@ +package main + +import ( + "io/fs" + "os" + "path/filepath" + "runtime" + "sync" +) + +var knownDependencyDirectories = map[string]bool{ + "node_modules": true, + "target": true, + ".next": true, + ".nuxt": true, + "__pycache__": true, + ".venv": true, + "venv": true, + ".gradle": true, + "Pods": true, + "zig-cache": true, + "zig-out": true, + "_build": true, + ".dart_tool": true, +} +var ignoredDirectories = map[string]bool{ + ".git": true, + ".hg": true, + ".svn": true, +} + +type DependencyDirectory struct { + Path string + RelativePath string + SizeBytes int64 + DirectoryType string +} + +func scanForDependencies(rootPath string) ([]DependencyDirectory, error) { + var foundDirectories []DependencyDirectory + + walkError := filepath.WalkDir(rootPath, func(currentPath string, entry fs.DirEntry, accessError error) error { + if accessError != nil { + return filepath.SkipDir + } + + if !entry.IsDir() { + return nil + } + + if ignoredDirectories[entry.Name()] { + return filepath.SkipDir + } + + if knownDependencyDirectories[entry.Name()] { + relativePath, _ := filepath.Rel(rootPath, currentPath) + foundDirectories = append(foundDirectories, DependencyDirectory{ + Path: currentPath, + RelativePath: relativePath, + DirectoryType: entry.Name(), + }) + + return filepath.SkipDir + } + + return nil + }) + + if walkError != nil { + return nil, walkError + } + + var waitGroup sync.WaitGroup + + semaphore := make(chan struct{}, runtime.NumCPU()) + + for directoryIndex := range foundDirectories { + waitGroup.Add(1) + + go func(targetIndex int) { + defer waitGroup.Done() + + semaphore <- struct{}{} + + defer func() { <-semaphore }() + + foundDirectories[targetIndex].SizeBytes = calculateDirectorySize(foundDirectories[targetIndex].Path) + }(directoryIndex) + } + + waitGroup.Wait() + + return foundDirectories, nil +} + +func calculateDirectorySize(directoryPath string) int64 { + var totalSize int64 + + _ = filepath.WalkDir(directoryPath, func(_ string, entry fs.DirEntry, walkError error) error { + if walkError != nil || entry.IsDir() { + return nil + } + + fileInformation, informationError := entry.Info() + + if informationError == nil { + totalSize += fileInformation.Size() + } + + return nil + }) + + return totalSize +} + +func deleteDependencies(dependencies []DependencyDirectory, selected map[int]bool) (int64, int) { + var freedBytes int64 + var deletedCount int + + for dependencyIndex, dependency := range dependencies { + if !selected[dependencyIndex] { + continue + } + + if removeError := os.RemoveAll(dependency.Path); removeError == nil { + freedBytes += dependency.SizeBytes + + deletedCount++ + } + } + + return freedBytes, deletedCount +} |