This commit is contained in:
parent
143ca8d555
commit
e1b53f8bea
2 changed files with 60 additions and 0 deletions
|
|
@ -13,6 +13,7 @@ import (
|
||||||
type OSProvider interface {
|
type OSProvider interface {
|
||||||
LookupEnv(string) (string, bool)
|
LookupEnv(string) (string, bool)
|
||||||
Exec(ctx context.Context, cmd string, args ...string) (*exec.Cmd, error)
|
Exec(ctx context.Context, cmd string, args ...string) (*exec.Cmd, error)
|
||||||
|
ExecBang(ctx context.Context, cmd string) (*exec.Cmd, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type osHandlers struct {
|
type osHandlers struct {
|
||||||
|
|
@ -29,6 +30,7 @@ func OS() ucl.Module {
|
||||||
Builtins: map[string]ucl.BuiltinHandler{
|
Builtins: map[string]ucl.BuiltinHandler{
|
||||||
"env": osh.env,
|
"env": osh.env,
|
||||||
"exec": osh.exec,
|
"exec": osh.exec,
|
||||||
|
"!": osh.bang,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -89,8 +91,42 @@ func (oh osHandlers) exec(ctx context.Context, args ucl.CallArgs) (any, error) {
|
||||||
return string(res), nil
|
return string(res), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (oh osHandlers) bang(ctx context.Context, args ucl.CallArgs) (any, error) {
|
||||||
|
var (
|
||||||
|
cmdStr string
|
||||||
|
)
|
||||||
|
|
||||||
|
if err := args.Bind(&cmdStr); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd, err := oh.provider.ExecBang(ctx, cmdStr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if args.NArgs() > 0 {
|
||||||
|
var stdin string
|
||||||
|
if err := args.Bind(&stdin); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
cmd.Stdin = strings.NewReader(stdin)
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := cmd.Output()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return string(res), nil
|
||||||
|
}
|
||||||
|
|
||||||
type builtinOSProvider struct{}
|
type builtinOSProvider struct{}
|
||||||
|
|
||||||
|
func (p builtinOSProvider) ExecBang(ctx context.Context, cmd string) (*exec.Cmd, error) {
|
||||||
|
return exec.CommandContext(ctx, "bash", "-c", cmd), nil
|
||||||
|
}
|
||||||
|
|
||||||
func (builtinOSProvider) LookupEnv(key string) (string, bool) {
|
func (builtinOSProvider) LookupEnv(key string) (string, bool) {
|
||||||
return os.LookupEnv(key)
|
return os.LookupEnv(key)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -60,3 +60,27 @@ func TestOS_Exec(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestOS_Bang(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
descr string
|
||||||
|
eval string
|
||||||
|
want any
|
||||||
|
}{
|
||||||
|
{descr: "run command 1", eval: `os:! "echo 'hello, world'"`, want: "hello, world\n"},
|
||||||
|
{descr: "run command 2", eval: `os:! "date +%Y%m%d"`, want: time.Now().Format("20060102") + "\n"},
|
||||||
|
{descr: "run command 3", eval: `os:! "tr [a-z] [A-Z]" "hello"`, want: "HELLO"},
|
||||||
|
{descr: "run command 4", eval: `os:! "tr -d e" "hello"`, want: "hllo"},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.descr, func(t *testing.T) {
|
||||||
|
inst := ucl.New(
|
||||||
|
ucl.WithModule(builtins.OS()),
|
||||||
|
)
|
||||||
|
res, err := inst.EvalString(context.Background(), tt.eval)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, tt.want, res)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue