1
0
mirror of https://github.com/tw93/Mole.git synced 2026-02-12 05:54:00 +00:00

feat: Exclude External Disks from Analyze (#428)

Created optional flag `--exclude-volumes` for `mo analyze` to consent the users to analyze the filesystem without taking in consideration attached Volumes.
Normal behaviour (with volumes included) is left untouched.
This commit is contained in:
Andrei Murariu
2026-02-10 09:28:33 +02:00
committed by GitHub
parent 9aa5a0a69d
commit 37bdc6edf7
4 changed files with 22 additions and 11 deletions

View File

@@ -68,6 +68,7 @@ mo optimize --dry-run # Preview optimization actions
mo optimize --debug # Run with detailed operation logs mo optimize --debug # Run with detailed operation logs
mo optimize --whitelist # Manage protected optimization rules mo optimize --whitelist # Manage protected optimization rules
mo purge --paths # Configure project scan directories mo purge --paths # Configure project scan directories
mo analyze --exclude-volumes # Skip external drives under /Volumes in overview
``` ```
## Tips ## Tips
@@ -149,6 +150,8 @@ Use `mo optimize --whitelist` to exclude specific optimizations.
### Disk Space Analyzer ### Disk Space Analyzer
Use `--exclude-volumes` to skip external drives under `/Volumes` in the overview (faster when many volumes are attached).
```bash ```bash
$ mo analyze $ mo analyze

View File

@@ -332,8 +332,8 @@ func removeOverviewSnapshot(path string) {
} }
// prefetchOverviewCache warms overview cache in background. // prefetchOverviewCache warms overview cache in background.
func prefetchOverviewCache(ctx context.Context) { func prefetchOverviewCache(ctx context.Context, excludeVolumes bool) {
entries := createOverviewEntries() entries := createOverviewEntries(excludeVolumes)
var needScan []string var needScan []string
for _, entry := range entries { for _, entry := range entries {

View File

@@ -4,6 +4,7 @@ package main
import ( import (
"context" "context"
"flag"
"fmt" "fmt"
"io/fs" "io/fs"
"os" "os"
@@ -122,6 +123,7 @@ type model struct {
largeMultiSelected map[string]bool // Track multi-selected large files by path (safer than index) largeMultiSelected map[string]bool // Track multi-selected large files by path (safer than index)
totalFiles int64 // Total files found in current/last scan totalFiles int64 // Total files found in current/last scan
lastTotalFiles int64 // Total files from previous scan (for progress bar) lastTotalFiles int64 // Total files from previous scan (for progress bar)
excludeVolumes bool // Skip /Volumes in overview (--exclude-volumes)
} }
func (m model) inOverviewMode() bool { func (m model) inOverviewMode() bool {
@@ -129,9 +131,13 @@ func (m model) inOverviewMode() bool {
} }
func main() { func main() {
fs := flag.NewFlagSet("analyze", flag.ContinueOnError)
excludeVolumes := fs.Bool("exclude-volumes", false, "exclude /Volumes (external drives) from overview")
_ = fs.Parse(os.Args[1:])
target := os.Getenv("MO_ANALYZE_PATH") target := os.Getenv("MO_ANALYZE_PATH")
if target == "" && len(os.Args) > 1 { if target == "" && fs.NArg() > 0 {
target = os.Args[1] target = fs.Arg(0)
} }
var abs string var abs string
@@ -153,16 +159,16 @@ func main() {
// Warm overview cache in background. // Warm overview cache in background.
prefetchCtx, prefetchCancel := context.WithTimeout(context.Background(), 30*time.Second) prefetchCtx, prefetchCancel := context.WithTimeout(context.Background(), 30*time.Second)
defer prefetchCancel() defer prefetchCancel()
go prefetchOverviewCache(prefetchCtx) go prefetchOverviewCache(prefetchCtx, *excludeVolumes)
p := tea.NewProgram(newModel(abs, isOverview), tea.WithAltScreen()) p := tea.NewProgram(newModel(abs, isOverview, *excludeVolumes), tea.WithAltScreen())
if _, err := p.Run(); err != nil { if _, err := p.Run(); err != nil {
fmt.Fprintf(os.Stderr, "analyzer error: %v\n", err) fmt.Fprintf(os.Stderr, "analyzer error: %v\n", err)
os.Exit(1) os.Exit(1)
} }
} }
func newModel(path string, isOverview bool) model { func newModel(path string, isOverview bool, excludeVolumes bool) model {
var filesScanned, dirsScanned, bytesScanned int64 var filesScanned, dirsScanned, bytesScanned int64
currentPath := &atomic.Value{} currentPath := &atomic.Value{}
currentPath.Store("") currentPath.Store("")
@@ -189,6 +195,7 @@ func newModel(path string, isOverview bool) model {
overviewScanningSet: make(map[string]bool), overviewScanningSet: make(map[string]bool),
multiSelected: make(map[string]bool), multiSelected: make(map[string]bool),
largeMultiSelected: make(map[string]bool), largeMultiSelected: make(map[string]bool),
excludeVolumes: excludeVolumes,
} }
if isOverview { if isOverview {
@@ -214,7 +221,7 @@ func newModel(path string, isOverview bool) model {
return m return m
} }
func createOverviewEntries() []dirEntry { func createOverviewEntries(excludeVolumes bool) []dirEntry {
home := os.Getenv("HOME") home := os.Getenv("HOME")
entries := []dirEntry{} entries := []dirEntry{}
@@ -233,8 +240,8 @@ func createOverviewEntries() []dirEntry {
dirEntry{Name: "System Library", Path: "/Library", IsDir: true, Size: -1}, dirEntry{Name: "System Library", Path: "/Library", IsDir: true, Size: -1},
) )
// Include Volumes only when real mounts exist. // Include Volumes only when real mounts exist and not excluded by --exclude-volumes.
if hasUsefulVolumeMounts("/Volumes") { if !excludeVolumes && hasUsefulVolumeMounts("/Volumes") {
entries = append(entries, dirEntry{Name: "Volumes", Path: "/Volumes", IsDir: true, Size: -1}) entries = append(entries, dirEntry{Name: "Volumes", Path: "/Volumes", IsDir: true, Size: -1})
} }
@@ -268,7 +275,7 @@ func hasUsefulVolumeMounts(path string) bool {
} }
func (m *model) hydrateOverviewEntries() { func (m *model) hydrateOverviewEntries() {
m.entries = createOverviewEntries() m.entries = createOverviewEntries(m.excludeVolumes)
if m.overviewSizeCache == nil { if m.overviewSizeCache == nil {
m.overviewSizeCache = make(map[string]int64) m.overviewSizeCache = make(map[string]int64)
} }

1
mole
View File

@@ -223,6 +223,7 @@ show_help() {
printf " %s%-28s%s %s\n" "$GREEN" "mo optimize --dry-run" "$NC" "Preview optimization" printf " %s%-28s%s %s\n" "$GREEN" "mo optimize --dry-run" "$NC" "Preview optimization"
printf " %s%-28s%s %s\n" "$GREEN" "mo optimize --whitelist" "$NC" "Manage protected items" printf " %s%-28s%s %s\n" "$GREEN" "mo optimize --whitelist" "$NC" "Manage protected items"
printf " %s%-28s%s %s\n" "$GREEN" "mo purge --paths" "$NC" "Configure scan directories" printf " %s%-28s%s %s\n" "$GREEN" "mo purge --paths" "$NC" "Configure scan directories"
printf " %s%-28s%s %s\n" "$GREEN" "mo analyze --exclude-volumes" "$NC" "Skip external drives in overview"
printf " %s%-28s%s %s\n" "$GREEN" "mo update --force" "$NC" "Force reinstall latest version" printf " %s%-28s%s %s\n" "$GREEN" "mo update --force" "$NC" "Force reinstall latest version"
echo echo
printf "%s%s%s\n" "$BLUE" "OPTIONS" "$NC" printf "%s%s%s\n" "$BLUE" "OPTIONS" "$NC"