town/cmd/contrib/main.go

163 lines
3.5 KiB
Go

package main
import (
"errors"
"fmt"
"github.com/AlecAivazis/survey/v2"
"github.com/spf13/cobra"
"os"
"path/filepath"
)
const (
submitOp = "submit"
delOp = "del"
updateOp = "update"
)
type ContribOptions struct {
CmdName string
Operation string // submit, delete, update
Admin bool
ExecPath string
}
func runContrib(opts *ContribOptions) error {
var action func(*ContribOptions) error
switch opts.Operation {
case submitOp:
action = submit
case delOp:
action = delete
case updateOp:
action = update
}
return action(opts)
}
func submit(opts *ContribOptions) error {
var cmdName string
var category string
var shortDescription string
var longDescription string
_, defaultName := filepath.Split(opts.ExecPath)
if err := survey.AskOne(&survey.Input{
Message: "New command's name:",
Default: defaultName}, &cmdName); err != nil {
return err
}
categories := []string{
"art",
"social",
"game",
"utility",
"misc",
}
var choice int
if err := survey.AskOne(&survey.Select{
Message: "what category should this command be filed under?",
Options: categories,
}, &choice); err != nil {
return err
}
category = categories[choice]
fmt.Printf("DBG %#v\n", category)
if err := survey.AskOne(&survey.Input{
Message: "What's a one line description of this command?",
}, &shortDescription); err != nil {
return err
}
if err := survey.AskOne(&survey.Editor{
Message: "Write a long description for this command. Try to include examples. If the short description is enough, you can just leave it blank though. Really it's whatever you want. I donno"}, &longDescription); err != nil {
return nil
}
// TODO create pending row
// TODO email me
// TODO print confirmation
return nil
}
func update(opts *ContribOptions) error {
return nil
}
func delete(opts *ContribOptions) error {
return nil
}
func rootCmd() *cobra.Command {
var updateName string
var delName string
var admin bool
rc := &cobra.Command{
Use: "contrib [path to executable]",
Short: "Submit new commands to the town launcher",
RunE: func(cmd *cobra.Command, args []string) error {
// submit - requires path arg
// update - requres path arg
// delete - no arg needed
if updateName != "" && delName != "" {
return errors.New("-u and -d are mutually exclusive")
}
var cmdName string
operation := "submit"
if updateName != "" {
operation = "update"
cmdName = updateName
} else if delName != "" {
operation = "delete"
cmdName = delName
}
if (operation == "update" || operation == "submit") && len(args) == 0 {
return errors.New("path to executable required when submitting or updating")
}
if operation == "delete" && len(args) > 0 {
return fmt.Errorf("no arguments expected when deleting; got %d", len(args))
}
if len(args) > 1 {
return fmt.Errorf("at most one argument is accepted; got %d", len(args))
}
var execPath string
if len(args) == 1 {
execPath = args[0]
}
opts := &ContribOptions{
Operation: operation,
Admin: admin,
ExecPath: execPath,
CmdName: cmdName,
}
return runContrib(opts)
},
// TODO longer example
}
rc.Flags().StringVarP(&updateName, "update", "u", "", "Name of command to update")
rc.Flags().StringVarP(&delName, "delete", "d", "", "Name of command to delete")
rc.Flags().BoolVarP(&admin, "admin", "a", false, "admin level operations")
return rc
}
func main() {
if err := rootCmd().Execute(); err != nil {
fmt.Fprintln(os.Stderr, err.Error())
os.Exit(1)
}
}