From 05083b7038a786a2c58913e093642024821bd08d Mon Sep 17 00:00:00 2001 From: kencx Date: Mon, 20 May 2024 21:41:04 +0800 Subject: [PATCH] feat: export to json and yaml --- README.md | 2 +- config/config.go | 1 - config/model.go | 12 ++++++------ output/output.go | 27 +++++++++++++++++++++++++-- output/output_test.go | 36 +++++++++++++++++++++++++++++++++++- ui/ui.go | 2 ++ 6 files changed, 69 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index a852d36..d5ff55e 100644 --- a/README.md +++ b/README.md @@ -168,7 +168,7 @@ See [config](examples/config/README.md) for all configuration options. ## Contributing -keyb requires Go 1.21. Bug reports, feature requests and PRs are very welcome. +keyb requires Go 1.22. Bug reports, feature requests and PRs are very welcome. ## Similar Tools diff --git a/config/config.go b/config/config.go index 059fecc..be35a9b 100644 --- a/config/config.go +++ b/config/config.go @@ -132,7 +132,6 @@ var DefaultConfig = &Config{ } // Read configuration and keyb file from flags, default path. -// If config directory and/or files do not exist, create them. func Parse(flagCPath, flagKPath string) (Apps, *Config, error) { xdgConfigDir, err := getXDGConfigDir() if err != nil { diff --git a/config/model.go b/config/model.go index fca868c..9117833 100644 --- a/config/model.go +++ b/config/model.go @@ -9,9 +9,9 @@ import ( ) type App struct { - Name string `yaml:"name"` - Prefix string `yaml:"prefix,omitempty"` - Keybinds []KeyBind `yaml:"keybinds"` + Prefix string `yaml:"prefix,omitempty" json:"prefix,omitempty"` + Name string `yaml:"name" json:"name"` + Keybinds []KeyBind `yaml:"keybinds" json:"keybinds"` } type Apps []*App @@ -21,12 +21,12 @@ func (a App) String() string { } type KeyBind struct { - Name string `yaml:"name"` - Key string `yaml:"key"` + Name string `yaml:"name" json:"name"` + Key string `yaml:"key" json:"key"` // ignore prefix defaults to false // so user can choose to ignore prefix for a specific kb - IgnorePrefix bool `yaml:"ignore_prefix,omitempty"` + IgnorePrefix bool `yaml:"ignore_prefix,omitempty" json:"ignore_prefix,omitempty"` } func AddEntry(path, binding string, kbIgnorePrefix bool) error { diff --git a/output/output.go b/output/output.go index 60d1b18..5e213a5 100644 --- a/output/output.go +++ b/output/output.go @@ -1,19 +1,42 @@ package output import ( + "encoding/json" "fmt" "os" + "path/filepath" "github.com/kencx/keyb/ui" + "gopkg.in/yaml.v2" ) func ToFile(m *ui.Model, path string) error { - output := m.List.UnstyledString() + var ( + output []byte + err error + ) path = os.ExpandEnv(path) - if err := os.WriteFile(path, []byte(output), 0664); err != nil { + ext := filepath.Ext(path) + + switch ext { + case ".json": + output, err = json.Marshal(m.Apps) + if err != nil { + return fmt.Errorf("failed to marshal to json: %w", err) + } + case ".yml", ".yaml": + output, err = yaml.Marshal(m.Apps) + if err != nil { + return fmt.Errorf("failed to marshal to yaml: %w", err) + } + default: + output = []byte(m.List.UnstyledString()) + } + if err := os.WriteFile(path, output, 0664); err != nil { return fmt.Errorf("failed to write to file: %w", err) } + return nil } diff --git a/output/output_test.go b/output/output_test.go index 90f307c..d6f8f83 100644 --- a/output/output_test.go +++ b/output/output_test.go @@ -3,6 +3,8 @@ package output import ( "io" "os" + "path/filepath" + "reflect" "testing" "github.com/kencx/keyb/config" @@ -14,9 +16,41 @@ import ( var ( testTable = table.New([]*table.Row{table.NewHeading("foo"), {Text: "bar"}}) testConfig = &config.Config{} - m = &ui.Model{List: list.New(testTable, testConfig)} + testApps = &config.Apps{ + &config.App{ + Name: "foo", + Prefix: "bar", + Keybinds: []config.KeyBind{ + { + Name: "key foo", + Key: "key bar", + }, + }, + }, + } + m = &ui.Model{List: list.New(testTable, testConfig), Apps: testApps} ) +func TestToJson(t *testing.T) { + tempDir := t.TempDir() + path := filepath.Join(tempDir, "test.json") + + err := ToFile(m, path) + if err != nil { + t.Fatal(err) + } + + got, err := os.ReadFile(path) + if err != nil { + t.Fatal(err) + } + + want := []byte(`[{"prefix":"bar","name":"foo","keybinds":[{"name":"key foo","key":"key bar"}]}]`) + if !reflect.DeepEqual(got, want) { + t.Fatalf("got %s, want %s", got, want) + } +} + func TestToStdout(t *testing.T) { rescueStdout := os.Stdout r, w, _ := os.Pipe() diff --git a/ui/ui.go b/ui/ui.go index e4b5302..030faf3 100644 --- a/ui/ui.go +++ b/ui/ui.go @@ -13,6 +13,7 @@ import ( type Model struct { List list.Model + Apps *config.Apps } func NewModel(a config.Apps, config *config.Config) *Model { @@ -20,6 +21,7 @@ func NewModel(a config.Apps, config *config.Config) *Model { table := createParentTable(a, config.SortKeys) return &Model{ List: list.New(table, config), + Apps: &a, } }