Commit 05a2349

Ansari <ping@ansari.wtf>
2025-12-27 10:37:12
add initial implementation of disk usage utility with go (duf mod)
1 parent 9f4ab07
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",
+}