Skip to content

Commit

Permalink
Improvements to JS commands
Browse files Browse the repository at this point in the history
  • Loading branch information
Nigel2392 committed May 8, 2024
1 parent 219943a commit 3dd67cf
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 35 deletions.
27 changes: 16 additions & 11 deletions quickgo/command/step.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ func (s *Step) ParseArgs(env map[string]any) ([]string, []string) {
}

// Execute runs the command.
func (s Step) Execute(env map[string]any) error {
func (s Step) Execute(env map[string]any) ([]byte, []byte, error) {
var (
args []string
envSlice []string
Expand Down Expand Up @@ -70,18 +70,23 @@ func (s Step) Execute(env map[string]any) error {
cmd.Stdout = stdout
cmd.Stderr = stderr

if err := cmd.Run(); err != nil {
return fmt.Errorf("%s: %s", err, stderr.String())
} else {
if stdout.Len() > 0 {
logger.Infof("%s", stdout.String())
}
var err = cmd.Run()
var stdoutB = stdout.Bytes()
var stderrB = stderr.Bytes()

if stderr.Len() > 0 {
logger.Errorf("%s", stderr.String())
}
if err != nil {
return stdoutB, stderrB, fmt.Errorf("%s: %s", err, string(stderrB))
}

if stdout.Len() > 0 {
logger.Info(string(stdoutB))
}

if stderr.Len() > 0 {
logger.Error(string(stderrB))
}
return nil

return stdoutB, stderrB, nil
}

// ExpandArgs expands the arguments.
Expand Down
2 changes: 1 addition & 1 deletion quickgo/command/steplist.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ func (l *StepList) Execute(env map[string]any) error {
}
for _, step := range l.Steps {
logger.Infof("Executing step: '%s'", step.Name)
if err := step.Execute(env); err != nil {
if _, _, err := step.Execute(env); err != nil {
return &Error{
Message: "failed to execute step",
Err: err,
Expand Down
16 changes: 15 additions & 1 deletion quickgo/js/js.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ type (
// The name of the main function to run.
Main string

// An override of a VM to use.
_VM *goja.Runtime

_Globals map[string]any
_Funcs []VMFunc
}
Expand Down Expand Up @@ -42,6 +45,12 @@ func WithConsole(s *Command) {
s._Globals["console"] = Console()
}

func WithVM(vm *goja.Runtime) OptFunc {
return func(s *Command) {
s._VM = vm
}
}

func NewScript(mainFunc string, options ...OptFunc) (cmd *Command) {
var s = &Command{
Main: mainFunc,
Expand All @@ -62,7 +71,12 @@ func (s *Command) AddFunc(f ...VMFunc) {

func (s *Command) Run(scriptSource string) (err error) {

var vm = goja.New()
var vm *goja.Runtime
if s._VM != nil {
vm = s._VM
} else {
vm = goja.New()
}

vm.SetFieldNameMapper(
goja.TagFieldNameMapper("json", true),
Expand Down
86 changes: 65 additions & 21 deletions quickgo/quickgo_commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ import (
"fmt"
"io"
"os"
"os/exec"
"path/filepath"
"strings"

"github.com/Nigel2392/quickgo/v2/quickgo/command"
"github.com/Nigel2392/quickgo/v2/quickgo/config"
"github.com/Nigel2392/quickgo/v2/quickgo/js"
"github.com/Nigel2392/quickgo/v2/quickgo/logger"
Expand Down Expand Up @@ -45,16 +45,17 @@ func (a *App) ListJSFiles() ([]string, error) {

func (a *App) SaveJS(path string) error {
var (
dirPath = GetQuickGoPath(config.COMMANDS_DIR)
filename = filepath.Join(dirPath, filepath.Base(path))
scriptSrc *os.File
file *os.File
err error
dirPath = GetQuickGoPath(config.COMMANDS_DIR)
scriptName = filepath.Base(path)
outputName = filepath.Join(dirPath, scriptName)
scriptSrc *os.File
file *os.File
err error
)

path = filepath.FromSlash(path)

logger.Infof("Copying file %s to %s", path, filename)
logger.Infof("Copying file %s to %s", path, outputName)

if s, err := os.Stat(path); err != nil || s.IsDir() {
return errors.Wrapf(err, "file %s does not exist or is not a valid file", path)
Expand All @@ -65,7 +66,7 @@ func (a *App) SaveJS(path string) error {
}

file, err = os.Create(
filename,
outputName,
)
if err != nil {
return errors.Wrapf(err, "failed to create file %s", path)
Expand All @@ -78,7 +79,13 @@ func (a *App) SaveJS(path string) error {
}

_, err = io.Copy(file, scriptSrc)
return errors.Wrapf(err, "failed to copy file %s to %s", path, file.Name())
if err != nil {
return errors.Wrapf(err, "failed to copy file %s to %s", path, file.Name())
}

logger.Infof("Command '%s' saved to '%s'", scriptName, outputName)

return nil
}

func (a *App) ExecJS(targetDir string, scriptName string, args map[string]any) (err error) {
Expand All @@ -92,24 +99,29 @@ func (a *App) ExecJS(targetDir string, scriptName string, args map[string]any) (
cmd *js.Command
)

logger.Debugf("Reading script '%s'", scriptPath)

script, err = os.ReadFile(scriptPath)
if err != nil {
return errors.Wrapf(err, "failed to read script %s", script)
}

logger.Debugf("'%s' has access to project config: %v", scriptName, a.ProjectConfig != nil)
var (
projectName string
projectPath string
)
if a.ProjectConfig != nil {
projectName = a.ProjectConfig.Name
projectPath = getTargetDirectory(
projectName,
targetDir,
)
}

var vm = goja.New()
cmd = js.NewScript(
"main",
js.WithVM(vm),
js.WithGlobals(map[string]any{
"quickgo": map[string]any{
"app": a,
Expand All @@ -128,9 +140,15 @@ func (a *App) ExecJS(targetDir string, scriptName string, args map[string]any) (
return getTargetDirectory(targetDir)
},
"setEnv": func(key, value string) error {
logger.Debugf("Setting environment variable '%s'='%s'", key, value)
return os.Setenv(key, value)
},
"exec": func(cmd string, commandArgs ...string) error {
"exec": func(cmd string, commandArgs ...string) goja.Value {

logger.Debugf(
"Executing command from '%s': %s %s",
scriptPath, cmd, strings.Join(commandArgs, " "),
)

// Parse the command arguments if the command is provided as a single string.
// Example: echo "Hello, World!" -> echo, ["Hello, World!"]
Expand All @@ -142,11 +160,11 @@ func (a *App) ExecJS(targetDir string, scriptName string, args map[string]any) (
s[1],
)
if err != nil {
return errors.Wrapf(
err,
"failed to split command arguments for: %s",
scriptPath,
logger.Errorf(
"failed to split command arguments for: %s: %s",
scriptPath, err,
)
return goja.Undefined()
}
} else {
logger.Warnf(
Expand All @@ -156,13 +174,26 @@ func (a *App) ExecJS(targetDir string, scriptName string, args map[string]any) (
}
}

var c = command.Step{
Name: fmt.Sprintf("%s %s", cmd, strings.Join(commandArgs, " ")),
Command: cmd,
Args: commandArgs,
var command = exec.Command(cmd, commandArgs...)
var s = new(strings.Builder)

command.Stdout = s
command.Stderr = s

if err = command.Run(); err != nil {
logger.Errorf(
"failed to execute command: %s: %s",
scriptPath, err,
)
return goja.Undefined()
}

return c.Execute(nil)
logger.Debugf(
"Command executed from '%s': %s %s",
scriptPath, cmd, strings.Join(commandArgs, " "),
)

return vm.ToValue(s.String())
},
},
}),
Expand Down Expand Up @@ -209,7 +240,13 @@ func (a *App) ExecJS(targetDir string, scriptName string, args map[string]any) (
b = []byte(data.String())
}

return os.WriteFile(path, b, os.ModePerm)
err = os.WriteFile(path, b, os.ModePerm)
if err != nil {
logger.Error(err)
return err
}
logger.Debugf("File '%s' written by '%s'", path, scriptPath)
return nil
})
vm.Set("readFile", func(path string) goja.Value {
var data []byte
Expand All @@ -219,6 +256,8 @@ func (a *App) ExecJS(targetDir string, scriptName string, args map[string]any) (
return goja.Undefined()
}

logger.Debugf("File '%s' read by '%s'", path, scriptPath)

var arr = vm.NewArrayBuffer(data)
return vm.ToValue(arr)
})
Expand All @@ -228,11 +267,16 @@ func (a *App) ExecJS(targetDir string, scriptName string, args map[string]any) (
logger.Error(err)
return ""
}

logger.Debugf("File '%s' read by '%s'", path, scriptPath)

return string(data)
})

return nil
})

logger.Debugf("Executing script '%s'", scriptPath)

return cmd.Run(string(script))
}
2 changes: 1 addition & 1 deletion quickgo/quickgo_http.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@ func (a *App) HttpHandler() http.Handler {
})
mux.Handle("/favicon.ico", &LogHandler{
Handler: http.HandlerFunc(a.serveFavicon),
Level: logger.DebugLevel,
Where: "favicon",
Level: logger.DebugLevel,
})
return a.middleware(mux)
}
Expand Down

0 comments on commit 3dd67cf

Please sign in to comment.