fix FileSize to return correct disk usage recursively

This commit is contained in:
Anton Evangelatov 2021-01-19 14:43:19 +01:00
parent e9989d0e46
commit 16d07d3f18

View File

@ -2,7 +2,7 @@ package fsutil
import ( import (
"os" "os"
"syscall" "path/filepath"
"golang.org/x/xerrors" "golang.org/x/xerrors"
) )
@ -11,19 +11,24 @@ type SizeInfo struct {
OnDisk int64 OnDisk int64
} }
// FileSize returns bytes used by a file on disk // FileSize returns bytes used by a file or directory on disk
func FileSize(path string) (SizeInfo, error) { func FileSize(path string) (SizeInfo, error) {
var stat syscall.Stat_t var size int64
if err := syscall.Stat(path, &stat); err != nil { err := filepath.Walk(path, func(_ string, info os.FileInfo, err error) error {
if err == syscall.ENOENT { if err != nil {
return err
}
if !info.IsDir() {
size += info.Size()
}
return err
})
if err != nil {
if os.IsNotExist(err) {
return SizeInfo{}, os.ErrNotExist return SizeInfo{}, os.ErrNotExist
} }
return SizeInfo{}, xerrors.Errorf("stat: %w", err) return SizeInfo{}, xerrors.Errorf("filepath.Walk err: %w", err)
} }
// NOTE: stat.Blocks is in 512B blocks, NOT in stat.Blksize return SizeInfo{size}, nil
// See https://www.gnu.org/software/libc/manual/html_node/Attribute-Meanings.html
return SizeInfo{
int64(stat.Blocks) * 512, // nolint NOTE: int64 cast is needed on osx
}, nil
} }