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:
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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
1
mole
@@ -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"
|
||||||
|
|||||||
Reference in New Issue
Block a user