From 67178c68f5bf6f34ea43f4424cb972177965355f Mon Sep 17 00:00:00 2001 From: kmetin Date: Fri, 1 Sep 2023 16:34:18 +0300 Subject: [PATCH] make aliases runtime variables --- base/commands/alias/alias.go | 27 +++++++++++- base/commands/alias/alias_add.go | 42 ++---------------- base/commands/alias/alias_it_test.go | 21 ++++----- base/commands/alias/alias_list.go | 43 ++++++------------- base/commands/alias/alias_remove.go | 26 ++--------- .../ROOT/pages/user-defined-aliases.adoc | 2 + 6 files changed, 55 insertions(+), 106 deletions(-) diff --git a/base/commands/alias/alias.go b/base/commands/alias/alias.go index 96a02724..5d917709 100644 --- a/base/commands/alias/alias.go +++ b/base/commands/alias/alias.go @@ -4,11 +4,18 @@ package alias import ( "context" + "os" + "path/filepath" + "strings" + "sync" + "github.com/hazelcast/hazelcast-commandline-client/clc/paths" . "github.com/hazelcast/hazelcast-commandline-client/internal/check" "github.com/hazelcast/hazelcast-commandline-client/internal/plug" ) +var Aliases sync.Map + const AliasFileName = "shell.clc" type AliasCommand struct { @@ -31,5 +38,23 @@ func (a AliasCommand) Exec(context.Context, plug.ExecContext) error { } func init() { - Must(plug.Registry.RegisterCommand("alias", AliasCommand{})) + Must(plug.Registry.RegisterCommand("alias", AliasCommand{}, plug.OnlyInteractive{})) + Must(persistentAliases()) +} + +func persistentAliases() error { + p := filepath.Join(paths.Home(), AliasFileName) + data, err := os.ReadFile(p) + if err != nil && !os.IsNotExist(err) { + return err + } + lines := strings.Split(string(data), "\n") + for _, l := range lines { + if l == "" { + continue + } + parts := strings.SplitN(l, "=", 2) + Aliases.Store(parts[0], parts[1]) + } + return nil } diff --git a/base/commands/alias/alias_add.go b/base/commands/alias/alias_add.go index 118659ca..641de394 100644 --- a/base/commands/alias/alias_add.go +++ b/base/commands/alias/alias_add.go @@ -6,12 +6,9 @@ import ( "context" "fmt" "math" - "os" - "path/filepath" "strings" "github.com/hazelcast/hazelcast-commandline-client/clc" - "github.com/hazelcast/hazelcast-commandline-client/clc/paths" . "github.com/hazelcast/hazelcast-commandline-client/internal/check" "github.com/hazelcast/hazelcast-commandline-client/internal/plug" ) @@ -34,7 +31,8 @@ func (a AliasAddCommand) Exec(ctx context.Context, ec plug.ExecContext) error { cmd := strings.Join(ec.Args()[1:], " ") _, stop, err := ec.ExecuteBlocking(ctx, func(ctx context.Context, sp clc.Spinner) (any, error) { sp.SetText(fmt.Sprintf("Saving alias %s", name)) - return nil, CreateAlias(name, cmd) + Aliases.Store(name, cmd) + return nil, nil }) if err != nil { return err @@ -43,40 +41,6 @@ func (a AliasAddCommand) Exec(ctx context.Context, ec plug.ExecContext) error { return nil } -func CreateAlias(key, value string) error { - p := filepath.Join(paths.Home(), AliasFileName) - data, err := os.ReadFile(p) - if err != nil { - if os.IsNotExist(err) { - _, err = os.Create(p) - if err != nil { - return err - } - } else { - return err - } - } - lines := strings.Split(string(data), "\n") - var newData []string - updated := false - for _, line := range lines { - parts := strings.SplitN(line, "=", 2) - if len(parts) == 2 { - if parts[0] == key { - newData = append(newData, fmt.Sprintf("%s=%s", key, value)) - updated = true - } else { - newData = append(newData, line) - } - } - } - if !updated { - newData = append(newData, fmt.Sprintf("%s=%s", key, value)) - } - c := strings.Join(newData, "\n") - return os.WriteFile(filepath.Join(paths.Home(), AliasFileName), []byte(c), 0644) -} - func init() { - Must(plug.Registry.RegisterCommand("alias:add", &AliasAddCommand{})) + Must(plug.Registry.RegisterCommand("alias:add", &AliasAddCommand{}, plug.OnlyInteractive{})) } diff --git a/base/commands/alias/alias_it_test.go b/base/commands/alias/alias_it_test.go index 642d7cb4..6d2df06a 100644 --- a/base/commands/alias/alias_it_test.go +++ b/base/commands/alias/alias_it_test.go @@ -5,16 +5,12 @@ package alias_test import ( "context" "fmt" - "os" - "path/filepath" "testing" _ "github.com/hazelcast/hazelcast-commandline-client/base" _ "github.com/hazelcast/hazelcast-commandline-client/base/commands" "github.com/hazelcast/hazelcast-commandline-client/base/commands/alias" - "github.com/hazelcast/hazelcast-commandline-client/internal/check" "github.com/hazelcast/hazelcast-commandline-client/internal/it" - "github.com/stretchr/testify/require" ) func TestAlias(t *testing.T) { @@ -22,10 +18,10 @@ func TestAlias(t *testing.T) { name string f func(t *testing.T) }{ + {name: "Execute_Interactive", f: Execute_InteractiveTest}, {name: "Add_Interactive", f: Add_InteractiveTest}, {name: "Remove_Interactive", f: Remove_InteractiveTest}, {name: "List_Interactive", f: List_InteractiveTest}, - {name: "Execute_Interactive", f: Execute_InteractiveTest}, } for _, tc := range testCases { t.Run(tc.name, tc.f) @@ -36,7 +32,7 @@ func Execute_InteractiveTest(t *testing.T) { ctx := context.TODO() tcx := it.TestContext{T: t} tcx.Tester(func(tcx it.TestContext) { - check.Must(alias.CreateAlias("mapAlias", "map set 1 1")) + alias.Aliases.Store("mapAlias", "map set 1 1") tcx.WithShell(ctx, func(tcx it.TestContext) { tcx.WithReset(func() { tcx.WriteStdinString("@mapAlias\n") @@ -54,10 +50,10 @@ func Add_InteractiveTest(t *testing.T) { tcx.WithShell(ctx, func(tcx it.TestContext) { tcx.WithReset(func() { tcx.WriteStdinString(fmt.Sprintf("\\alias add mapAlias %s\n", `map set 1 1`)) + tcx.WriteStdinString("\\alias list\n") + tcx.AssertStdoutContains("map set 1 1") }) }) - c := check.MustValue(os.ReadFile(filepath.Join(tcx.HomePath(), alias.AliasFileName))) - require.Equal(t, "mapAlias=map set 1 1", string(c)) }) } @@ -65,14 +61,14 @@ func Remove_InteractiveTest(t *testing.T) { ctx := context.TODO() tcx := it.TestContext{T: t} tcx.Tester(func(tcx it.TestContext) { - check.Must(alias.CreateAlias("mapAlias", "map set 1 1")) + alias.Aliases.Store("mapAlias", "map set 1 1") tcx.WithShell(ctx, func(tcx it.TestContext) { tcx.WithReset(func() { tcx.WriteStdinString("\\alias remove mapAlias\n") + tcx.WriteStdinString("\\alias list\n") + tcx.AssertStdoutNotContains("map set 1 1") }) }) - c := check.MustValue(os.ReadFile(filepath.Join(tcx.HomePath(), alias.AliasFileName))) - require.Equal(t, 0, len(c)) }) } @@ -80,11 +76,12 @@ func List_InteractiveTest(t *testing.T) { ctx := context.TODO() tcx := it.TestContext{T: t} tcx.Tester(func(tcx it.TestContext) { - check.Must(alias.CreateAlias("mapAlias", "map set 1 1")) + alias.Aliases.Store("mapAlias", "map set 1 1") tcx.WithShell(ctx, func(tcx it.TestContext) { tcx.WithReset(func() { tcx.WriteStdinString("\\alias list\n") tcx.AssertStdoutContains("mapAlias") + tcx.AssertStdoutContains("map set 1 1") }) }) }) diff --git a/base/commands/alias/alias_list.go b/base/commands/alias/alias_list.go index 9c5c4a86..dd4d69e5 100644 --- a/base/commands/alias/alias_list.go +++ b/base/commands/alias/alias_list.go @@ -2,12 +2,8 @@ package alias import ( "context" - "os" - "path/filepath" - "strings" "github.com/hazelcast/hazelcast-commandline-client/clc" - "github.com/hazelcast/hazelcast-commandline-client/clc/paths" . "github.com/hazelcast/hazelcast-commandline-client/internal/check" "github.com/hazelcast/hazelcast-commandline-client/internal/output" "github.com/hazelcast/hazelcast-commandline-client/internal/plug" @@ -32,14 +28,22 @@ type alias struct { func (a AliasListCommand) Exec(ctx context.Context, ec plug.ExecContext) error { sv, stop, err := ec.ExecuteBlocking(ctx, func(ctx context.Context, sp clc.Spinner) (any, error) { sp.SetText("Listing aliases") - return listAliases() + var all []alias + Aliases.Range(func(key, value any) bool { + all = append(all, alias{ + name: key.(string), + value: value.(string), + }) + return true + }) + return all, nil }) if err != nil { return err } stop() - aliases := sv.([]alias) - if len(aliases) == 0 { + all := sv.([]alias) + if len(all) == 0 { ec.PrintlnUnnecessary("No aliases found.") return nil } @@ -61,29 +65,6 @@ func (a AliasListCommand) Exec(ctx context.Context, ec plug.ExecContext) error { return ec.AddOutputRows(ctx, rows...) } -func listAliases() ([]alias, error) { - var aliases []alias - data, err := os.ReadFile(filepath.Join(paths.Home(), AliasFileName)) - if err != nil { - if os.IsNotExist(err) { - return nil, nil - } - return nil, err - } - lines := strings.Split(string(data), "\n") - for _, l := range lines { - if l == "" { - continue - } - parts := strings.SplitN(l, "=", 2) - aliases = append(aliases, alias{ - name: parts[0], - value: parts[1], - }) - } - return aliases, nil -} - func init() { - Must(plug.Registry.RegisterCommand("alias:list", &AliasListCommand{})) + Must(plug.Registry.RegisterCommand("alias:list", &AliasListCommand{}, plug.OnlyInteractive{})) } diff --git a/base/commands/alias/alias_remove.go b/base/commands/alias/alias_remove.go index e7ecf87d..1971bb57 100644 --- a/base/commands/alias/alias_remove.go +++ b/base/commands/alias/alias_remove.go @@ -3,12 +3,8 @@ package alias import ( "context" "fmt" - "os" - "path/filepath" - "strings" "github.com/hazelcast/hazelcast-commandline-client/clc" - "github.com/hazelcast/hazelcast-commandline-client/clc/paths" . "github.com/hazelcast/hazelcast-commandline-client/internal/check" "github.com/hazelcast/hazelcast-commandline-client/internal/plug" ) @@ -27,7 +23,8 @@ func (a AliasRemoveCommand) Exec(ctx context.Context, ec plug.ExecContext) error name := ec.Args()[0] _, stop, err := ec.ExecuteBlocking(ctx, func(ctx context.Context, sp clc.Spinner) (any, error) { sp.SetText(fmt.Sprintf("Removing alias %s", name)) - return nil, removeAlias(name) + Aliases.Delete(name) + return nil, nil }) if err != nil { return err @@ -36,23 +33,6 @@ func (a AliasRemoveCommand) Exec(ctx context.Context, ec plug.ExecContext) error return nil } -func removeAlias(name string) error { - data, err := os.ReadFile(filepath.Join(paths.Home(), AliasFileName)) - if err != nil { - return err - } - lines := strings.Split(string(data), "\n") - var newData []string - for _, l := range lines { - parts := strings.SplitN(l, "=", 2) - if parts[0] != name { - newData = append(newData, l) - } - } - newContent := strings.Join(newData, "\n") - return os.WriteFile(filepath.Join(paths.Home(), AliasFileName), []byte(newContent), 0600) -} - func init() { - Must(plug.Registry.RegisterCommand("alias:remove", &AliasRemoveCommand{})) + Must(plug.Registry.RegisterCommand("alias:remove", &AliasRemoveCommand{}, plug.OnlyInteractive{})) } diff --git a/docs/modules/ROOT/pages/user-defined-aliases.adoc b/docs/modules/ROOT/pages/user-defined-aliases.adoc index 854b866b..4c5477c7 100644 --- a/docs/modules/ROOT/pages/user-defined-aliases.adoc +++ b/docs/modules/ROOT/pages/user-defined-aliases.adoc @@ -2,6 +2,8 @@ Alias command are a group of alias operations. +They are runtime variables. If you want to persist them you need to save them in `$CLC_HOME/shell.clc` in `=` format. Variables in `shell.clc` are loaded everytime CLC starts. + Usage: [source,bash]