mirror of
https://github.com/mcuadros/ascode
synced 2024-11-22 17:02:03 +01:00
starlark/module: os, added command function
This commit is contained in:
parent
e2a245a645
commit
4d4f1058d3
1
go.mod
1
go.mod
@ -8,6 +8,7 @@ require (
|
||||
github.com/docker/distribution v2.7.1+incompatible // indirect
|
||||
github.com/docker/go-metrics v0.0.1 // indirect
|
||||
github.com/go-git/go-git/v5 v5.0.0
|
||||
github.com/gobs/args v0.0.0-20180315064131-86002b4df18c
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e // indirect
|
||||
github.com/hashicorp/go-hclog v0.11.0
|
||||
github.com/hashicorp/go-plugin v1.0.1-0.20190610192547-a1bc61569a26
|
||||
|
2
go.sum
2
go.sum
@ -211,6 +211,8 @@ github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/me
|
||||
github.com/go-test/deep v1.0.1/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
|
||||
github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68=
|
||||
github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
|
||||
github.com/gobs/args v0.0.0-20180315064131-86002b4df18c h1:3r/O0iUDMwVJx8XCrjcUvfmfbVP3poiT+1dLyYzx8+w=
|
||||
github.com/gobs/args v0.0.0-20180315064131-86002b4df18c/go.mod h1:ZpqkpUmnBz2Jz7hMGSPRbHtYC82FP/IZ1Y7A2riYH0s=
|
||||
github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
|
@ -1,10 +1,13 @@
|
||||
package os
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"sync"
|
||||
|
||||
gobs "github.com/gobs/args"
|
||||
"go.starlark.net/starlark"
|
||||
"go.starlark.net/starlarkstruct"
|
||||
)
|
||||
@ -26,6 +29,7 @@ const (
|
||||
removeAllFuncName = "remove_all"
|
||||
renameFuncName = "rename"
|
||||
tempDirFuncName = "temp_dir"
|
||||
commandFuncName = "command"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -57,6 +61,7 @@ func LoadModule() (starlark.StringDict, error) {
|
||||
removeAllFuncName: starlark.NewBuiltin(mkdirFuncName, RemoveAll),
|
||||
renameFuncName: starlark.NewBuiltin(renameFuncName, Rename),
|
||||
tempDirFuncName: starlark.NewBuiltin(tempDirFuncName, TempDir),
|
||||
commandFuncName: starlark.NewBuiltin(commandFuncName, Command),
|
||||
},
|
||||
},
|
||||
}
|
||||
@ -335,3 +340,97 @@ func Rename(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, k
|
||||
func TempDir(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
|
||||
return starlark.String(os.TempDir()), nil
|
||||
}
|
||||
|
||||
// Command runs the command and returns its standard output.
|
||||
//
|
||||
// outline: os
|
||||
// functions:
|
||||
// command(command, shell?, dir?, combined?, env?)
|
||||
// runs the command and returns its standard output. If the exit code
|
||||
// it different to zero, an error is triggered.
|
||||
// params:
|
||||
// shell bool
|
||||
// if True execute the command inside of a shell.
|
||||
// dir string
|
||||
// working directory of the command.
|
||||
// combined bool
|
||||
// if True returns combined standard output and standard error.
|
||||
// env list
|
||||
// specifies the environment of the process, each value of the list
|
||||
// should follow the pattern "key=value".
|
||||
func Command(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
|
||||
var (
|
||||
command string
|
||||
env *starlark.List
|
||||
dir string
|
||||
combined bool
|
||||
shell bool
|
||||
)
|
||||
|
||||
err := starlark.UnpackArgs(renameFuncName, args, kwargs,
|
||||
"command", &command,
|
||||
"env?", &env,
|
||||
"dir?", &dir,
|
||||
"combined?", &combined,
|
||||
"shell?", &shell,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if shell {
|
||||
command = fmt.Sprintf("sh -c %q", command)
|
||||
}
|
||||
|
||||
cmdArgs := gobs.GetArgs(command)
|
||||
bin, err := exec.LookPath(cmdArgs[0])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
environment, err := unpackListArg(renameFuncName, "env", env)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cmd := &exec.Cmd{
|
||||
Path: bin,
|
||||
Args: cmdArgs,
|
||||
Env: append(os.Environ(), environment...),
|
||||
Dir: dir,
|
||||
}
|
||||
|
||||
var output []byte
|
||||
if combined {
|
||||
output, err = cmd.CombinedOutput()
|
||||
} else {
|
||||
output, err = cmd.Output()
|
||||
}
|
||||
|
||||
if len(output) >= 1 && output[len(output)-1] == '\n' {
|
||||
output = output[:len(output)-1]
|
||||
}
|
||||
|
||||
return starlark.String(output), err
|
||||
}
|
||||
|
||||
func unpackListArg(fnName, argName string, l *starlark.List) ([]string, error) {
|
||||
if l == nil {
|
||||
return []string{}, nil
|
||||
}
|
||||
|
||||
output := make([]string, l.Len())
|
||||
for i := 0; i < l.Len(); i++ {
|
||||
s, ok := l.Index(i).(starlark.String)
|
||||
if ok {
|
||||
output[i] = s.GoString()
|
||||
continue
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("%s: parameter %q expected string at index %d", fnName, argName, i)
|
||||
|
||||
}
|
||||
|
||||
return output, nil
|
||||
}
|
||||
|
@ -17,6 +17,9 @@ func TestFile(t *testing.T) {
|
||||
}
|
||||
|
||||
resolve.AllowFloat = true
|
||||
resolve.AllowGlobalReassign = true
|
||||
resolve.AllowLambda = true
|
||||
|
||||
thread := &starlark.Thread{Load: testdata.NewLoader(LoadModule, ModuleName)}
|
||||
starlarktest.SetReporter(thread, t)
|
||||
|
||||
|
21
starlark/module/os/testdata/test.star
vendored
21
starlark/module/os/testdata/test.star
vendored
@ -34,3 +34,24 @@ os.remove_all("bar")
|
||||
|
||||
def deleteNotExistant(): os.remove("foo")
|
||||
assert.fails(deleteNotExistant, "remove foo: no such file or directory")
|
||||
|
||||
# test command
|
||||
temp = os.temp_dir() + "/example-dir"
|
||||
os.mkdir_all(temp + "/foo/bar", 0o755)
|
||||
os.chdir(temp)
|
||||
|
||||
assert.eq(os.command("ls -1"), "foo")
|
||||
|
||||
# test command dir
|
||||
assert.eq(os.command("ls -1", dir="foo"), "bar")
|
||||
|
||||
# test command shell and env
|
||||
assert.eq(os.command("echo $FOO", shell=True, env=["FOO=foo"]), "foo")
|
||||
|
||||
# test command combined
|
||||
assert.ne(os.command("not-exists || true", shell=True, combined=True), "")
|
||||
|
||||
# test command error
|
||||
assert.fails(lambda: os.command("not-exists"), "executable file not found")
|
||||
|
||||
os.remove_all(temp)
|
||||
|
Loading…
Reference in New Issue
Block a user