github.com/JarrahG/buffalocli@v0.0.0-20230801092127-b85bfd5d395a/internal/plugins/decorate.go (about)

     1  package plugins
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"os/exec"
     7  	"path/filepath"
     8  	"runtime"
     9  	"strings"
    10  
    11  	"github.com/gobuffalo/envy"
    12  	"github.com/spf13/cobra"
    13  )
    14  
    15  // ErrPlugMissing error for when a plugin is missing
    16  var ErrPlugMissing = fmt.Errorf("plugin missing")
    17  
    18  // Decorate setup cobra Commands for plugins
    19  func Decorate(c Command) *cobra.Command {
    20  	var flags []string
    21  	if len(c.Flags) > 0 {
    22  		flags = append(flags, c.Flags...)
    23  	}
    24  	cc := &cobra.Command{
    25  		Use:     c.Name,
    26  		Short:   fmt.Sprintf("[PLUGIN] %s", c.Description),
    27  		Aliases: c.Aliases,
    28  		RunE: func(cmd *cobra.Command, args []string) error {
    29  			plugCmd := c.Name
    30  			if c.UseCommand != "" {
    31  				plugCmd = c.UseCommand
    32  			}
    33  
    34  			ax := []string{plugCmd}
    35  			if plugCmd == "-" {
    36  				ax = []string{}
    37  			}
    38  
    39  			ax = append(ax, args...)
    40  			ax = append(ax, flags...)
    41  
    42  			bin, err := LookPath(c.Binary)
    43  			if err != nil {
    44  				return err
    45  			}
    46  
    47  			ex := exec.Command(bin, ax...)
    48  			if runtime.GOOS != "windows" {
    49  				ex.Env = append(envy.Environ(), "BUFFALO_PLUGIN=1")
    50  			}
    51  			ex.Stdin = os.Stdin
    52  			ex.Stdout = os.Stdout
    53  			ex.Stderr = os.Stderr
    54  			return log(strings.Join(ex.Args, " "), ex.Run)
    55  		},
    56  	}
    57  	cc.DisableFlagParsing = true
    58  	return cc
    59  }
    60  
    61  // LookPath for plugin
    62  func LookPath(s string) (string, error) {
    63  	if _, err := os.Stat(s); err == nil {
    64  		return s, nil
    65  	}
    66  
    67  	if lp, err := exec.LookPath(s); err == nil {
    68  		return lp, err
    69  	}
    70  
    71  	var bin string
    72  	pwd, err := os.Getwd()
    73  	if err != nil {
    74  		return "", err
    75  	}
    76  
    77  	var looks []string
    78  	if from, err := envy.MustGet("BUFFALO_PLUGIN_PATH"); err == nil {
    79  		looks = append(looks, from)
    80  	} else {
    81  		looks = []string{filepath.Join(pwd, "plugins"), filepath.Join(envy.GoPath(), "bin"), envy.Get("PATH", "")}
    82  	}
    83  
    84  	for _, p := range looks {
    85  		lp := filepath.Join(p, s)
    86  		if lp, err = filepath.EvalSymlinks(lp); err == nil {
    87  			bin = lp
    88  			break
    89  		}
    90  	}
    91  
    92  	if len(bin) == 0 {
    93  		return "", ErrPlugMissing
    94  	}
    95  	return bin, nil
    96  }