Refactored msgbus client CLI to use cobra
This commit is contained in:
parent
1dded6cc6b
commit
2f7d09660f
|
@ -1,88 +1,5 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
|
||||
"github.com/prologic/msgbus/client"
|
||||
)
|
||||
|
||||
const defaultTopic = "hello"
|
||||
|
||||
func main() {
|
||||
var url string
|
||||
|
||||
flag.StringVar(
|
||||
&url, "url",
|
||||
"http://localhost:8000", "url to connect to",
|
||||
)
|
||||
|
||||
flag.Parse()
|
||||
|
||||
client := client.NewClient(url, nil)
|
||||
|
||||
if flag.Arg(0) == "sub" {
|
||||
subscribe(client, flag.Arg(1))
|
||||
} else if flag.Arg(0) == "pub" {
|
||||
publish(client, flag.Arg(1), flag.Arg(2))
|
||||
} else if flag.Arg(0) == "pull" {
|
||||
pull(client, flag.Arg(1))
|
||||
} else {
|
||||
log.Fatalf("invalid command %s", flag.Arg(0))
|
||||
}
|
||||
}
|
||||
|
||||
func publish(client *client.Client, topic, message string) {
|
||||
if topic == "" {
|
||||
topic = defaultTopic
|
||||
}
|
||||
|
||||
if message == "" || message == "-" {
|
||||
log.Printf("Reading message from stdin...\n")
|
||||
buf, err := ioutil.ReadAll(os.Stdin)
|
||||
if err != nil {
|
||||
log.Fatalf("error reading message from stdin: %s", err)
|
||||
}
|
||||
message = string(buf[:])
|
||||
}
|
||||
|
||||
err := client.Publish(topic, message)
|
||||
if err != nil {
|
||||
log.Fatalf("error publishing message: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func pull(client *client.Client, topic string) {
|
||||
if topic == "" {
|
||||
topic = defaultTopic
|
||||
}
|
||||
|
||||
client.Pull(topic)
|
||||
}
|
||||
|
||||
func subscribe(client *client.Client, topic string) {
|
||||
if topic == "" {
|
||||
topic = defaultTopic
|
||||
}
|
||||
|
||||
s := client.Subscribe(topic)
|
||||
go s.Run()
|
||||
|
||||
sigs := make(chan os.Signal, 1)
|
||||
done := make(chan bool, 1)
|
||||
|
||||
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
|
||||
|
||||
go func() {
|
||||
sig := <-sigs
|
||||
log.Printf("caught signal %s: ", sig)
|
||||
s.Stop()
|
||||
done <- true
|
||||
}()
|
||||
|
||||
<-done
|
||||
Execute()
|
||||
}
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/prologic/msgbus/client"
|
||||
)
|
||||
|
||||
// pubCmd represents the pub command
|
||||
var pubCmd = &cobra.Command{
|
||||
Use: "pub [flags] <topic> [<message>|-]",
|
||||
Short: "Publish a new message",
|
||||
Long: `This publishes a new message either from positional command-line
|
||||
arguments or from standard input if - is used as the first and only argument.
|
||||
|
||||
This is an asynchronous operation and does not wait for a response unless the
|
||||
-w/--wait option is also present.`,
|
||||
Args: cobra.MinimumNArgs(1),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
uri := cmd.Flag("uri").Value.String()
|
||||
client := client.NewClient(uri, nil)
|
||||
|
||||
topic := args[0]
|
||||
|
||||
message := ""
|
||||
if len(args) == 2 {
|
||||
message = args[1]
|
||||
}
|
||||
|
||||
publish(client, topic, message)
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
RootCmd.AddCommand(pubCmd)
|
||||
|
||||
pubCmd.Flags().BoolP(
|
||||
"wait", "w", false,
|
||||
"Waits for a response and prints it before terminating",
|
||||
)
|
||||
}
|
||||
|
||||
const defaultTopic = "hello"
|
||||
|
||||
func publish(client *client.Client, topic, message string) {
|
||||
if topic == "" {
|
||||
topic = defaultTopic
|
||||
}
|
||||
|
||||
if message == "" || message == "-" {
|
||||
log.Printf("Reading message from stdin...\n")
|
||||
buf, err := ioutil.ReadAll(os.Stdin)
|
||||
if err != nil {
|
||||
log.Fatalf("error reading message from stdin: %s", err)
|
||||
}
|
||||
message = string(buf[:])
|
||||
}
|
||||
|
||||
err := client.Publish(topic, message)
|
||||
if err != nil {
|
||||
log.Fatalf("error publishing message: %s", err)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/prologic/msgbus/client"
|
||||
)
|
||||
|
||||
// pullCmd represents the pub command
|
||||
var pullCmd = &cobra.Command{
|
||||
Use: "pull [flags] <topic>",
|
||||
Short: "Pulls a message from a given topic",
|
||||
Long: `This pulls a message from the given topic if there are any messages
|
||||
and prints the message to standard output. Otherwise if the queue for the
|
||||
given topic is empty, this does nothing.
|
||||
|
||||
This is primarily useful in situations where a subscription was lost and you
|
||||
want to "catch up" and pull any messages left in the queue for that topic.`,
|
||||
Args: cobra.MinimumNArgs(1),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
uri := cmd.Flag("uri").Value.String()
|
||||
client := client.NewClient(uri, nil)
|
||||
|
||||
topic := args[0]
|
||||
|
||||
pull(client, topic)
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
RootCmd.AddCommand(pullCmd)
|
||||
}
|
||||
|
||||
func pull(client *client.Client, topic string) {
|
||||
if topic == "" {
|
||||
topic = defaultTopic
|
||||
}
|
||||
|
||||
client.Pull(topic)
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/mitchellh/go-homedir"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
var configFile string
|
||||
|
||||
// RootCmd represents the base command when called without any subcommands
|
||||
var RootCmd = &cobra.Command{
|
||||
Use: "msgbus",
|
||||
Short: "Command-line client for msgbus",
|
||||
Long: `This is the command-line client for the msgbus daemon msgbusd.
|
||||
|
||||
This lets you publish, subscribe and pull messages from a running msgbusd
|
||||
instance. This is the reference implementation of using the msgbus client
|
||||
library for publishing and subscribing to topics.`,
|
||||
}
|
||||
|
||||
// Execute adds all child commands to the root command
|
||||
// and sets flags appropriately.
|
||||
// This is called by main.main(). It only needs to happen once to the rootCmd.
|
||||
func Execute() {
|
||||
if err := RootCmd.Execute(); err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
func init() {
|
||||
cobra.OnInitialize(initConfig)
|
||||
|
||||
RootCmd.PersistentFlags().StringVar(
|
||||
&configFile, "config", "",
|
||||
"config file (default is $HOME/.msgbus.yaml)",
|
||||
)
|
||||
|
||||
RootCmd.PersistentFlags().StringP(
|
||||
"uri", "u", "http://localhost:8000",
|
||||
"URI to connect to msgbusd",
|
||||
)
|
||||
}
|
||||
|
||||
// initConfig reads in config file and ENV variables if set.
|
||||
func initConfig() {
|
||||
if configFile != "" {
|
||||
// Use config file from the flag.
|
||||
viper.SetConfigFile(configFile)
|
||||
} else {
|
||||
// Find home directory.
|
||||
home, err := homedir.Dir()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Search config in home directory with name ".cobra-example" (without extension).
|
||||
viper.AddConfigPath(home)
|
||||
viper.SetConfigName(".cobra-example")
|
||||
}
|
||||
|
||||
viper.AutomaticEnv() // read in environment variables that match
|
||||
|
||||
// If a config file is found, read it in.
|
||||
if err := viper.ReadInConfig(); err == nil {
|
||||
fmt.Println("Using config file:", viper.ConfigFileUsed())
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/prologic/msgbus/client"
|
||||
)
|
||||
|
||||
// subCmd represents the pub command
|
||||
var subCmd = &cobra.Command{
|
||||
Use: "sub [flags] <topic>",
|
||||
Short: "Subscribe to a topic",
|
||||
Long: `This subscribes to the given topic and for every message published
|
||||
to the topic, the message is printed to standard output.`,
|
||||
Args: cobra.MinimumNArgs(1),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
uri := cmd.Flag("uri").Value.String()
|
||||
client := client.NewClient(uri, nil)
|
||||
|
||||
topic := args[0]
|
||||
|
||||
subscribe(client, topic)
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
RootCmd.AddCommand(subCmd)
|
||||
}
|
||||
|
||||
func subscribe(client *client.Client, topic string) {
|
||||
if topic == "" {
|
||||
topic = defaultTopic
|
||||
}
|
||||
|
||||
s := client.Subscribe(topic)
|
||||
go s.Run()
|
||||
|
||||
sigs := make(chan os.Signal, 1)
|
||||
done := make(chan bool, 1)
|
||||
|
||||
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
|
||||
|
||||
go func() {
|
||||
sig := <-sigs
|
||||
log.Printf("caught signal %s: ", sig)
|
||||
s.Stop()
|
||||
done <- true
|
||||
}()
|
||||
|
||||
<-done
|
||||
}
|
Loading…
Reference in New Issue