Implemented roadmap #9: Shell scripts execution with variables. Features: - set <name> <value> - Set shell variable - unset <name> - Remove variable - vars - List all variables - Variable substitution in all commands Variable syntax: - $VAR or ${VAR} - Shell variables - $ENV:VARNAME - Environment variables Variables expand before command execution, enabling: - Dynamic key paths: put $BASE/$ID '{"data":"value"}' - Reusable values: set TOKEN xyz && auth $TOKEN - Script parameterization in batch files Example batch script: set USER alice set KEY_PREFIX users put $KEY_PREFIX/$USER '{"name":"$USER"}' get $KEY_PREFIX/$USER Variables are session-scoped and work in both interactive and batch modes. Environment variables can be injected using $ENV:HOME syntax. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
131 lines
2.4 KiB
Go
131 lines
2.4 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"strings"
|
|
|
|
"github.com/chzyer/readline"
|
|
)
|
|
|
|
// executeCommand executes a single command line
|
|
func (c *KVSClient) executeCommand(line string) bool {
|
|
// Expand variables in the line
|
|
line = c.expandVariables(line)
|
|
|
|
parts := parseCommand(line)
|
|
if len(parts) == 0 {
|
|
return true
|
|
}
|
|
|
|
cmd := parts[0]
|
|
args := parts[1:]
|
|
|
|
switch cmd {
|
|
case "exit", "quit":
|
|
fmt.Println("Goodbye!")
|
|
return false
|
|
case "clear":
|
|
print("\033[H\033[2J")
|
|
case "help":
|
|
c.handleHelp(args)
|
|
case "connect":
|
|
c.handleConnect(args)
|
|
case "auth":
|
|
c.handleAuth(args)
|
|
case "profile":
|
|
c.handleProfile(args)
|
|
case "get":
|
|
c.handleGet(args)
|
|
case "put":
|
|
c.handlePut(args)
|
|
case "delete":
|
|
c.handleDelete(args)
|
|
case "meta":
|
|
c.handleMeta(args)
|
|
case "members":
|
|
c.handleMembers(args)
|
|
case "health":
|
|
c.handleHealth(args)
|
|
case "user":
|
|
if len(args) > 0 {
|
|
switch args[0] {
|
|
case "get":
|
|
c.handleUserGet(args[1:])
|
|
case "create":
|
|
c.handleUserCreate(args[1:])
|
|
default:
|
|
fmt.Println(red("Unknown user command:"), args[0])
|
|
fmt.Println("Type 'help' for available commands")
|
|
}
|
|
} else {
|
|
c.handleUserList(args)
|
|
}
|
|
case "group":
|
|
c.handleGroup(args)
|
|
case "export":
|
|
c.handleExport(args)
|
|
case "import":
|
|
c.handleImport(args)
|
|
case "export-list":
|
|
c.handleExportList(args)
|
|
case "set":
|
|
c.handleSet(args)
|
|
case "unset":
|
|
c.handleUnset(args)
|
|
case "vars":
|
|
c.handleVars(args)
|
|
case "batch", "source":
|
|
c.handleBatch(args, c.executeCommand)
|
|
default:
|
|
fmt.Println(red("Unknown command:"), cmd)
|
|
fmt.Println("Type 'help' for available commands")
|
|
}
|
|
return true
|
|
}
|
|
|
|
func main() {
|
|
client := NewKVSClient("http://localhost:8090")
|
|
|
|
// Load saved profiles
|
|
if config, err := LoadConfig(); err == nil {
|
|
client.syncConfigToClient(config)
|
|
}
|
|
|
|
// Setup readline
|
|
rl, err := readline.NewEx(&readline.Config{
|
|
Prompt: cyan("kvs> "),
|
|
HistoryFile: os.Getenv("HOME") + "/.kvs_history",
|
|
AutoComplete: completer,
|
|
InterruptPrompt: "^C",
|
|
EOFPrompt: "exit",
|
|
})
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
defer rl.Close()
|
|
|
|
fmt.Println(magenta("KVS Interactive Shell"))
|
|
fmt.Println("Type 'help' for available commands")
|
|
if client.activeProfile != "" {
|
|
fmt.Println(green("Active profile:"), client.activeProfile)
|
|
}
|
|
fmt.Println()
|
|
|
|
for {
|
|
line, err := rl.Readline()
|
|
if err != nil {
|
|
break
|
|
}
|
|
|
|
line = strings.TrimSpace(line)
|
|
if line == "" {
|
|
continue
|
|
}
|
|
|
|
if !client.executeCommand(line) {
|
|
return
|
|
}
|
|
}
|
|
}
|