mirror of
https://github.com/k3s-io/k3s.git
synced 2024-06-07 19:41:36 +00:00
Match to last After keyword for parser (#4383)
* Made parser able to skip over subcommands * Edge case coverage, reworked regex with groups Signed-off-by: Derek Nola <derek.nola@suse.com>
This commit is contained in:
parent
8915e4c7f7
commit
7bd65047c3
@ -7,7 +7,7 @@ import (
|
|||||||
|
|
||||||
func MustParse(args []string) []string {
|
func MustParse(args []string) []string {
|
||||||
parser := &Parser{
|
parser := &Parser{
|
||||||
After: []string{"server", "agent", "etcd-snapshot"},
|
After: []string{"server", "agent", "etcd-snapshot:1"},
|
||||||
FlagNames: []string{"--config", "-c"},
|
FlagNames: []string{"--config", "-c"},
|
||||||
EnvName: version.ProgramUpper + "_CONFIG_FILE",
|
EnvName: version.ProgramUpper + "_CONFIG_FILE",
|
||||||
DefaultConfig: "/etc/rancher/" + version.Program + "/config.yaml",
|
DefaultConfig: "/etc/rancher/" + version.Program + "/config.yaml",
|
||||||
|
@ -7,6 +7,8 @@ import (
|
|||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"regexp"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/rancher/k3s/pkg/agent/util"
|
"github.com/rancher/k3s/pkg/agent/util"
|
||||||
@ -101,14 +103,36 @@ func (p *Parser) findStart(args []string) ([]string, []string, bool) {
|
|||||||
return []string{}, args, true
|
return []string{}, args, true
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, val := range args {
|
afterIndex := make(map[string]int)
|
||||||
for _, test := range p.After {
|
re, err := regexp.Compile(`(.+):(\d+)`)
|
||||||
if val == test {
|
if err != nil {
|
||||||
return args[0 : i+1], args[i+1:], true
|
return args, nil, false
|
||||||
|
}
|
||||||
|
// After keywords ending with ":<NUM>" can set + NUM of arguments as the split point.
|
||||||
|
// used for matching on subcommmands
|
||||||
|
for i, arg := range p.After {
|
||||||
|
if match := re.FindAllStringSubmatch(arg, -1); match != nil {
|
||||||
|
p.After[i] = match[0][1]
|
||||||
|
afterIndex[match[0][1]], err = strconv.Atoi(match[0][2])
|
||||||
|
if err != nil {
|
||||||
|
return args, nil, false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for i, val := range args {
|
||||||
|
for _, test := range p.After {
|
||||||
|
if val == test {
|
||||||
|
if skip := afterIndex[test]; skip != 0 {
|
||||||
|
if len(args) <= i+skip || strings.HasPrefix(args[i+skip], "-") {
|
||||||
|
return args[0 : i+1], args[i+1:], true
|
||||||
|
}
|
||||||
|
return args[0 : i+skip+1], args[i+skip+1:], true
|
||||||
|
}
|
||||||
|
return args[0 : i+1], args[i+1:], true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return args, nil, false
|
return args, nil, false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,11 +48,46 @@ func Test_UnitParser_findStart(t *testing.T) {
|
|||||||
prefix: []string{"not-server", "foo", "bar"},
|
prefix: []string{"not-server", "foo", "bar"},
|
||||||
found: false,
|
found: false,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "command (with optional subcommands) but no flags",
|
||||||
|
args: []string{"etcd-snapshot"},
|
||||||
|
prefix: []string{"etcd-snapshot"},
|
||||||
|
suffix: []string{},
|
||||||
|
found: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "command (with optional subcommands) and flags",
|
||||||
|
args: []string{"etcd-snapshot", "-f"},
|
||||||
|
prefix: []string{"etcd-snapshot"},
|
||||||
|
suffix: []string{"-f"},
|
||||||
|
found: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "command and subcommand with no flags",
|
||||||
|
args: []string{"etcd-snapshot", "list"},
|
||||||
|
prefix: []string{"etcd-snapshot", "list"},
|
||||||
|
suffix: []string{},
|
||||||
|
found: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "command and subcommand with flags",
|
||||||
|
args: []string{"etcd-snapshot", "list", "-f"},
|
||||||
|
prefix: []string{"etcd-snapshot", "list"},
|
||||||
|
suffix: []string{"-f"},
|
||||||
|
found: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "command and too many subcommands",
|
||||||
|
args: []string{"etcd-snapshot", "list", "delete", "foo", "bar"},
|
||||||
|
prefix: []string{"etcd-snapshot", "list"},
|
||||||
|
suffix: []string{"delete", "foo", "bar"},
|
||||||
|
found: true,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
p := Parser{
|
p := Parser{
|
||||||
After: []string{"server", "agent"},
|
After: []string{"server", "agent", "etcd-snapshot:1"},
|
||||||
}
|
}
|
||||||
prefix, suffix, found := p.findStart(tt.args)
|
prefix, suffix, found := p.findStart(tt.args)
|
||||||
if !reflect.DeepEqual(prefix, tt.prefix) {
|
if !reflect.DeepEqual(prefix, tt.prefix) {
|
||||||
|
Loading…
Reference in New Issue
Block a user