master
1package get
2
3import (
4 "fmt"
5 "math"
6 "os"
7 "strings"
8
9 human "github.com/dustin/go-humanize"
10 "github.com/jedib0t/go-pretty/v6/table"
11 "github.com/kahnwong/swissknife/configs/color"
12 "github.com/shirou/gopsutil/v4/disk"
13)
14
15func Volumes() error {
16 // ref: <https://stackoverflow.com/a/64141403>
17 // layout inspired by `duf`
18
19 // init table
20 t := table.NewWriter()
21 t.SetOutputMirror(os.Stdout)
22 t.AppendHeader(table.Row{"Mounted on", "Size", "Used", "Avail", "Use%", "Type", "Filesystem"})
23
24 // get volumes info
25 partitions, err := disk.Partitions(false)
26 if err != nil {
27 return fmt.Errorf("error getting partitions info: %w", err)
28 }
29
30 for _, partition := range partitions {
31 // linux
32 isSquashFs := partition.Fstype == "squashfs"
33 isSnap := strings.Contains(partition.Mountpoint, "snap")
34 isKubernetes := strings.Contains(partition.Mountpoint, "kubelet")
35 // osx
36 isOsx := strings.Contains(partition.Mountpoint, "System/Volumes")
37 isDevFs := partition.Fstype == "devfs"
38 isOsxNix := strings.Contains(partition.Mountpoint, "/nix")
39 if !isSquashFs && !isSnap && !isKubernetes && !isOsx && !isDevFs && !isOsxNix {
40 device := partition.Mountpoint
41 stats, err := disk.Usage(device)
42 if err != nil {
43 return fmt.Errorf("error getting disk info: %w", err)
44 }
45
46 if stats.Total == 0 {
47 continue
48 }
49
50 // disk available
51 diskAvail := stats.Free
52 diskAvailStr := ""
53 if diskAvail < 50*1024*1024*1024 { // if free space less than 50 GB
54 diskAvailStr = color.Red(human.Bytes(diskAvail))
55 } else if diskAvail < 100*1024*1024*1024 { // if free space less than 100 GB
56 diskAvailStr = color.Yellow(human.Bytes(diskAvail))
57 } else {
58 diskAvailStr = color.Green(human.Bytes(diskAvail))
59 }
60
61 // disk use percent
62 percentRaw := stats.UsedPercent
63 diskUseTicks := int(math.Round(stats.UsedPercent)) / 10
64 diskUseBar := fmt.Sprintf(
65 "[%s%s] %2.f%%",
66 strings.Repeat("#", diskUseTicks),
67 strings.Repeat(".", 10-diskUseTicks),
68 stats.UsedPercent,
69 )
70 diskUseStr := ""
71 if percentRaw > 80 {
72 diskUseStr = color.Red(diskUseBar)
73 } else if percentRaw > 70 {
74 diskUseStr = color.Yellow(diskUseBar)
75 } else {
76 diskUseStr = color.Green(diskUseBar)
77 }
78
79 // append info to table
80 t.AppendRows([]table.Row{
81 {
82 color.Blue(partition.Mountpoint),
83 human.Bytes(stats.Total),
84 human.Bytes(stats.Used),
85 diskAvailStr,
86 diskUseStr,
87 color.Magenta(partition.Fstype),
88 color.Magenta(partition.Device),
89 },
90 })
91 }
92 }
93
94 // render
95 t.Render()
96 return nil
97}