From ec7894ff9f13b108094c03541c5ef6855cded994 Mon Sep 17 00:00:00 2001 From: Andrey Nering Date: Wed, 16 Jul 2025 13:53:10 -0300 Subject: [PATCH] feat(shell): use coreutils from u-root --- go.mod | 3 +- go.sum | 5 +++- internal/shell/coreutils.go | 59 +++++++++++++++++++++++++++++++++++++ internal/shell/shell.go | 2 +- 4 files changed, 66 insertions(+), 3 deletions(-) create mode 100644 internal/shell/coreutils.go diff --git a/go.mod b/go.mod index c2b6fa54ed62365230814e41aa3295a096514c17..ed11d17a745e7e9a2806b1cb0b7f86a335c0f2bd 100644 --- a/go.mod +++ b/go.mod @@ -39,6 +39,7 @@ require ( github.com/srwiley/rasterx v0.0.0-20220730225603-2ab79fcdd4ef github.com/stretchr/testify v1.10.0 github.com/tidwall/sjson v1.2.5 + github.com/u-root/u-root v0.14.1-0.20250722142936-bf4e78a90dfc github.com/zeebo/xxh3 v1.0.2 golang.org/x/exp v0.0.0-20250305212735-054e65f0b394 gopkg.in/natefinch/lumberjack.v2 v2.2.1 @@ -108,7 +109,7 @@ require ( github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect github.com/sethvargo/go-retry v0.3.0 // indirect github.com/spf13/cast v1.7.1 // indirect - github.com/spf13/pflag v1.0.6 // indirect + github.com/spf13/pflag v1.0.7 // indirect github.com/tetratelabs/wazero v1.9.0 // indirect github.com/tidwall/gjson v1.18.0 // indirect github.com/tidwall/match v1.1.1 // indirect diff --git a/go.sum b/go.sum index 0d05967cdf1a80070dab737b1c473d0c39c20611..18a31002f61f069e7c24316b642c60799902d2c7 100644 --- a/go.sum +++ b/go.sum @@ -234,8 +234,9 @@ github.com/spf13/cast v1.7.1 h1:cuNEagBQEHWN1FnbGEjCXL2szYEXqfJPbP2HNUaca9Y= github.com/spf13/cast v1.7.1/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo= github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0= -github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o= github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/pflag v1.0.7 h1:vN6T9TfwStFPFM5XzjsvmzZkLuaLX+HS+0SeFLRgU6M= +github.com/spf13/pflag v1.0.7/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/srwiley/oksvg v0.0.0-20221011165216-be6e8873101c h1:km8GpoQut05eY3GiYWEedbTT0qnSxrCjsVbb7yKY1KE= github.com/srwiley/oksvg v0.0.0-20221011165216-be6e8873101c/go.mod h1:cNQ3dwVJtS5Hmnjxy6AgTPd0Inb3pW05ftPSX7NZO7Q= github.com/srwiley/rasterx v0.0.0-20220730225603-2ab79fcdd4ef h1:Ch6Q+AZUxDBCVqdkI8FSpFyZDtCVBc2VmejdNrm5rRQ= @@ -258,6 +259,8 @@ github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= +github.com/u-root/u-root v0.14.1-0.20250722142936-bf4e78a90dfc h1:HjI/UCF4dRyzizePQrhGUSQvuU7z4tOqMqz6GRGlFCM= +github.com/u-root/u-root v0.14.1-0.20250722142936-bf4e78a90dfc/go.mod h1:/0Qr7qJeDwWxoKku2xKQ4Szc+SwBE3g9VE8jNiamsmc= github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no= github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM= github.com/yosida95/uritemplate/v3 v3.0.2 h1:Ed3Oyj9yrmi9087+NczuL5BwkIc4wvTb5zIM+UJPGz4= diff --git a/internal/shell/coreutils.go b/internal/shell/coreutils.go new file mode 100644 index 0000000000000000000000000000000000000000..5669d578987ba5a8792430c96e6fc869d8b5cf55 --- /dev/null +++ b/internal/shell/coreutils.go @@ -0,0 +1,59 @@ +package shell + +import ( + "context" + + "github.com/u-root/u-root/pkg/core" + "github.com/u-root/u-root/pkg/core/cat" + "github.com/u-root/u-root/pkg/core/chmod" + "github.com/u-root/u-root/pkg/core/cp" + "github.com/u-root/u-root/pkg/core/find" + "github.com/u-root/u-root/pkg/core/ls" + "github.com/u-root/u-root/pkg/core/mkdir" + "github.com/u-root/u-root/pkg/core/mv" + "github.com/u-root/u-root/pkg/core/rm" + "github.com/u-root/u-root/pkg/core/touch" + "github.com/u-root/u-root/pkg/core/xargs" + "mvdan.cc/sh/v3/interp" +) + +var coreUtils = map[string]func() core.Command{ + "cat": func() core.Command { return cat.New() }, + "chmod": func() core.Command { return chmod.New() }, + "cp": func() core.Command { return cp.New() }, + "find": func() core.Command { return find.New() }, + "ls": func() core.Command { return ls.New() }, + "mkdir": func() core.Command { return mkdir.New() }, + "mv": func() core.Command { return mv.New() }, + "rm": func() core.Command { return rm.New() }, + "touch": func() core.Command { return touch.New() }, + "xargs": func() core.Command { return xargs.New() }, +} + +func (s *Shell) coreUtilsHandler() func(next interp.ExecHandlerFunc) interp.ExecHandlerFunc { + return func(next interp.ExecHandlerFunc) interp.ExecHandlerFunc { + return func(ctx context.Context, args []string) error { + if len(args) == 0 { + return next(ctx, args) + } + + program, programArgs := args[0], args[1:] + + newCoreUtil, ok := coreUtils[program] + if !ok { + return next(ctx, args) + } + + c := interp.HandlerCtx(ctx) + + cmd := newCoreUtil() + cmd.SetIO(c.Stdin, c.Stdout, c.Stderr) + cmd.SetWorkingDir(c.Dir) + cmd.SetLookupEnv(func(key string) (string, bool) { + v := c.Env.Get(key) + return v.Str, v.Set + }) + return cmd.RunContext(ctx, programArgs...) + } + } +} diff --git a/internal/shell/shell.go b/internal/shell/shell.go index e6e6d47e644e4569c4dc04e927a66817a9fc1a28..d76f9bdcb355cc9314e570761147ab0bce1fd219 100644 --- a/internal/shell/shell.go +++ b/internal/shell/shell.go @@ -221,7 +221,7 @@ func (s *Shell) execPOSIX(ctx context.Context, command string) (string, string, interp.Interactive(false), interp.Env(expand.ListEnviron(s.env...)), interp.Dir(s.cwd), - interp.ExecHandlers(s.blockHandler()), + interp.ExecHandlers(s.blockHandler(), s.coreUtilsHandler()), ) if err != nil { return "", "", fmt.Errorf("could not run command: %w", err)