Commit 05a2349
wdu/go.mod
@@ -0,0 +1,12 @@
+module wdu
+
+go 1.25.5
+
+require golang.org/x/sys v0.39.0
+
+require (
+ github.com/jedib0t/go-pretty/v6 v6.7.8 // indirect
+ github.com/mattn/go-runewidth v0.0.16 // indirect
+ github.com/rivo/uniseg v0.4.7 // indirect
+ golang.org/x/text v0.22.0 // indirect
+)
wdu/go.sum
@@ -0,0 +1,13 @@
+github.com/jedib0t/go-pretty v4.3.0+incompatible h1:CGs8AVhEKg/n9YbUenWmNStRW2PHJzaeDodcfvRAbIo=
+github.com/jedib0t/go-pretty v4.3.0+incompatible/go.mod h1:XemHduiw8R651AF9Pt4FwCTKeG3oo7hrHJAoznj9nag=
+github.com/jedib0t/go-pretty/v6 v6.7.8 h1:BVYrDy5DPBA3Qn9ICT+PokP9cvCv1KaHv2i+Hc8sr5o=
+github.com/jedib0t/go-pretty/v6 v6.7.8/go.mod h1:YwC5CE4fJ1HFUDeivSV1r//AmANFHyqczZk+U6BDALU=
+github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
+github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
+github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
+github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
+github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
+golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk=
+golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
+golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
+golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
wdu/main.go
@@ -0,0 +1,43 @@
+package main
+
+import (
+ "fmt"
+ "os"
+ "github.com/jedib0t/go-pretty/v6/table"
+ "golang.org/x/sys/unix"
+)
+
+func main() {
+ var stat unix.Statfs_t
+ mountPoint := "/"
+ err := unix.Statfs(mountPoint, &stat)
+ if err != nil {
+ if err != os.ErrPermission {
+ fmt.Printf("%s: %s", mountPoint, err)
+ }
+ stat = unix.Statfs_t{}
+ }
+
+ total := uint64(stat.Blocks) * uint64(stat.Bsize)
+ free := uint64(stat.Bavail) * uint64(stat.Bsize)
+ used := (uint64(stat.Blocks) - uint64(stat.Bfree)) * uint64(stat.Bsize)
+
+ fsType, ok := fsTypeMap[int64(stat.Type)]
+ if !ok {
+ fsType = "unknown"
+ }
+ details := DiskDetails{
+ Type: fsType,
+ Total: sizeToString(total),
+ Used: sizeToString(used),
+ Free: sizeToString(free),
+ }
+
+ tab := table.NewWriter()
+ headers := table.Row{"Mount", "Type", "Total", "Free", "Used"}
+ tab.AppendHeader(headers)
+ row := table.Row{mountPoint, details.Type, details.Total, details.Free, details.Used}
+ tab.AppendRow(row)
+ tab.SetStyle(table.StyleRounded)
+ fmt.Println(tab.Render())
+}
wdu/utils.go
@@ -0,0 +1,53 @@
+package main
+
+import "fmt"
+
+type DiskDetails struct {
+ Type, Total, Used, Free string
+}
+
+func sizeToString(size uint64) (str string) {
+ b := float64(size)
+
+ switch {
+ case size >= 1<<60:
+ str = fmt.Sprintf("%.1fE", b/(1<<60))
+ case size >= 1<<50:
+ str = fmt.Sprintf("%.1fP", b/(1<<50))
+ case size >= 1<<40:
+ str = fmt.Sprintf("%.1fT", b/(1<<40))
+ case size >= 1<<30:
+ str = fmt.Sprintf("%.1fG", b/(1<<30))
+ case size >= 1<<20:
+ str = fmt.Sprintf("%.1fM", b/(1<<20))
+ case size >= 1<<10:
+ str = fmt.Sprintf("%.1fK", b/(1<<10))
+ default:
+ str = fmt.Sprintf("%dB", size)
+ }
+ return
+}
+
+var fsTypeMap = map[int64]string{
+ 0xEF53: "EXT2 / EXT3 / EXT4",
+ 0x58465342: "XFS",
+ 0x9123683E: "Btrfs",
+ 0x52654973: "ReiserFS",
+ 0x5346544E: "NTFS",
+ 0xF995E849: "ZFS",
+ 0x2FC12FC1: "ZFS (alt)",
+ 0x65735546: "FUSE",
+ 0x01021994: "TMPFS",
+ 0x28CD3D45: "CRAMFS",
+ 0x73717368: "SquashFS",
+ 0x4244: "HFS",
+ 0x482B: "HFS+",
+ 0x41504653: "APFS",
+ 0x6969: "NFS",
+ 0xFF534D42: "CIFS / SMB",
+ 0x4D44: "FAT",
+ 0x4006: "FAT32",
+ 0xE0F5E1E2: "EXFAT",
+ 0x9660: "ISO 9660",
+ 0x15013346: "UDF",
+}