diff --git a/cmd/gotop/main.go b/cmd/gotop/main.go index d8e0493..2458612 100644 --- a/cmd/gotop/main.go +++ b/cmd/gotop/main.go @@ -18,7 +18,7 @@ import ( ui "github.com/gizak/termui/v3" "github.com/prometheus/client_golang/prometheus/promhttp" "github.com/shibukawa/configdir" - flag "github.com/xxxserxxx/pflag" + flag "github.com/xxxserxxx/opflag" "github.com/xxxserxxx/gotop/v4" "github.com/xxxserxxx/gotop/v4/colorschemes" @@ -29,8 +29,6 @@ import ( ) const ( - appName = "gotop" - graphHorizontalScaleDelta = 3 defaultUI = "2:cpu\ndisk/1 2:mem/2\ntemp\n2:net 2:procs" minimalUI = "cpu\nmem procs" @@ -65,7 +63,7 @@ func parseArgs(conf *gotop.Config) error { fahrenheit := flag.BoolP("fahrenheit", "f", conf.TempScale == 'F', "Show temperatures in fahrenheit.Show temperatures in fahrenheit.") flag.BoolVarP(&conf.Statusbar, "statusbar", "s", conf.Statusbar, "Show a statusbar with the time.") flag.DurationVarP(&conf.UpdateInterval, "rate", "r", conf.UpdateInterval, "Number of times per second to update CPU and Mem widgets.") - flag.StringVarP(&conf.ExportPort, "layout", "l", conf.Layout, `Name of layout spec file for the UI. Use "-" to pipe.`) + flag.StringVarP(&conf.Layout, "layout", "l", conf.Layout, `Name of layout spec file for the UI. Use "-" to pipe.`) flag.StringVarP(&conf.NetInterface, "interface", "i", "all", "Select network interface. Several interfaces can be defined using comma separated values. Interfaces can also be ignored using `!`") flag.StringVarP(&conf.ExportPort, "export", "x", conf.ExportPort, "Enable metrics for export on the specified port.") flag.BoolVarP(&conf.Mbps, "mbps", "", conf.Mbps, "Show network rate as mbps.") @@ -73,13 +71,13 @@ func parseArgs(conf *gotop.Config) error { //conf.Band = flag.IntP("bandwidth", "B", 100, "Specify the number of bits per seconds.") flag.BoolVar(&conf.Test, "test", conf.Test, "Runs tests and exits with success/failure code.") list := flag.String("list", "", `List -devices: Prints out device names for filterable widgets -layouts: Lists build-in layouts -colorschemes: Lists built-in colorschemes -paths: List out configuration file search paths -keys: Show the keyboard bindings.`) + devices: Prints out device names for filterable widgets + layouts: Lists build-in layouts + colorschemes: Lists built-in colorschemes + paths: List out configuration file search paths + keys: Show the keyboard bindings.`) wc := flag.Bool("write-config", false, "Write out a default config file.") - flag.CommandLine.SortFlags = false + flag.SortFlags = false flag.Usage = func() { fmt.Fprintf(os.Stderr, "Usage: %s [options]\n\nOptions:\n", os.Args[0]) flag.PrintDefaults() @@ -122,7 +120,7 @@ keys: Show the keyboard bindings.`) case "keys": fmt.Println(KEYS) default: - fmt.Printf("Unknown option \"%s\"; try layouts, colorschemes, or devices\n", *list) + fmt.Printf("Unknown option \"%s\"; try layouts, colorschemes, keys, paths, or devices\n", *list) os.Exit(1) } os.Exit(0) @@ -327,26 +325,6 @@ func eventLoop(c gotop.Config, grid *layout.MyGrid) { } } -func makeConfig() gotop.Config { - cd := configdir.New("", appName) - cd.LocalPath, _ = filepath.Abs(".") - conf = gotop.Config{ - ConfigDir: cd, - GraphHorizontalScale: 7, - HelpVisible: false, - UpdateInterval: time.Second, - AverageLoad: false, - PercpuLoad: true, - TempScale: w.Celsius, - Statusbar: false, - NetInterface: w.NET_INTERFACE_ALL, - MaxLogSize: 5000000, - Layout: "default", - } - conf.Colorscheme, _ = colorschemes.FromName(conf.ConfigDir, "default") - return conf -} - // TODO: Add fans // TODO: mpd visualizer widget // TODO: Add tab completion for Linux https://gist.github.com/icholy/5314423 @@ -374,8 +352,7 @@ func main() { } func run() int { - // Set up default config - conf := makeConfig() + conf := gotop.NewConfig() // Find the config file; look in (1) local, (2) user, (3) global err := conf.Load() if err != nil { @@ -407,7 +384,13 @@ func run() int { return runTests(conf) } - //devices.Startup(conf) + errs := devices.Startup(conf.ExtensionVars) + if len(errs) > 0 { + for _, err := range errs { + stderrLogger.Print(err) + } + return 1 + } if err := ui.Init(); err != nil { stderrLogger.Print(err) return 1 @@ -527,15 +510,15 @@ CPU and Mem graph scaling: l: scale out ?: toggles keybind help menu` const LAYOUTS = `Built-in layouts: -\tdefault -\tminimal -\tbattery -\tkitchensink` + default + minimal + battery + kitchensink` const COLORSCHEMES = `Built-in colorschemes: -\tdefault -\tdefault-dark (for white background) -\tsolarized -\tsolarized16-dark -\tsolarized16-light -\tmonokai -\tvice` + default + default-dark (for white background) + solarized + solarized16-dark + solarized16-light + monokai + vice` diff --git a/config.go b/config.go index 3619c54..fef5478 100644 --- a/config.go +++ b/config.go @@ -17,25 +17,44 @@ import ( ) type Config struct { - ConfigDir configdir.ConfigDir - + ConfigDir configdir.ConfigDir GraphHorizontalScale int HelpVisible bool Colorscheme colorschemes.Colorscheme + UpdateInterval time.Duration + AverageLoad bool + PercpuLoad bool + Statusbar bool + TempScale widgets.TempScale + NetInterface string + Layout string + MaxLogSize int64 + ExportPort string + Mbps bool + Temps []string + Test bool + ExtensionVars map[string]string +} - UpdateInterval time.Duration - AverageLoad bool - PercpuLoad bool - Statusbar bool - TempScale widgets.TempScale - NetInterface string - Layout string - MaxLogSize int64 - ExportPort string - Mbps bool - Temps []string - - Test bool +func NewConfig() Config { + cd := configdir.New("", "gotop") + cd.LocalPath, _ = filepath.Abs(".") + conf := Config{ + ConfigDir: cd, + GraphHorizontalScale: 7, + HelpVisible: false, + UpdateInterval: time.Second, + AverageLoad: false, + PercpuLoad: true, + TempScale: widgets.Celsius, + Statusbar: false, + NetInterface: widgets.NET_INTERFACE_ALL, + MaxLogSize: 5000000, + Layout: "default", + ExtensionVars: make(map[string]string), + } + conf.Colorscheme, _ = colorschemes.FromName(conf.ConfigDir, "default") + return conf } func (conf *Config) Load() error { @@ -68,7 +87,7 @@ func load(in io.Reader, conf *Config) error { key := strings.ToLower(kv[0]) switch key { default: - return fmt.Errorf("invalid config option %s", key) + conf.ExtensionVars[key] = kv[1] case "configdir": log.Printf("configdir is deprecated. Ignored configdir=%s", kv[1]) case "logdir": diff --git a/devices/devices.go b/devices/devices.go index 81b0521..5923cb6 100644 --- a/devices/devices.go +++ b/devices/devices.go @@ -12,6 +12,7 @@ var Domains []string = []string{Temperatures} var _shutdownFuncs []func() error var _devs map[string][]string var _defaults map[string][]string +var _startup []func(map[string]string) error // RegisterShutdown stores a function to be called by gotop on exit, allowing // extensions to properly release resources. Extensions should register a @@ -22,21 +23,24 @@ func RegisterShutdown(f func() error) { _shutdownFuncs = append(_shutdownFuncs, f) } -/* -func RegisterStartup(f func(gotop.Config)) { +func RegisterStartup(f func(vars map[string]string) error) { if _startup == nil { - _startup = make([]func(gotop.Config), 1) + _startup = make([]func(map[string]string) error, 0, 1) } _startup = append(_startup, f) } // Called after configuration has been parsed -func Startup(c gotop.Config) { +func Startup(vars map[string]string) []error { + rv := make([]error, 0) for _, f := range _startup { - f(c) + err := f(vars) + if err != nil { + rv = append(rv, err) + } } + return rv } -*/ // Shutdown will be called by the `main()` function if gotop is exited // cleanly. It will call all of the registered shutdown functions of devices, diff --git a/go.mod b/go.mod index 97508d5..29a5919 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,7 @@ require ( github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4 // indirect github.com/stretchr/testify v1.4.0 github.com/xxxserxxx/iSMC v1.0.1 - github.com/xxxserxxx/pflag v1.0.8 + github.com/xxxserxxx/opflag v1.0.3 golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a // indirect golang.org/x/tools v0.0.0-20200425043458-8463f397d07c // indirect golang.org/x/tools/gopls v0.4.0 // indirect diff --git a/go.sum b/go.sum index 4a2c105..2410a27 100644 --- a/go.sum +++ b/go.sum @@ -113,10 +113,12 @@ github.com/xxxserxxx/gotop/v3 v3.5.1 h1:aBf++Oxg7qCZpKqYpPPnXKFOxT1KYLPtiEXRh57y github.com/xxxserxxx/gotop/v3 v3.5.1/go.mod h1:DGPTiAmUhqE21xvokK64BuMxW+EmnOptaxpdOlqiH6s= github.com/xxxserxxx/iSMC v1.0.1 h1:M9Gkwnnkl+evvnugoB5yRYrbUP+cRIVOPM+xrHZc3Hs= github.com/xxxserxxx/iSMC v1.0.1/go.mod h1:TGgNjU7BF2DZSuxiTft+BdzxzcujFJYqFfMCzcTl/aY= -github.com/xxxserxxx/pflag v1.0.7 h1:451NW+tmkc1R30NnibaAbbsysLqGLguFrdLr6SIbYac= -github.com/xxxserxxx/pflag v1.0.7/go.mod h1:Nyfo0BBT+1wKxL37phQvEyr5zgzmQ+C7/CiXSOsYR2w= -github.com/xxxserxxx/pflag v1.0.8 h1:UuFim2L1eNWapysJARSJ+QbbUOxEz23VrYWe4mFXTg8= -github.com/xxxserxxx/pflag v1.0.8/go.mod h1:Nyfo0BBT+1wKxL37phQvEyr5zgzmQ+C7/CiXSOsYR2w= +github.com/xxxserxxx/opflag v1.0.0 h1:NabxbubvejqcdzQUHnsU8pBMAiWM+a/Rh2IJe56moiU= +github.com/xxxserxxx/opflag v1.0.0/go.mod h1:Zf9bGkOcA35ypGfN25KX0iujVpZB5XwauEFjcfSKcBo= +github.com/xxxserxxx/opflag v1.0.2 h1:TanW4Ck/RNal4fP2VVAvhEu7eBq4z+9hhGq9Q8OTq68= +github.com/xxxserxxx/opflag v1.0.2/go.mod h1:GWZtb3/tGGj5W1GE/JTyJAuqgxDxl1+jqDGAGM+P/p4= +github.com/xxxserxxx/opflag v1.0.3 h1:ugsBWZtSXUaMLEjPLW0WKGjq/gsrc0GpZYbCJY6ZHVY= +github.com/xxxserxxx/opflag v1.0.3/go.mod h1:GWZtb3/tGGj5W1GE/JTyJAuqgxDxl1+jqDGAGM+P/p4= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= golang.org/x/arch v0.0.0-20181203225421-5a4828bb7045/go.mod h1:cYlCBUl1MsqxdiKgmc4uh7TxZfWSFLOGSRR090WDxt8= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=