Add shared command path primitives
This commit is contained in:
@@ -11,6 +11,7 @@ import (
|
||||
"strings"
|
||||
|
||||
commandmeta "gitea.maximumdirect.net/eric/CommandKit/internal/commandmeta"
|
||||
"gitea.maximumdirect.net/eric/CommandKit/internal/commandpath"
|
||||
|
||||
spfcobra "github.com/spf13/cobra"
|
||||
"github.com/spf13/pflag"
|
||||
@@ -63,16 +64,17 @@ func (session *Session) Parse(argv []string) commandmeta.Result {
|
||||
}
|
||||
result.Key = selectedNode.Key
|
||||
var pathOK bool
|
||||
result.Path, pathOK = pathFor(selected, session.declarations)
|
||||
selectedPath, pathOK := pathFor(selected, session.declarations)
|
||||
if !pathOK {
|
||||
return failure(result, "selected command is not part of the declared tree")
|
||||
}
|
||||
result.Path = []string(selectedPath)
|
||||
consumed := len(leading) - len(unconsumed)
|
||||
if consumed != len(result.Path) || !equalPath(leading[:consumed], result.Path) {
|
||||
if consumed != len(selectedPath) || !commandpath.FromTokens(leading[:consumed]).Equal(selectedPath) {
|
||||
return failure(result, "command path must match a registered command exactly")
|
||||
}
|
||||
|
||||
remaining := append(append([]string(nil), unconsumed...), tail...)
|
||||
remaining := append(commandpath.CloneTokens(unconsumed), tail...)
|
||||
if err := selected.ParseFlags(remaining); err != nil {
|
||||
return failure(result, err.Error())
|
||||
}
|
||||
@@ -105,12 +107,12 @@ func (session *Session) RenderHelp(path []string) (string, *commandmeta.Failure)
|
||||
}
|
||||
selected, remaining, err := session.root.Find(path)
|
||||
if err != nil {
|
||||
return "", &commandmeta.Failure{Message: fmt.Sprintf("unknown help path %q", strings.Join(path, " ")), Usage: true}
|
||||
return "", &commandmeta.Failure{Message: fmt.Sprintf("unknown help path %q", commandpath.FromTokens(path).String()), Usage: true}
|
||||
}
|
||||
declaration := session.declarations[selected]
|
||||
selectedPath, pathOK := pathFor(selected, session.declarations)
|
||||
if declaration == nil || !pathOK || len(remaining) != 0 || !equalPath(path, selectedPath) {
|
||||
return "", &commandmeta.Failure{Message: fmt.Sprintf("unknown help path %q", strings.Join(path, " ")), Usage: true}
|
||||
if declaration == nil || !pathOK || len(remaining) != 0 || !commandpath.FromTokens(path).Equal(selectedPath) {
|
||||
return "", &commandmeta.Failure{Message: fmt.Sprintf("unknown help path %q", commandpath.FromTokens(path).String()), Usage: true}
|
||||
}
|
||||
buffer := new(bytes.Buffer)
|
||||
previousOut, previousErr := selected.OutOrStdout(), selected.ErrOrStderr()
|
||||
@@ -134,7 +136,7 @@ func (session *Session) UsageLine(path []string) (string, *commandmeta.Failure)
|
||||
selected, remaining, err := session.root.Find(path)
|
||||
declaration := session.declarations[selected]
|
||||
selectedPath, pathOK := pathFor(selected, session.declarations)
|
||||
if err != nil || declaration == nil || !pathOK || len(remaining) != 0 || !equalPath(path, selectedPath) {
|
||||
if err != nil || declaration == nil || !pathOK || len(remaining) != 0 || !commandpath.FromTokens(path).Equal(selectedPath) {
|
||||
return "", &commandmeta.Failure{Message: "usage path is not registered"}
|
||||
}
|
||||
line := selected.UseLine()
|
||||
@@ -303,28 +305,16 @@ func flagUsage(flag commandmeta.Flag) string {
|
||||
return usage
|
||||
}
|
||||
|
||||
func equalPath(left, right []string) bool {
|
||||
if len(left) != len(right) {
|
||||
return false
|
||||
}
|
||||
for index := range left {
|
||||
if left[index] != right[index] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func splitRoutingPrefix(argv []string) ([]string, []string) {
|
||||
for index, argument := range argv {
|
||||
if argument == "--" || (strings.HasPrefix(argument, "-") && argument != "-") {
|
||||
return append([]string(nil), argv[:index]...), append([]string(nil), argv[index:]...)
|
||||
return commandpath.CloneTokens(argv[:index]), commandpath.CloneTokens(argv[index:])
|
||||
}
|
||||
}
|
||||
return append([]string(nil), argv...), nil
|
||||
return commandpath.CloneTokens(argv), nil
|
||||
}
|
||||
|
||||
func pathFor(selected *spfcobra.Command, declarations map[*spfcobra.Command]*commandmeta.Command) ([]string, bool) {
|
||||
func pathFor(selected *spfcobra.Command, declarations map[*spfcobra.Command]*commandmeta.Command) (commandpath.Path, bool) {
|
||||
var reverse []string
|
||||
for current := selected; current != nil; current = current.Parent() {
|
||||
declaration := declarations[current]
|
||||
@@ -338,7 +328,7 @@ func pathFor(selected *spfcobra.Command, declarations map[*spfcobra.Command]*com
|
||||
for left, right := 0, len(reverse)-1; left < right; left, right = left+1, right-1 {
|
||||
reverse[left], reverse[right] = reverse[right], reverse[left]
|
||||
}
|
||||
return reverse, true
|
||||
return commandpath.FromTokens(reverse), true
|
||||
}
|
||||
|
||||
func failure(result commandmeta.Result, message string) commandmeta.Result {
|
||||
|
||||
Reference in New Issue
Block a user