add support for config file, keybinding for exporting active config

This commit is contained in:
Bradley Cicenas 2018-01-11 16:15:18 +00:00
parent d785b263f4
commit d743472b16
6 changed files with 133 additions and 1 deletions

View File

@ -79,6 +79,7 @@ s | Select container sort field
r | Reverse container sort order
o | Open single view
l | View container logs (`t` to toggle timestamp when open)
S | Save current configuration to file
q | Quit ctop
[build]: _docs/build.md

119
config/file.go Normal file
View File

@ -0,0 +1,119 @@
package config
import (
"fmt"
"os"
"regexp"
"strings"
"github.com/BurntSushi/toml"
)
var (
xdgRe = regexp.MustCompile("^XDG_*")
)
type ConfigFile struct {
Options map[string]string `toml:"options"`
Toggles map[string]bool `toml:"toggles"`
}
func exportConfig() ConfigFile {
c := ConfigFile{
Options: make(map[string]string),
Toggles: make(map[string]bool),
}
for _, p := range GlobalParams {
c.Options[p.Key] = p.Val
}
for _, sw := range GlobalSwitches {
c.Toggles[sw.Key] = sw.Val
}
return c
}
func Read() error {
var config ConfigFile
path, err := getConfigPath()
if err != nil {
return err
}
if _, err := toml.DecodeFile(path, &config); err != nil {
return err
}
for k, v := range config.Options {
Update(k, v)
}
for k, v := range config.Toggles {
UpdateSwitch(k, v)
}
return nil
}
func Write() error {
path, err := getConfigPath()
if err != nil {
return err
}
cfgdir := basedir(path)
// create config dir if not exist
if _, err := os.Stat(cfgdir); err != nil {
err = os.MkdirAll(cfgdir, 0755)
if err != nil {
return fmt.Errorf("failed to create config dir [%s]: %s", cfgdir, err)
}
}
file, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE, 0644)
if err != nil {
return fmt.Errorf("failed to open config for writing: %s", err)
}
writer := toml.NewEncoder(file)
err = writer.Encode(exportConfig())
if err != nil {
return fmt.Errorf("failed to write config: %s", err)
}
return nil
}
// determine config path from environment
func getConfigPath() (path string, err error) {
homeDir, ok := os.LookupEnv("HOME")
if !ok {
return path, fmt.Errorf("$HOME not set")
}
// use xdg config home if possible
if xdgSupport() {
xdgHome, ok := os.LookupEnv("XDG_CONFIG_HOME")
if !ok {
xdgHome = fmt.Sprintf("%s/.config", homeDir)
}
path = fmt.Sprintf("%s/ctop/config", xdgHome)
} else {
path = fmt.Sprintf("%s/.ctop", homeDir)
}
return path, nil
}
// test for environemnt supporting XDG spec
func xdgSupport() bool {
for _, e := range os.Environ() {
if xdgRe.FindAllString(e, 1) != nil {
return true
}
}
return false
}
func basedir(path string) string {
parts := strings.Split(path, "/")
return strings.Join((parts[0 : len(parts)-1]), "/")
}

View File

@ -45,6 +45,14 @@ func GetSwitchVal(k string) bool {
return GetSwitch(k).Val
}
func UpdateSwitch(k string, val bool) {
sw := GetSwitch(k)
if sw.Val != val {
log.Noticef("config change: %s: %t -> %t", k, sw.Val, val)
sw.Val = val
}
}
// Toggle a boolean switch
func Toggle(k string) {
sw := GetSwitch(k)

View File

@ -131,6 +131,9 @@ func Display() bool {
menu = SortMenu
ui.StopLoop()
})
ui.Handle("/sys/kbd/S", func(ui.Event) {
config.Write()
})
ui.Handle("/timer/1s", func(e ui.Event) {
RefreshDisplay()

View File

@ -41,7 +41,7 @@ func main() {
sortFieldFlag = flag.String("s", "", "select container sort field")
reverseSortFlag = flag.Bool("r", false, "reverse container sort order")
invertFlag = flag.Bool("i", false, "invert default colors")
scaleCpu = flag.Bool("scale-cpu", false, "show cpu as %% of system total")
scaleCpu = flag.Bool("scale-cpu", false, "show cpu as % of system total")
connectorFlag = flag.String("connector", "docker", "container connector to use")
)
flag.Parse()

View File

@ -25,6 +25,7 @@ var helpDialog = []menu.Item{
{"[r] - reverse container sort order", ""},
{"[o] - open single view", ""},
{"[l] - view container logs ([t] to toggle timestamp when open)", ""},
{"[S] - save current configuration to file", ""},
{"[q] - exit ctop", ""},
}