mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-05-17 18:25:26 +00:00
add testcases for shlexsplit
This commit is contained in:
@@ -12,8 +12,6 @@ import (
|
|||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
shlex "github.com/carapace-sh/carapace-shlex"
|
|
||||||
|
|
||||||
"sigs.k8s.io/kustomize/api/internal/plugins/utils"
|
"sigs.k8s.io/kustomize/api/internal/plugins/utils"
|
||||||
"sigs.k8s.io/kustomize/api/resmap"
|
"sigs.k8s.io/kustomize/api/resmap"
|
||||||
"sigs.k8s.io/kustomize/kyaml/errors"
|
"sigs.k8s.io/kustomize/kyaml/errors"
|
||||||
@@ -95,11 +93,11 @@ func (p *ExecPlugin) processOptionalArgsFields() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if c.ArgsOneLiner != "" {
|
if c.ArgsOneLiner != "" {
|
||||||
argsTolenSlice, err := shlex.Split(c.ArgsOneLiner)
|
argsTolenSlice, err := ShlexSplit(c.ArgsOneLiner)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to parse argsOneLiner: %w", err)
|
return fmt.Errorf("failed to parse argsOneLiner: %w", err)
|
||||||
}
|
}
|
||||||
p.args = argsTolenSlice.Strings()
|
p.args = argsTolenSlice
|
||||||
}
|
}
|
||||||
if c.ArgsFromFile != "" {
|
if c.ArgsFromFile != "" {
|
||||||
content, err := p.h.Loader().Load(c.ArgsFromFile)
|
content, err := p.h.Loader().Load(c.ArgsFromFile)
|
||||||
|
|||||||
19
api/internal/plugins/execplugin/shlex.go
Normal file
19
api/internal/plugins/execplugin/shlex.go
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
// Copyright 2019 The Kubernetes Authors.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
package execplugin
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
shlex "github.com/carapace-sh/carapace-shlex"
|
||||||
|
)
|
||||||
|
|
||||||
|
func ShlexSplit(s string) ([]string, error) {
|
||||||
|
// return shlexSplit(s)
|
||||||
|
tokens, err := shlex.Split(s)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("shlex split error: %w", err)
|
||||||
|
}
|
||||||
|
return tokens.Strings(), nil
|
||||||
|
}
|
||||||
177
api/internal/plugins/execplugin/shlex_test.go
Normal file
177
api/internal/plugins/execplugin/shlex_test.go
Normal file
@@ -0,0 +1,177 @@
|
|||||||
|
// Copyright 2019 The Kubernetes Authors.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
package execplugin
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestShlexSplit(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
input string
|
||||||
|
expected []string
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "basic space separation",
|
||||||
|
input: `hello world`,
|
||||||
|
expected: []string{"hello", "world"},
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "double quoted string",
|
||||||
|
input: `"hello world"`,
|
||||||
|
expected: []string{"hello world"},
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "single quoted string",
|
||||||
|
input: `'hello world'`,
|
||||||
|
expected: []string{"hello world"},
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "mixed quotes and words",
|
||||||
|
input: `hello "world test"`,
|
||||||
|
expected: []string{"hello", "world test"},
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "single quotes with spaces",
|
||||||
|
input: `hello 'world test'`,
|
||||||
|
expected: []string{"hello", "world test"},
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "nested quotes - single in double",
|
||||||
|
input: `"hello 'nested' world"`,
|
||||||
|
expected: []string{"hello 'nested' world"},
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "nested quotes - double in single",
|
||||||
|
input: `'hello "nested" world'`,
|
||||||
|
expected: []string{"hello \"nested\" world"},
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "escaped space",
|
||||||
|
input: `hello\ world`,
|
||||||
|
expected: []string{"hello world"},
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "escaped quotes in double quotes",
|
||||||
|
input: `"hello \"world\""`,
|
||||||
|
expected: []string{"hello \"world\""},
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "single quote in single quotes",
|
||||||
|
input: `'can'\''t'`,
|
||||||
|
expected: []string{"can't"},
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "complex argument list",
|
||||||
|
input: `arg1 "arg 2" 'arg 3' arg4`,
|
||||||
|
expected: []string{"arg1", "arg 2", "arg 3", "arg4"},
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "echo command with escaped quotes",
|
||||||
|
input: `echo "Hello, \"World!\""`,
|
||||||
|
expected: []string{"echo", "Hello, \"World!\""},
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "grep command with quoted search term",
|
||||||
|
input: `grep -r "search term" /path/to/dir`,
|
||||||
|
expected: []string{"grep", "-r", "search term", "/path/to/dir"},
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ls command with quoted filename",
|
||||||
|
input: `ls -la "file with spaces.txt"`,
|
||||||
|
expected: []string{"ls", "-la", "file with spaces.txt"},
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "empty string",
|
||||||
|
input: ``,
|
||||||
|
expected: []string{""},
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "multiple spaces",
|
||||||
|
input: ` multiple spaces `,
|
||||||
|
expected: []string{"multiple", "spaces", ""},
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "with comment string",
|
||||||
|
input: `echo "Hello, W#orld!" ${USER} # This is a comment`,
|
||||||
|
expected: []string{"echo", "Hello, W#orld!", "${USER}"},
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
// may cause an error in shlex at python3
|
||||||
|
{
|
||||||
|
name: "unclosed double quote",
|
||||||
|
input: `"unclosed quote`,
|
||||||
|
expected: []string{"unclosed quote"},
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "unclosed single quote",
|
||||||
|
input: `'unclosed quote`,
|
||||||
|
expected: []string{"unclosed quote"},
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "mixed unclosed quotes",
|
||||||
|
input: `"mixed 'quotes`,
|
||||||
|
expected: []string{"mixed 'quotes"},
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "single quote closed with double quote",
|
||||||
|
input: `"hello world'`,
|
||||||
|
expected: []string{"hello world'"},
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "double quote closed with single quote",
|
||||||
|
input: `'hello world"`,
|
||||||
|
expected: []string{"hello world\""},
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// execute each test case
|
||||||
|
for _, tc := range testCases {
|
||||||
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
// call the ShlexSplit function
|
||||||
|
result, err := ShlexSplit(tc.input)
|
||||||
|
|
||||||
|
// check for expected error
|
||||||
|
if tc.wantErr {
|
||||||
|
if err == nil {
|
||||||
|
t.Errorf("FAIL: Expected error but got none, Expected: %q\n", tc.expected)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if assert.NoError(t, err, "FAIL: Unexpected error for input %q", tc.input) {
|
||||||
|
// check if the result matches the expected output
|
||||||
|
assert.Equal(t, tc.expected, result,
|
||||||
|
"FAIL: Result mismatch,Input %q, Expected %q, Got: %q\n",
|
||||||
|
tc.input, tc.expected, result,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user