aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cli/context.go4
-rw-r--r--cli/handler.go52
-rw-r--r--gdrive.go9
-rw-r--r--handlers_drive.go (renamed from handlers.go)35
-rw-r--r--handlers_meta.go76
-rw-r--r--util.go22
6 files changed, 118 insertions, 80 deletions
diff --git a/cli/context.go b/cli/context.go
index c109281..ce82b17 100644
--- a/cli/context.go
+++ b/cli/context.go
@@ -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 {
diff --git a/cli/handler.go b/cli/handler.go
index 5cd13f8..a4aafef 100644
--- a/cli/handler.go
+++ b/cli/handler.go
@@ -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])
@@ -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
}
@@ -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, ">")
}
@@ -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
-}
diff --git a/gdrive.go b/gdrive.go
index 78b168a..f20f9f3 100644
--- a/gdrive.go
+++ b/gdrive.go
@@ -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)
diff --git a/handlers.go b/handlers_drive.go
index 5e681ab..21bf5f7 100644
--- a/handlers.go
+++ b/handlers_drive.go
@@ -3,7 +3,6 @@ package main
import (
"fmt"
"os"
- "strings"
"./cli"
"./auth"
"./drive"
@@ -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)
diff --git a/handlers_meta.go b/handlers_meta.go
new file mode 100644
index 0000000..f0f7ef7
--- /dev/null
+++ b/handlers_meta.go
@@ -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
+}
diff --git a/util.go b/util.go
index 4416696..d40d33e 100644
--- a/util.go
+++ b/util.go
@@ -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("")