github.com/segakazzz/buffalo@v0.16.22-0.20210119082501-1f52048d3feb/plugins/plugcmds/available.go (about)

     1  package plugcmds
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"io"
     7  	"os"
     8  
     9  	"github.com/gobuffalo/buffalo/plugins"
    10  	"github.com/gobuffalo/events"
    11  	"github.com/spf13/cobra"
    12  )
    13  
    14  // NewAvailable returns a fully formed Available type
    15  func NewAvailable() *Available {
    16  	return &Available{
    17  		plugs: plugMap{},
    18  	}
    19  }
    20  
    21  // Available used to manage all of the available commands
    22  // for the plugin
    23  type Available struct {
    24  	plugs plugMap
    25  }
    26  
    27  type plug struct {
    28  	BuffaloCommand string
    29  	Cmd            *cobra.Command
    30  	Plugin         plugins.Command
    31  }
    32  
    33  func (p plug) String() string {
    34  	b, _ := json.Marshal(p.Plugin)
    35  	return string(b)
    36  }
    37  
    38  // Cmd returns the "available" command
    39  func (a *Available) Cmd() *cobra.Command {
    40  	return &cobra.Command{
    41  		Use:   "available",
    42  		Short: "a list of available buffalo plugins",
    43  		RunE: func(cmd *cobra.Command, args []string) error {
    44  			return a.Encode(os.Stdout)
    45  		},
    46  	}
    47  }
    48  
    49  // Commands returns all of the commands that are available
    50  func (a *Available) Commands() []*cobra.Command {
    51  	cmds := []*cobra.Command{a.Cmd()}
    52  	a.plugs.Range(func(_ string, p plug) bool {
    53  		cmds = append(cmds, p.Cmd)
    54  		return true
    55  	})
    56  	return cmds
    57  }
    58  
    59  // Add a new command to this list of available ones.
    60  // The bufCmd should corresponding buffalo command that
    61  // command should live below.
    62  //
    63  // Special "commands":
    64  //	"root" - is the `buffalo` command
    65  //	"events" - listens for emitted events
    66  func (a *Available) Add(bufCmd string, cmd *cobra.Command) error {
    67  	if len(cmd.Aliases) == 0 {
    68  		cmd.Aliases = []string{}
    69  	}
    70  	p := plug{
    71  		BuffaloCommand: bufCmd,
    72  		Cmd:            cmd,
    73  		Plugin: plugins.Command{
    74  			Name:           cmd.Use,
    75  			BuffaloCommand: bufCmd,
    76  			Description:    cmd.Short,
    77  			Aliases:        cmd.Aliases,
    78  			UseCommand:     cmd.Use,
    79  		},
    80  	}
    81  	a.plugs.Store(p.String(), p)
    82  	return nil
    83  }
    84  
    85  // Mount all of the commands that are available
    86  // on to the other command. This is the recommended
    87  // approach for using Available.
    88  //	a.Mount(rootCmd)
    89  func (a *Available) Mount(cmd *cobra.Command) {
    90  	// mount all the cmds on to the cobra command
    91  	cmd.AddCommand(a.Cmd())
    92  	a.plugs.Range(func(_ string, p plug) bool {
    93  		cmd.AddCommand(p.Cmd)
    94  		return true
    95  	})
    96  }
    97  
    98  // Encode into the required Buffalo plugins available
    99  // format
   100  func (a *Available) Encode(w io.Writer) error {
   101  	var plugs plugins.Commands
   102  	a.plugs.Range(func(_ string, p plug) bool {
   103  		plugs = append(plugs, p.Plugin)
   104  		return true
   105  	})
   106  	return json.NewEncoder(w).Encode(plugs)
   107  }
   108  
   109  // Listen adds a command for github.com/gobuffalo/events.
   110  // This will listen for ALL events. Use ListenFor to
   111  // listen to a regex of events.
   112  func (a *Available) Listen(fn func(e events.Event) error) error {
   113  	return a.Add("events", buildListen(fn))
   114  }
   115  
   116  // ListenFor adds a command for github.com/gobuffalo/events.
   117  // This will only listen for events that match the regex provided.
   118  func (a *Available) ListenFor(rx string, fn func(e events.Event) error) error {
   119  	cmd := buildListen(fn)
   120  	p := plug{
   121  		BuffaloCommand: "events",
   122  		Cmd:            cmd,
   123  		Plugin: plugins.Command{
   124  			Name:           cmd.Use,
   125  			BuffaloCommand: "events",
   126  			Description:    cmd.Short,
   127  			Aliases:        cmd.Aliases,
   128  			UseCommand:     cmd.Use,
   129  			ListenFor:      rx,
   130  		},
   131  	}
   132  	a.plugs.Store(p.String(), p)
   133  	return nil
   134  }
   135  
   136  func buildListen(fn func(e events.Event) error) *cobra.Command {
   137  	listenCmd := &cobra.Command{
   138  		Use:     "listen",
   139  		Short:   "listens to github.com/gobuffalo/events",
   140  		Aliases: []string{},
   141  		RunE: func(cmd *cobra.Command, args []string) error {
   142  			if len(args) == 0 {
   143  				return fmt.Errorf("must pass a payload")
   144  			}
   145  
   146  			e := events.Event{}
   147  			err := json.Unmarshal([]byte(args[0]), &e)
   148  			if err != nil {
   149  				return err
   150  			}
   151  
   152  			return fn(e)
   153  		},
   154  	}
   155  	return listenCmd
   156  }