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 }