delete added, more details below #3

Merged
jake merged 1 commits from dev/delete into main 2025-04-17 21:25:54 +00:00
8 changed files with 121 additions and 17 deletions
Showing only changes of commit 658adfbe16 - Show all commits

View File

@ -10,7 +10,7 @@ go install code.jakeyoungdev.com/jake/mctl@main #it is recommended to use a tagg
## Setup
### Configuring mctl
mctl requires a one-time setup via the 'config' command, password is entered securely from the terminal
mctl requires a one-time setup via the 'config' command before interacting with any servers, password is entered securely from the terminal
```bash
mctl config -s <serveraddress> -p <rconport>
```
@ -65,6 +65,12 @@ mctl run test jake
#will run: tp jake 0 0 0 on remote server
```
### Delete saved command
Commands can be deleted with:
```bash
mctl delete <name>
```
## Documentation
### Commands
|Command|Description|
@ -73,6 +79,7 @@ mctl run test jake
|login|makes connection request to the server using saved configuration and enters command loop|
|save \<name>|saves specific command for reuse|
|view \<name>|displays saved command|
|delete \<name>|deletes saved command|
|run \<name> args...|runs saved command filling placeholders with supplied args|
### Flags

View File

@ -86,6 +86,11 @@ func initConfig() {
_, err := rand.Read(uu)
cobra.CheckErr(err)
//create custom command map
cmdMap := make(map[string]any, 0)
//write config
viper.Set("customcmd", cmdMap)
viper.Set("device", string(uu))
viper.SafeWriteConfig()
}

42
cmd/delete.go Normal file
View File

@ -0,0 +1,42 @@
/*
Copyright © 2025 Jake jake.young.dev@gmail.com
*/
package cmd
import (
"errors"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
// deleteCmd represents the delete command
var deleteCmd = &cobra.Command{
Use: "delete <name>",
Example: "mctl delete newcmd",
Short: "Delete a saved command",
Long: `Deletes a command stored using the save command`,
Run: func(cmd *cobra.Command, args []string) {
var cm map[string]any
cmdMap := viper.Get("customcmd")
if cmdMap == nil {
cm = make(map[string]any, 0)
} else {
cm = cmdMap.(map[string]any)
}
delete(cm, args[0])
viper.Set("customcmd", cmdMap)
viper.WriteConfig()
},
PreRunE: func(cmd *cobra.Command, args []string) error {
if len(args) == 0 {
return errors.New("name argument is required")
}
return nil
},
}
func init() {
rootCmd.AddCommand(deleteCmd)
}

View File

@ -5,6 +5,7 @@ package cmd
import (
"bufio"
"errors"
"fmt"
"os"
@ -17,6 +18,7 @@ import (
var loginCmd = &cobra.Command{
Use: "login",
Example: "mctl login",
SilenceUsage: true,
Short: "Login to server and send commands",
Long: `Login to server using saved config and enter command loop
sending commands to server and printing the response.`,
@ -54,6 +56,13 @@ var loginCmd = &cobra.Command{
fmt.Printf("Disconnected from %s\n", server)
},
PreRunE: func(cmd *cobra.Command, args []string) error {
//ensure config command has been run
if viper.Get("server") == "" || viper.Get("password") == "" || viper.Get("port") == 0 {
return errors.New("the 'config' command must be run before you can interact with servers")
}
return nil
},
}
func init() {

View File

@ -28,6 +28,5 @@ func Execute() {
}
func init() {
//dont show completion subcommand in help message, makes the syntax confusing
rootCmd.Root().CompletionOptions.DisableDefaultCmd = true
}

View File

@ -17,12 +17,26 @@ import (
var runCmd = &cobra.Command{
Use: "run <name> args...",
Example: "mctl run savedcmd 63 jake",
SilenceUsage: true,
Short: "Runs a previously saved command with supplied arguments on remote server",
Long: `Loads a saved command, injects the supplied arguments into the command, and sends the command to the remove server
printing the response`,
Run: func(cmd *cobra.Command, args []string) {
//grab saved command
cmdName := viper.Get(fmt.Sprintf("customCmd-%s", args[0])).(string)
//check for command map
var cm map[string]any
cmdMap := viper.Get("customcmd")
if cmdMap == nil {
cm = make(map[string]any, 0)
} else {
cm = cmdMap.(map[string]any)
}
//is this an existing command
cmdRun, ok := cm[args[0]]
if !ok {
fmt.Printf("command %s not found", args[0])
return
}
//convert arguments to interface
var nargs []any
for _, a := range args[1:] {
@ -30,7 +44,7 @@ var runCmd = &cobra.Command{
}
//inject arguments
fixed := fmt.Sprintf(cmdName, nargs...)
fixed := fmt.Sprintf(cmdRun.(string), nargs...)
fmt.Printf("Running saved command %s\n", fixed)
//create client and send command
@ -44,13 +58,20 @@ var runCmd = &cobra.Command{
fmt.Println(res)
},
PreRunE: func(cmd *cobra.Command, args []string) error {
//ensure configuration has been setup
if viper.Get("server") == "" || viper.Get("password") == "" || viper.Get("port") == 0 {
return errors.New("the 'config' command must be run before you can interact with servers")
}
//ensure we have a command name
al := len(args)
if al == 0 {
return errors.New("name argument is required")
}
cmdCheck := viper.Get(fmt.Sprintf("customCmd-%s", args[0]))
count := strings.Count(cmdCheck.(string), "%s")
cmdMap := viper.Get("customcmd").(map[string]any)
count := strings.Count(cmdMap[args[0]].(string), "%s")
//make sure enough arguments are sent to fill command placeholders
if al < count+1 {
return fmt.Errorf("not enough arguments to populate command. Supplied: %d, Needed: %d", al-1, count)

View File

@ -27,10 +27,17 @@ var saveCmd = &cobra.Command{
if sc.Scan() {
txt := sc.Text()
if txt != "" {
viper.Set(fmt.Sprintf("customCmd-%s", args[0]), txt)
var cmdMap map[string]any
cm := viper.Get("customcmd")
if cmdMap == nil {
cmdMap = make(map[string]any, 0)
} else {
cmdMap = cm.(map[string]any)
}
cmdMap[args[0]] = txt
viper.Set("customcmd", cmdMap)
viper.WriteConfig()
fmt.Println("\nSaved!")
return
}
}
},

View File

@ -18,7 +18,21 @@ var viewCmd = &cobra.Command{
Short: "View saved commands",
Long: `Load command using the supplied name and displays it in the terminal`,
Run: func(cmd *cobra.Command, args []string) {
fmt.Printf("\nCommand: %s\n", viper.Get(args[0]))
var cm map[string]any
cmdMap := viper.Get("customcmd")
if cmdMap == nil {
fmt.Println("no custom commands found")
return
}
cm = cmdMap.(map[string]any)
custom, ok := cm[args[0]]
if !ok {
fmt.Println("command not found")
return
}
fmt.Printf("Command: %s", custom.(string))
},
PreRunE: func(cmd *cobra.Command, args []string) error {
if len(args) == 0 {