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 3dd67cf commit d7adc9f
Showing 1 changed file with 156 additions and 109 deletions.
265 changes: 156 additions & 109 deletions quickgo/quickgo_commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,84 +118,173 @@ func (a *App) ExecJS(targetDir string, scriptName string, args map[string]any) (
)
}

var vm = goja.New()
cmd = js.NewScript(
"main",
js.WithVM(vm),
js.WithGlobals(map[string]any{
"quickgo": map[string]any{
"app": a,
"project": a.ProjectConfig,
"config": a.Config,
"environ": args,
"projectName": projectName,
"projectPath": projectPath,
var (
vm = goja.New()
quickgoModule = map[string]any{
"app": a,
"project": a.ProjectConfig,
"config": a.Config,
"environ": args,
"projectName": projectName,
"projectPath": projectPath,
}
fsModule = map[string]any{
"cleanPath": filepath.Clean,
"joinPath": filepath.Join,
"absPath": func(path string) string {
path, err = filepath.Abs(path)
if err != nil {
logger.Error(err)
return ""
}
return path
},
"os": map[string]any{
"args": os.Args,
"getEnv": func(key string) string {
return os.Getenv(key)
},
"getWd": func() string {
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) goja.Value {

logger.Debugf(
"Executing command from '%s': %s %s",
scriptPath, cmd, strings.Join(commandArgs, " "),
)
"writeFile": func(path string, data goja.Value) error {
var b []byte
if vm.InstanceOf(data, vm.Get("Uint8Array").ToObject(vm)) {
b = data.Export().([]byte)
} else if d, ok := data.Export().(goja.ArrayBuffer); ok {
b = d.Bytes()
} else {
b = []byte(data.String())
}

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
},
"readFile": func(path string) goja.Value {
var data []byte
var err error
if data, err = os.ReadFile(path); err != nil {
logger.Error(err)
return goja.Undefined()
}

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

var arr = vm.NewArrayBuffer(data)
return vm.ToValue(arr)
},
"readTextFile": func(path string) string {
var data, err = os.ReadFile(path)
if err != nil {
logger.Error(err)
return ""
}

// Parse the command arguments if the command is provided as a single string.
// Example: echo "Hello, World!" -> echo, ["Hello, World!"]
if strings.Index(cmd, " ") > 0 {
var s = strings.SplitN(cmd, " ", 2)
cmd = s[0]
if len(commandArgs) == 0 {
commandArgs, err = shellquote.Split(
s[1],
)
if err != nil {
logger.Errorf(
"failed to split command arguments for: %s: %s",
scriptPath, err,
)
return goja.Undefined()
}
} else {
logger.Warnf(
"command arguments are provided, but the command is already split for: %s",
scriptPath,
logger.Debugf("File '%s' read by '%s'", path, scriptPath)

return string(data)
},
"readDir": func(path string) goja.Value {

path, err = filepath.Abs(path)
if err != nil {
logger.Error(err)
return goja.Undefined()
}

var dir, err = os.ReadDir(path)
if err != nil {
logger.Error(err)
return goja.Undefined()
}

var d = make([]any, len(dir))
for i, f := range dir {
d[i] = map[string]any{
"name": f.Name(),
"isDirectory": f.IsDir(),
"isFile": f.Type().IsRegular(),
"path": filepath.Join(
path, f.Name(),
),
}
}

return vm.ToValue(
vm.NewArray(d...),
)
},
}
osModule = map[string]any{
"args": os.Args,
"getEnv": func(key string) string {
return os.Getenv(key)
},
"getWd": func() string {
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) 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!"]
if strings.Index(cmd, " ") > 0 {
var s = strings.SplitN(cmd, " ", 2)
cmd = s[0]
if len(commandArgs) == 0 {
commandArgs, err = shellquote.Split(
s[1],
)
if err != nil {
logger.Errorf(
"failed to split command arguments for: %s: %s",
scriptPath, err,
)
return goja.Undefined()
}
} else {
logger.Warnf(
"command arguments are provided, but the command is already split for: %s",
scriptPath,
)
}
}

var command = exec.Command(cmd, commandArgs...)
var s = new(strings.Builder)

command.Stdout = s
command.Stderr = s
var command = exec.Command(cmd, commandArgs...)
var s = new(strings.Builder)

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

logger.Debugf(
"Command executed from '%s': %s %s",
scriptPath, cmd, strings.Join(commandArgs, " "),
if err = command.Run(); err != nil {
logger.Errorf(
"failed to execute command: %s: %s",
scriptPath, err,
)
return goja.Undefined()
}

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

return vm.ToValue(s.String())
},
return vm.ToValue(s.String())
},
}
)
cmd = js.NewScript(
"main",
js.WithVM(vm),
js.WithGlobals(map[string]any{
"quickgo": quickgoModule,
"os": osModule,
"fs": fsModule,
}),
)

Expand Down Expand Up @@ -230,48 +319,6 @@ func (a *App) ExecJS(targetDir string, scriptName string, args map[string]any) (
var arrBuff = vm.NewArrayBuffer(arr)
return vm.ToValue(arrBuff)
})
vm.Set("writeFile", func(path string, data goja.Value) error {
var b []byte
if vm.InstanceOf(data, vm.Get("Uint8Array").ToObject(vm)) {
b = data.Export().([]byte)
} else if d, ok := data.Export().(goja.ArrayBuffer); ok {
b = d.Bytes()
} else {
b = []byte(data.String())
}

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
var err error
if data, err = os.ReadFile(path); err != nil {
logger.Error(err)
return goja.Undefined()
}

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

var arr = vm.NewArrayBuffer(data)
return vm.ToValue(arr)
})
vm.Set("readTextFile", func(path string) string {
var data, err = os.ReadFile(path)
if err != nil {
logger.Error(err)
return ""
}

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

return string(data)
})

return nil
})
Expand Down

0 comments on commit d7adc9f

Please sign in to comment.