From 3bb7fe3690e93f364e10e4c149927b39f389360e Mon Sep 17 00:00:00 2001 From: Arsen Musayelyan Date: Sun, 20 Nov 2022 20:52:38 -0800 Subject: [PATCH] Add initial helper functions (#39) --- build.go | 1 + helpers.go | 65 ++++++++++++++++++++++++++++++++++++++++ internal/shutils/exec.go | 21 ++++++++++--- 3 files changed, 83 insertions(+), 4 deletions(-) create mode 100644 helpers.go diff --git a/build.go b/build.go index a2463c1..b941136 100644 --- a/build.go +++ b/build.go @@ -142,6 +142,7 @@ func buildPackage(ctx context.Context, script string, mgr manager.Manager) ([]st runner, err := interp.New( interp.Env(expand.ListEnviron(env...)), interp.StdIO(os.Stdin, os.Stdout, os.Stderr), + interp.ExecHandler(helpers.ExecHandler), ) if err != nil { return nil, nil, err diff --git a/helpers.go b/helpers.go new file mode 100644 index 0000000..0ff9a37 --- /dev/null +++ b/helpers.go @@ -0,0 +1,65 @@ +package main + +import ( + "fmt" + "io" + "os" + "path/filepath" + + "go.arsenm.dev/lure/internal/shutils" + "mvdan.cc/sh/v3/interp" +) + +var helpers = shutils.ExecFuncs{ + "install-bin": installHelperCmd("/usr/bin", 0o755), + "install-systemd-user": installHelperCmd("/usr/lib/systemd/user", 0o644), + "install-systemd": installHelperCmd("/usr/lib/systemd/system", 0o644), + "install-config": installHelperCmd("/etc", 0o644), + "install-license": installHelperCmd("/usr/share/licenses", 0o644), + "install-manual": installHelperCmd("/usr/share/man/man1", 0o644), + "install-desktop": installHelperCmd("/usr/share/applications", 0o644), +} + +func installHelperCmd(prefix string, perms os.FileMode) shutils.ExecFunc { + return func(hc interp.HandlerContext, cmd string, args []string) error { + if len(args) < 1 { + return shutils.InsufficientArgsError(cmd, 1, len(args)) + } + + from := args[0] + to := "" + if len(args) > 1 { + to = filepath.Join(hc.Env.Get("pkgdir").Str, prefix, args[1]) + } else { + to = filepath.Join(hc.Env.Get("pkgdir").Str, prefix, filepath.Base(from)) + } + + err := helperInstall(from, to, perms) + if err != nil { + return fmt.Errorf("%s: %w", cmd, err) + } + return nil + } +} + +func helperInstall(from, to string, perms os.FileMode) error { + err := os.MkdirAll(filepath.Dir(to), 0o755) + if err != nil { + return err + } + + src, err := os.Open(from) + if err != nil { + return err + } + defer src.Close() + + dst, err := os.OpenFile(to, os.O_TRUNC|os.O_CREATE|os.O_RDWR, perms) + if err != nil { + return err + } + defer dst.Close() + + _, err = io.Copy(dst, src) + return err +} diff --git a/internal/shutils/exec.go b/internal/shutils/exec.go index ef1cb41..3a18fd4 100644 --- a/internal/shutils/exec.go +++ b/internal/shutils/exec.go @@ -20,21 +20,34 @@ package shutils import ( "context" + "fmt" "time" "mvdan.cc/sh/v3/interp" ) -type ExecFuncs map[string]func(interp.HandlerContext, []string) uint8 +func InsufficientArgsError(cmd string, exp, got int) error { + argsWord := "arguments" + if exp == 1 { + argsWord = "argument" + } + + return fmt.Errorf("%s: command requires at least %d %s, got %d", cmd, exp, argsWord, got) +} + +type ExecFunc func(hc interp.HandlerContext, name string, args []string) error + +type ExecFuncs map[string]ExecFunc func (ef ExecFuncs) ExecHandler(ctx context.Context, args []string) error { name := args[0] if fn, ok := ef[name]; ok { hctx := interp.HandlerCtx(ctx) - ec := fn(hctx, args) - if ec != 0 { - return interp.NewExitStatus(ec) + if len(args) > 1 { + return fn(hctx, args[0], args[1:]) + } else { + return fn(hctx, args[0], nil) } }