Skip to content

Commit

Permalink
Adds possibility to pass arguments to macro commands
Browse files Browse the repository at this point in the history
  • Loading branch information
ksysoev committed Dec 31, 2023
1 parent dfd3c35 commit 5c39f1c
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 39 deletions.
7 changes: 6 additions & 1 deletion pkg/command/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,13 @@ func Factory(raw string, macro *Macro) (Executer, error) {

return NewSleepCommand(time.Duration(sec) * time.Second), nil
default:
args := ""
if len(parts) > 1 {
args = parts[1]
}

if macro != nil {
return macro.Get(cmd)
return macro.Get(cmd, args)
}

return nil, &ErrUnknownCommand{cmd}
Expand Down
80 changes: 61 additions & 19 deletions pkg/command/macro.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package command

import (
"bytes"
"fmt"
"log"
"os"
"strings"
"text/template"

"gopkg.in/yaml.v3"
)
Expand All @@ -16,7 +18,7 @@ type Config struct {
}

type Macro struct {
macro map[string]Executer
macro map[string]*MacroTemplates
domains []string
}

Expand All @@ -25,7 +27,7 @@ type Macro struct {
// Returns a pointer to the newly created Macro instance.
func NewMacro(domains []string) *Macro {
return &Macro{
macro: make(map[string]Executer),
macro: make(map[string]*MacroTemplates),
domains: domains,
}
}
Expand All @@ -40,25 +42,17 @@ func (m *Macro) AddCommands(name string, rawCommands []string) error {
return &ErrDuplicateMacro{name}
}

commands := []Executer{}
if len(rawCommands) == 0 {
return ErrEmptyMacro{name}
}

for _, rawCommand := range rawCommands {
cmd, err := Factory(rawCommand, nil)
if err != nil {
return err
}
templs, err := NewMacroTemplates(rawCommands)

commands = append(commands, cmd)
if err != nil {
return err
}

switch len(commands) {
case 0:
return ErrEmptyMacro{name}
case 1:
m.macro[name] = commands[0]
default:
m.macro[name] = NewSequence(commands)
}
m.macro[name] = templs

return nil
}
Expand All @@ -78,9 +72,10 @@ func (m *Macro) merge(macro *Macro) error {
}

// Get returns the Executer associated with the given name, or an error if the name is not found.
func (m *Macro) Get(name string) (Executer, error) {
func (m *Macro) Get(name, argString string) (Executer, error) {
if cmd, ok := m.macro[name]; ok {
return cmd, nil
args := strings.Fields(argString)
return cmd.GetExecuter(args)
}

return nil, &ErrUnknownCommand{name}
Expand Down Expand Up @@ -172,3 +167,50 @@ func LoadMacroForDomain(macroDir, domain string) (*Macro, error) {

return macro, nil
}

type MacroTemplates struct {
list []*template.Template
}

func NewMacroTemplates(templates []string) (*MacroTemplates, error) {
tmpls := &MacroTemplates{}
tmpls.list = make([]*template.Template, len(templates))

for i, rawTempl := range templates {
tmpl, err := template.New("macro").Parse(rawTempl)
if err != nil {
return nil, err
}

tmpls.list[i] = tmpl
}

return tmpls, nil
}

func (t *MacroTemplates) GetExecuter(args []string) (Executer, error) {
data := struct {
Args []string
}{args}
cmds := make([]Executer, len(t.list))

for i, tmpl := range t.list {
var output bytes.Buffer
if err := tmpl.Execute(&output, data); err != nil {
return nil, err
}

cmd, err := Factory(output.String(), nil)
if err != nil {
return nil, err
}

cmds[i] = cmd
}

if len(cmds) == 1 {
return cmds[0], nil
}

return NewSequence(cmds), nil
}
39 changes: 20 additions & 19 deletions pkg/command/macro_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@ func TestNewMacro(t *testing.T) {
name: "empty domains",
domains: []string{},
want: &Macro{
macro: make(map[string]Executer),
macro: make(map[string]*MacroTemplates),
domains: []string{},
},
},
{
name: "non-empty domains",
domains: []string{"example.com", "google.com"},
want: &Macro{
macro: make(map[string]Executer),
macro: make(map[string]*MacroTemplates),
domains: []string{"example.com", "google.com"},
},
},
Expand Down Expand Up @@ -58,7 +58,7 @@ func TestMacro_AddCommands(t *testing.T) {
},
{
name: "add existing macro",
macro: &Macro{macro: map[string]Executer{"test": nil}},
macro: &Macro{macro: map[string]*MacroTemplates{"test": nil}},
commandName: "test",
commands: []string{"send hello"},
wantErr: true,
Expand Down Expand Up @@ -106,11 +106,11 @@ func TestMacro_Merge(t *testing.T) {
{
name: "merge empty macro with empty macro",
macro: &Macro{
macro: make(map[string]Executer),
macro: make(map[string]*MacroTemplates),
domains: []string{},
},
otherMacro: &Macro{
macro: make(map[string]Executer),
macro: make(map[string]*MacroTemplates),
domains: []string{},
},
wantErr: false,
Expand All @@ -119,13 +119,13 @@ func TestMacro_Merge(t *testing.T) {
{
name: "merge non-empty macro with empty macro",
macro: &Macro{
macro: map[string]Executer{
macro: map[string]*MacroTemplates{
"test": nil,
},
domains: []string{},
},
otherMacro: &Macro{
macro: make(map[string]Executer),
macro: make(map[string]*MacroTemplates),
domains: []string{},
},
wantErr: false,
Expand All @@ -134,11 +134,11 @@ func TestMacro_Merge(t *testing.T) {
{
name: "merge empty macro with non-empty macro",
macro: &Macro{
macro: make(map[string]Executer),
macro: make(map[string]*MacroTemplates),
domains: []string{},
},
otherMacro: &Macro{
macro: map[string]Executer{
macro: map[string]*MacroTemplates{
"test": nil,
},
domains: []string{},
Expand All @@ -149,13 +149,13 @@ func TestMacro_Merge(t *testing.T) {
{
name: "merge non-empty macro with non-empty macro",
macro: &Macro{
macro: map[string]Executer{
macro: map[string]*MacroTemplates{
"test": nil,
},
domains: []string{},
},
otherMacro: &Macro{
macro: map[string]Executer{
macro: map[string]*MacroTemplates{
"test2": nil,
},
domains: []string{},
Expand All @@ -166,13 +166,13 @@ func TestMacro_Merge(t *testing.T) {
{
name: "merge macro with duplicate macro name",
macro: &Macro{
macro: map[string]Executer{
macro: map[string]*MacroTemplates{
"test": nil,
},
domains: []string{},
},
otherMacro: &Macro{
macro: map[string]Executer{
macro: map[string]*MacroTemplates{
"test": nil,
},
domains: []string{},
Expand All @@ -194,6 +194,7 @@ func TestMacro_Merge(t *testing.T) {
}
}
func TestMacro_Get(t *testing.T) {
testTemplate, _ := NewMacroTemplates([]string{"exit"})
tests := []struct {
name string
macro *Macro
Expand All @@ -204,31 +205,31 @@ func TestMacro_Get(t *testing.T) {
}{
{
name: "get existing command",
macro: &Macro{macro: map[string]Executer{"test": NewExit()}},
macro: &Macro{macro: map[string]*MacroTemplates{"test": testTemplate}},
cmdName: "test",
wantCmd: NewExit(),
wantErr: false,
errMsg: "",
},
{
name: "get non-existing command",
macro: &Macro{macro: map[string]Executer{}},
macro: &Macro{macro: map[string]*MacroTemplates{}},
cmdName: "test",
wantCmd: nil,
wantErr: true,
errMsg: "unknown command: test",
},
{
name: "get command with empty macro",
macro: &Macro{macro: map[string]Executer{}},
macro: &Macro{macro: map[string]*MacroTemplates{}},
cmdName: "",
wantCmd: nil,
wantErr: true,
errMsg: "unknown command: ",
},
{
name: "get command with non-empty macro",
macro: &Macro{macro: map[string]Executer{"test": nil}},
macro: &Macro{macro: map[string]*MacroTemplates{"test": nil}},
cmdName: "",
wantCmd: nil,
wantErr: true,
Expand All @@ -238,7 +239,7 @@ func TestMacro_Get(t *testing.T) {

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
cmd, err := tt.macro.Get(tt.cmdName)
cmd, err := tt.macro.Get(tt.cmdName, "")
if (err != nil) != tt.wantErr {
t.Errorf("Macro.Get() error = %v, wantErr %v", err, tt.wantErr)
}
Expand Down Expand Up @@ -297,7 +298,7 @@ macro:
t.Errorf("LoadFromFile() domain = %s, want %s", macro.domains[0], domain)
}

cmd, err := macro.Get("test")
cmd, err := macro.Get("test", "")

if err != nil {
t.Errorf("LoadFromFile() error = %v, want nil", err)
Expand Down

0 comments on commit 5c39f1c

Please sign in to comment.