lure/helpers.go

113 lines
2.7 KiB
Go

package main
import (
"errors"
"fmt"
"io"
"os"
"path/filepath"
"go.arsenm.dev/lure/internal/shutils"
"mvdan.cc/sh/v3/interp"
)
var ErrNoPipe = errors.New("command requires data to be piped in")
var helpers = shutils.ExecFuncs{
"install-binary": 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),
"install-completion": installCompletionCmd,
}
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 installCompletionCmd(hc interp.HandlerContext, cmd string, args []string) error {
// If the command's stdin is the same as the system's,
// that means nothing was piped in. In this case, return an error.
if hc.Stdin == os.Stdin {
return fmt.Errorf("install-completion: %w", ErrNoPipe)
}
if len(args) < 2 {
return shutils.InsufficientArgsError(cmd, 2, len(args))
}
shell := args[0]
name := args[1]
var prefix string
switch shell {
case "bash":
prefix = "/usr/share/bash-completion/completion"
case "zsh":
prefix = "/usr/share/zsh/site-functions"
name = "_" + name
case "fish":
prefix = "/usr/share/fish/vendor_completions.d"
name += ".fish"
}
path := filepath.Join(hc.Env.Get("pkgdir").Str, prefix, name)
err := os.MkdirAll(filepath.Dir(path), 0o755)
if err != nil {
return err
}
dst, err := os.OpenFile(path, os.O_TRUNC|os.O_CREATE|os.O_RDWR, 0o644)
if err != nil {
return err
}
defer dst.Close()
_, err = io.Copy(dst, hc.Stdin)
return err
}
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
}