1
0
mirror of https://github.com/tw93/Mole.git synced 2026-03-22 20:50:06 +00:00

fix: use Base-10 sizes and mdls logical size to match macOS Finder

- Switch bytes_to_human (shell) and humanizeBytes (Go) from Base-2
  (1024) to Base-10 (1000) to match Apple's storage calculation
  standard since Snow Leopard
- Add proper decimal rounding instead of truncation
- Use mdls kMDItemLogicalSize for .app bundles to avoid APFS clone
  file undercounting by du

Fixes #511
This commit is contained in:
tw93
2026-02-28 10:02:34 +08:00
parent 646ff72a96
commit 1be71edc9d
4 changed files with 36 additions and 20 deletions

View File

@@ -80,7 +80,7 @@ func humanizeBytes(size int64) string {
if size < 0 { if size < 0 {
return "0 B" return "0 B"
} }
const unit = 1024 const unit = 1000
if size < unit { if size < unit {
return fmt.Sprintf("%d B", size) return fmt.Sprintf("%d B", size)
} }
@@ -90,7 +90,7 @@ func humanizeBytes(size int64) string {
exp++ exp++
} }
value := float64(size) / float64(div) value := float64(size) / float64(div)
return fmt.Sprintf("%.1f %cB", value, "KMGTPE"[exp]) return fmt.Sprintf("%.1f %cB", value, "kMGTPE"[exp])
} }
func coloredProgressBar(value, maxValue int64, percent float64) string { func coloredProgressBar(value, maxValue int64, percent float64) string {

View File

@@ -63,15 +63,15 @@ func TestHumanizeBytes(t *testing.T) {
{-100, "0 B"}, {-100, "0 B"},
{0, "0 B"}, {0, "0 B"},
{512, "512 B"}, {512, "512 B"},
{1023, "1023 B"}, {999, "999 B"},
{1024, "1.0 KB"}, {1000, "1.0 kB"},
{1536, "1.5 KB"}, {1500, "1.5 kB"},
{10240, "10.0 KB"}, {10000, "10.0 kB"},
{1048576, "1.0 MB"}, {1000000, "1.0 MB"},
{1572864, "1.5 MB"}, {1500000, "1.5 MB"},
{1073741824, "1.0 GB"}, {1000000000, "1.0 GB"},
{1099511627776, "1.0 TB"}, {1000000000000, "1.0 TB"},
{1125899906842624, "1.0 PB"}, {1000000000000000, "1.0 PB"},
} }
for _, tt := range tests { for _, tt := range tests {

View File

@@ -451,6 +451,7 @@ ensure_user_file() {
# ============================================================================ # ============================================================================
# Convert bytes to human-readable format (e.g., 1.5GB) # Convert bytes to human-readable format (e.g., 1.5GB)
# macOS (since Snow Leopard) uses Base-10 calculation (1 KB = 1000 bytes)
bytes_to_human() { bytes_to_human() {
local bytes="$1" local bytes="$1"
[[ "$bytes" =~ ^[0-9]+$ ]] || { [[ "$bytes" =~ ^[0-9]+$ ]] || {
@@ -458,15 +459,17 @@ bytes_to_human() {
return 1 return 1
} }
# GB: >= 1073741824 bytes # GB: >= 1,000,000,000 bytes
if ((bytes >= 1073741824)); then if ((bytes >= 1000000000)); then
printf "%d.%02dGB\n" $((bytes / 1073741824)) $(((bytes % 1073741824) * 100 / 1073741824)) local scaled=$(( (bytes * 100 + 500000000) / 1000000000 ))
# MB: >= 1048576 bytes printf "%d.%02dGB\n" $((scaled / 100)) $((scaled % 100))
elif ((bytes >= 1048576)); then # MB: >= 1,000,000 bytes
printf "%d.%01dMB\n" $((bytes / 1048576)) $(((bytes % 1048576) * 10 / 1048576)) elif ((bytes >= 1000000)); then
# KB: >= 1024 bytes (round up) local scaled=$(( (bytes * 10 + 500000) / 1000000 ))
elif ((bytes >= 1024)); then printf "%d.%01dMB\n" $((scaled / 10)) $((scaled % 10))
printf "%dKB\n" $(((bytes + 512) / 1024)) # KB: >= 1,000 bytes (round up to nearest KB instead of decimal)
elif ((bytes >= 1000)); then
printf "%dKB\n" $(((bytes + 500) / 1000))
else else
printf "%dB\n" "$bytes" printf "%dB\n" "$bytes"
fi fi

View File

@@ -503,6 +503,19 @@ get_path_size_kb() {
echo "0" echo "0"
return return
} }
# For .app bundles, prefer mdls logical size as it matches Finder
# (APFS clone/sparse files make 'du' severely underreport apps like Xcode)
if [[ "$path" == *.app || "$path" == *.app/ ]]; then
local mdls_size
mdls_size=$(mdls -name kMDItemLogicalSize -raw "$path" 2> /dev/null || true)
if [[ "$mdls_size" =~ ^[0-9]+$ && "$mdls_size" -gt 0 ]]; then
# Return in KB
echo "$((mdls_size / 1024))"
return
fi
fi
local size local size
size=$(command du -skP "$path" 2> /dev/null | awk 'NR==1 {print $1; exit}' || true) size=$(command du -skP "$path" 2> /dev/null | awk 'NR==1 {print $1; exit}' || true)