Files
kvs-sh/cmd_variables.go
ryyst efaa5cdcc9 feat: add shell scripting with variables
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>
2025-10-06 00:01:36 +03:00

85 lines
2.0 KiB
Go

package main
import (
"fmt"
"os"
"regexp"
"strings"
)
// handleSet sets a shell variable
func (c *KVSClient) handleSet(args []string) {
if len(args) < 2 {
fmt.Println(red("Usage: set <name> <value>"))
fmt.Println("Example: set USER_ID abc-123")
return
}
name := args[0]
value := strings.Join(args[1:], " ")
c.variables[name] = value
fmt.Printf(green("Set:")+" %s = %s\n", name, value)
}
// handleUnset removes a shell variable
func (c *KVSClient) handleUnset(args []string) {
if len(args) < 1 {
fmt.Println(red("Usage: unset <name>"))
return
}
name := args[0]
if _, exists := c.variables[name]; exists {
delete(c.variables, name)
fmt.Println(green("Unset:"), name)
} else {
fmt.Println(yellow("Variable not set:"), name)
}
}
// handleVars lists all shell variables
func (c *KVSClient) handleVars(args []string) {
if len(c.variables) == 0 {
fmt.Println(yellow("No variables set"))
return
}
fmt.Println(cyan("Shell Variables:"))
for name, value := range c.variables {
fmt.Printf(" %s = %s\n", name, value)
}
}
// expandVariables performs variable substitution on a string
// Supports:
// - $VAR or ${VAR} for shell variables
// - $ENV:VAR for environment variables
func (c *KVSClient) expandVariables(input string) string {
// Pattern for $VAR or ${VAR}
varPattern := regexp.MustCompile(`\$\{?([A-Za-z_][A-Za-z0-9_]*)\}?`)
// Pattern for $ENV:VAR
envPattern := regexp.MustCompile(`\$ENV:([A-Za-z_][A-Za-z0-9_]*)`)
// First, replace environment variables
result := envPattern.ReplaceAllStringFunc(input, func(match string) string {
varName := envPattern.FindStringSubmatch(match)[1]
if value, exists := os.LookupEnv(varName); exists {
return value
}
return match // Leave unchanged if not found
})
// Then, replace shell variables
result = varPattern.ReplaceAllStringFunc(result, func(match string) string {
varName := varPattern.FindStringSubmatch(match)[1]
if value, exists := c.variables[varName]; exists {
return value
}
return match // Leave unchanged if not found
})
return result
}