Skip to content

Commit

Permalink
Move things around, support subcommand help
Browse files Browse the repository at this point in the history
  • Loading branch information
prasmussen committed Jan 23, 2016
1 parent ef9d5e6 commit 6b3da5b
Show file tree
Hide file tree
Showing 6 changed files with 118 additions and 80 deletions.
4 changes: 0 additions & 4 deletions cli/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,6 @@ func (self Context) Handlers() []*Handler {
return self.handlers
}

func (self Context) FilterHandlers(prefix string) []*Handler {
return filterHandlers(self.handlers, prefix)
}

type Arguments map[string]interface{}

func (self Arguments) String(key string) string {
Expand Down
52 changes: 13 additions & 39 deletions cli/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ type Handler struct {
func (self *Handler) getParser() Parser {
var parsers []Parser

for _, pattern := range splitPattern(self.Pattern) {
for _, pattern := range self.SplitPattern() {
if isOptional(pattern) {
name := optionalName(pattern)
parser := getFlagParser(self.Flags[name])
Expand All @@ -35,6 +35,18 @@ func (self *Handler) getParser() Parser {
return CompleteParser{parsers}
}

// Split on spaces but ignore spaces inside <...> and [...]
func (self *Handler) SplitPattern() []string {
re := regexp.MustCompile(`(<[^>]+>|\[[^\]]+]|\S+)`)
matches := []string{}

for _, value := range re.FindAllStringSubmatch(self.Pattern, -1) {
matches = append(matches, value[1])
}

return matches
}

func SetHandlers(h []*Handler) {
handlers = h
}
Expand Down Expand Up @@ -74,32 +86,6 @@ func Handle(args []string) bool {
return true
}

func filterHandlers(handlers []*Handler, prefix string) []*Handler {
matches := []*Handler{}

for _, h := range handlers {
pattern := strings.Join(stripOptionals(splitPattern(h.Pattern)), " ")
if strings.HasPrefix(pattern, prefix) {
matches = append(matches, h)
}
}

return matches
}


// Split on spaces but ignore spaces inside <...> and [...]
func splitPattern(pattern string) []string {
re := regexp.MustCompile(`(<[^>]+>|\[[^\]]+]|\S+)`)
matches := []string{}

for _, value := range re.FindAllStringSubmatch(pattern, -1) {
matches = append(matches, value[1])
}

return matches
}

func isCaptureGroup(arg string) bool {
return strings.HasPrefix(arg, "<") && strings.HasSuffix(arg, ">")
}
Expand All @@ -111,15 +97,3 @@ func isOptional(arg string) bool {
func optionalName(s string) string {
return s[1:len(s) - 1]
}

// Strip optional groups from pattern
func stripOptionals(pattern []string) []string {
newArgs := []string{}

for _, arg := range pattern {
if !isOptional(arg) {
newArgs = append(newArgs, arg)
}
}
return newArgs
}
9 changes: 7 additions & 2 deletions gdrive.go
Original file line number Diff line number Diff line change
Expand Up @@ -339,10 +339,15 @@ func main() {
Callback: printHelp,
},
&cli.Handler{
Pattern: "help <subcommand>",
Description: "Print subcommand help",
Pattern: "help <command>",
Description: "Print command help",
Callback: printCommandHelp,
},
&cli.Handler{
Pattern: "help <command> <subcommand>",
Description: "Print subcommand help",
Callback: printSubCommandHelp,
},
}

cli.SetHandlers(handlers)
Expand Down
35 changes: 0 additions & 35 deletions handlers.go → handlers_drive.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package main
import (
"fmt"
"os"
"strings"
"./cli"
"./auth"
"./drive"
Expand Down Expand Up @@ -142,40 +141,6 @@ func aboutHandler(ctx cli.Context) {
checkErr(err)
}

func printVersion(ctx cli.Context) {
fmt.Printf("%s v%s\n", Name, Version)
}

func printHelp(ctx cli.Context) {
fmt.Printf("%s usage:\n\n", Name)

for _, h := range ctx.Handlers() {
fmt.Printf("%s %s (%s)\n", Name, h.Pattern, h.Description)
}
}

func printCommandHelp(ctx cli.Context) {
handlers := ctx.FilterHandlers(ctx.Args().String("subcommand"))

if len(handlers) == 0 {
ExitF("Subcommand not found")
}

if len(handlers) > 1 {
ExitF("More than one matching subcommand, be more specific")
}

handler := handlers[0]

fmt.Printf("%s %s (%s)\n", Name, handler.Pattern, handler.Description)
for name, flags := range handler.Flags {
fmt.Printf("\n%s:\n", name)
for _, flag := range flags {
fmt.Printf(" %s (%s)\n", strings.Join(flag.GetPatterns(), ", "), flag.GetDescription())
}
}
}

func newDrive(args cli.Arguments) *drive.Drive {
configDir := args.String("configDir")
tokenPath := ConfigFilePath(configDir, TokenFilename)
Expand Down
76 changes: 76 additions & 0 deletions handlers_meta.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package main

import (
"fmt"
"strings"
"./cli"
)

func printVersion(ctx cli.Context) {
fmt.Printf("%s v%s\n", Name, Version)
}

func printHelp(ctx cli.Context) {
fmt.Printf("%s usage:\n\n", Name)

for _, h := range ctx.Handlers() {
fmt.Printf("%s %s (%s)\n", Name, h.Pattern, h.Description)
}
}

func printCommandHelp(ctx cli.Context) {
args := ctx.Args()
prefix := []string{args.String("command")}
printCommandPrefixHelp(prefix, ctx)
}

func printSubCommandHelp(ctx cli.Context) {
args := ctx.Args()
prefix := []string{args.String("command"), args.String("subcommand")}
printCommandPrefixHelp(prefix, ctx)
}

func printCommandPrefixHelp(prefix []string, ctx cli.Context) {
handler := getHandler(ctx.Handlers(), prefix)

if handler == nil {
ExitF("Command not found")
}

fmt.Printf("%s %s (%s)\n", Name, handler.Pattern, handler.Description)
for name, flags := range handler.Flags {
fmt.Printf("\n%s:\n", name)
for _, flag := range flags {
fmt.Printf(" %s (%s)\n", strings.Join(flag.GetPatterns(), ", "), flag.GetDescription())
}
}
}

func getHandler(handlers []*cli.Handler, prefix []string) *cli.Handler {
for _, h := range handlers {
pattern := stripOptionals(h.SplitPattern())

if len(prefix) > len(pattern) {
continue
}

if equal(prefix, pattern[:len(prefix)]) {
return h
}
}

return nil
}

// Strip optional groups (<...>) from pattern
func stripOptionals(pattern []string) []string {
newArgs := []string{}

for _, arg := range pattern {
if strings.HasPrefix(arg, "[") && strings.HasSuffix(arg, "]") {
continue
}
newArgs = append(newArgs, arg)
}
return newArgs
}
22 changes: 22 additions & 0 deletions util.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,28 @@ func Homedir() string {
return os.Getenv("HOME")
}

func equal(a, b []string) bool {
if a == nil && b == nil {
return true;
}

if a == nil || b == nil {
return false;
}

if len(a) != len(b) {
return false
}

for i := range a {
if a[i] != b[i] {
return false
}
}

return true
}

func ExitF(format string, a ...interface{}) {
fmt.Fprintf(os.Stderr, format, a...)
fmt.Println("")
Expand Down

0 comments on commit 6b3da5b

Please sign in to comment.