Compare commits
2 Commits
aa5db2b8cc
...
67b92d44a7
Author | SHA1 | Date |
---|---|---|
|
67b92d44a7 | 1 week ago |
|
9751ebeef4 | 1 week ago |
5 changed files with 188 additions and 58 deletions
@ -0,0 +1,162 @@ |
||||
package free |
||||
|
||||
import ( |
||||
"flag" |
||||
"fmt" |
||||
"io" |
||||
|
||||
"git.mills.io/prologic/gonix/internal/applets" |
||||
"git.mills.io/prologic/gonix/internal/common" |
||||
"github.com/dustin/go-humanize" |
||||
) |
||||
|
||||
const binaryName = "free" |
||||
|
||||
const helpText = ` |
||||
Display the amount of free and used system memory |
||||
` |
||||
|
||||
type unit uint |
||||
|
||||
const ( |
||||
// B is bytes
|
||||
B unit = 0 |
||||
// KB is kibibytes
|
||||
KB = 10 |
||||
// MB is mebibytes
|
||||
MB = 20 |
||||
// GB is gibibytes
|
||||
GB = 30 |
||||
// TB is tebibytes
|
||||
TB = 40 |
||||
) |
||||
|
||||
var units = [...]string{"B", "K", "M", "G", "T"} |
||||
|
||||
type Config struct { |
||||
Unit unit |
||||
HumanOutput bool |
||||
} |
||||
|
||||
func init() { |
||||
applets.Register(binaryName, Main) |
||||
} |
||||
|
||||
type Option struct { |
||||
helpFlag bool |
||||
hFlag bool |
||||
bFlag bool |
||||
kFlag bool |
||||
mFlag bool |
||||
gFlag bool |
||||
} |
||||
|
||||
// Validate checks that only one option of -b, -k, -m, -g or -h has been
|
||||
// specified on the command line
|
||||
func (opt *Option) Validate() bool { |
||||
count := 0 |
||||
if opt.bFlag { |
||||
count++ |
||||
} |
||||
if opt.kFlag { |
||||
count++ |
||||
} |
||||
if opt.mFlag { |
||||
count++ |
||||
} |
||||
if opt.gFlag { |
||||
count++ |
||||
} |
||||
if opt.hFlag { |
||||
count++ |
||||
} |
||||
if count > 1 { |
||||
return false |
||||
} |
||||
return true |
||||
} |
||||
|
||||
func NewFlagSet() (*flag.FlagSet, *Option) { |
||||
ret := flag.NewFlagSet(binaryName, flag.ExitOnError) |
||||
|
||||
ret.Usage = func() { |
||||
fmt.Printf("Usage: %s [OPTIONS] ...\n", binaryName) |
||||
fmt.Printf("%s\n", helpText) |
||||
ret.PrintDefaults() |
||||
} |
||||
|
||||
var opt Option |
||||
|
||||
ret.BoolVar(&opt.helpFlag, "help", false, "show this message") |
||||
ret.BoolVar(&opt.hFlag, "h", false, "Display values in human readable form") |
||||
ret.BoolVar(&opt.bFlag, "b", false, "Display values in bytes") |
||||
ret.BoolVar(&opt.kFlag, "k", false, "Display values in kitobytes") |
||||
ret.BoolVar(&opt.mFlag, "m", false, "Display values in megabytes") |
||||
ret.BoolVar(&opt.gFlag, "g", false, "Display values in gigabytes") |
||||
|
||||
return ret, &opt |
||||
} |
||||
|
||||
func Main(stdout io.Writer, args []string) error { |
||||
flagSet, opt := NewFlagSet() |
||||
flagSet.Parse(args) |
||||
|
||||
if opt.helpFlag { |
||||
flagSet.Usage() |
||||
return nil |
||||
} |
||||
|
||||
return free(stdout, flagSet.Args(), opt) |
||||
} |
||||
|
||||
// formatValueByConfig formats a size in bytes in the appropriate unit,
|
||||
// depending on whether FreeConfig specifies a human-readable format or a
|
||||
// specific unit
|
||||
func formatValueByConfig(value uint64, config *Config) string { |
||||
if config.HumanOutput { |
||||
return humanize.Bytes(value) |
||||
} |
||||
// units and decimal part are not printed when a unit is explicitly specified
|
||||
return fmt.Sprintf("%v", value>>config.Unit) |
||||
} |
||||
|
||||
func free(w io.Writer, args []string, opt *Option) error { |
||||
if !opt.Validate() { |
||||
return fmt.Errorf("options -k, -m, -g and -h are mutually exclusive") |
||||
} |
||||
|
||||
config := &Config{HumanOutput: opt.hFlag} |
||||
|
||||
switch { |
||||
case opt.bFlag: |
||||
config.Unit = B |
||||
case opt.kFlag: |
||||
config.Unit = KB |
||||
case opt.mFlag: |
||||
config.Unit = MB |
||||
case opt.gFlag: |
||||
config.Unit = GB |
||||
} |
||||
|
||||
sysinfo, err := common.Sysinfo() |
||||
if err != nil { |
||||
return err |
||||
} |
||||
|
||||
fmt.Fprintf(w, " total used free shared buffers\n") |
||||
fmt.Fprintf(w, "%-7s %11v %11v %11v %11v %11v\n", |
||||
"Mem:", |
||||
formatValueByConfig(sysinfo.TotalRam, config), |
||||
formatValueByConfig(sysinfo.TotalRam-sysinfo.FreeRam, config), |
||||
formatValueByConfig(sysinfo.FreeRam, config), |
||||
formatValueByConfig(sysinfo.SharedRam, config), |
||||
formatValueByConfig(sysinfo.BufferRam, config), |
||||
) |
||||
fmt.Fprintf(w, "%-7s %11v %11v %11v\n", |
||||
"Swap:", |
||||
formatValueByConfig(sysinfo.TotalSwap, config), |
||||
formatValueByConfig(sysinfo.TotalSwap-sysinfo.FreeSwap, config), |
||||
formatValueByConfig(sysinfo.FreeSwap, config), |
||||
) |
||||
return nil |
||||
} |
@ -1,56 +0,0 @@ |
||||
package sysinfo |
||||
|
||||
import ( |
||||
"flag" |
||||
"fmt" |
||||
"io" |
||||
|
||||
"git.mills.io/prologic/gonix/internal/applets" |
||||
"git.mills.io/prologic/gonix/internal/common" |
||||
) |
||||
|
||||
const binaryName = "sysinfo" |
||||
|
||||
func init() { |
||||
applets.Register(binaryName, Main) |
||||
} |
||||
|
||||
var ( |
||||
help bool |
||||
) |
||||
|
||||
func NewFlagSet() *flag.FlagSet { |
||||
ret := flag.NewFlagSet(binaryName, flag.ExitOnError) |
||||
|
||||
ret.Usage = func() { |
||||
fmt.Println("sysinfo [OPTIONS]") |
||||
ret.PrintDefaults() |
||||
} |
||||
|
||||
ret.BoolVar(&help, "help", false, "show this message") |
||||
|
||||
return ret |
||||
} |
||||
|
||||
func Main(stdout io.Writer, args []string) error { |
||||
flagSet := NewFlagSet() |
||||
flagSet.Parse(args) |
||||
|
||||
if help { |
||||
flagSet.Usage() |
||||
return nil |
||||
} |
||||
|
||||
return sysinfo(stdout, flagSet.Args()) |
||||
} |
||||
|
||||
func sysinfo(w io.Writer, args []string) error { |
||||
sysinfo, err := common.Sysinfo() |
||||
if err != nil { |
||||
return err |
||||
} |
||||
|
||||
fmt.Fprintln(w, sysinfo.String()) |
||||
|
||||
return nil |
||||
} |
After Width: | Height: | Size: 321 KiB |
Loading…
Reference in new issue