Skip to content

Commit

Permalink
Merge branch 'spf13:main' into dm/local-flags-doc
Browse files Browse the repository at this point in the history
  • Loading branch information
niamster authored Jan 6, 2024
2 parents 5105640 + 0dec88e commit d35fd5f
Show file tree
Hide file tree
Showing 16 changed files with 566 additions and 61 deletions.
19 changes: 13 additions & 6 deletions .github/labeler.yml
Original file line number Diff line number Diff line change
@@ -1,17 +1,24 @@
# changes to documentation generation
"area/docs-generation": doc/**/*
"area/docs-generation":
- changed-files:
- any-glob-to-any-file: 'doc/**'

# changes to the core cobra command
"area/cobra-command":
- any: ['./cobra.go', './cobra_test.go', './*command*.go']
- changed-files:
- any-glob-to-any-file: ['./cobra.go', './cobra_test.go', './*command*.go']

# changes made to command flags/args
"area/flags": ./args*.go
"area/flags":
- changed-files:
- any-glob-to-any-file: './args*.go'

# changes to Github workflows
"area/github": .github/**/*
"area/github":
- changed-files:
- any-glob-to-any-file: '.github/**'

# changes to shell completions
"area/shell-completion":
- ./*completions*

- changed-files:
- any-glob-to-any-file: './*completions*'
2 changes: 1 addition & 1 deletion .github/workflows/labeler.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
pull-requests: write # for actions/labeler to add labels to PRs
runs-on: ubuntu-latest
steps:
- uses: actions/labeler@v4
- uses: actions/labeler@v5
with:
repo-token: "${{ github.token }}"

6 changes: 2 additions & 4 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,12 @@ jobs:

- uses: actions/checkout@v4

- uses: actions/setup-go@v4
- uses: actions/setup-go@v5
with:
go-version: '^1.21'
check-latest: true
cache: true

- uses: actions/checkout@v4

- uses: golangci/[email protected]
with:
version: latest
Expand All @@ -74,7 +72,7 @@ jobs:

- uses: actions/checkout@v4

- uses: actions/setup-go@v4
- uses: actions/setup-go@v5
with:
go-version: 1.${{ matrix.go }}.x
cache: true
Expand Down
13 changes: 3 additions & 10 deletions active_help.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,17 @@ package cobra
import (
"fmt"
"os"
"regexp"
"strings"
)

const (
activeHelpMarker = "_activeHelp_ "
// The below values should not be changed: programs will be using them explicitly
// in their user documentation, and users will be using them explicitly.
activeHelpEnvVarSuffix = "_ACTIVE_HELP"
activeHelpGlobalEnvVar = "COBRA_ACTIVE_HELP"
activeHelpEnvVarSuffix = "ACTIVE_HELP"
activeHelpGlobalEnvVar = configEnvVarGlobalPrefix + "_" + activeHelpEnvVarSuffix
activeHelpGlobalDisable = "0"
)

var activeHelpEnvVarPrefixSubstRegexp = regexp.MustCompile(`[^A-Z0-9_]`)

// AppendActiveHelp adds the specified string to the specified array to be used as ActiveHelp.
// Such strings will be processed by the completion script and will be shown as ActiveHelp
// to the user.
Expand Down Expand Up @@ -60,8 +56,5 @@ func GetActiveHelpConfig(cmd *Command) string {
// variable. It has the format <PROGRAM>_ACTIVE_HELP where <PROGRAM> is the name of the
// root command in upper case, with all non-ASCII-alphanumeric characters replaced by `_`.
func activeHelpEnvVar(name string) string {
// This format should not be changed: users will be using it explicitly.
activeHelpEnvVar := strings.ToUpper(fmt.Sprintf("%s%s", name, activeHelpEnvVarSuffix))
activeHelpEnvVar = activeHelpEnvVarPrefixSubstRegexp.ReplaceAllString(activeHelpEnvVar, "_")
return activeHelpEnvVar
return configEnvVar(name, activeHelpEnvVarSuffix)
}
4 changes: 2 additions & 2 deletions args.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,9 @@ func OnlyValidArgs(cmd *Command, args []string) error {
if len(cmd.ValidArgs) > 0 {
// Remove any description that may be included in ValidArgs.
// A description is following a tab character.
var validArgs []string
validArgs := make([]string, 0, len(cmd.ValidArgs))
for _, v := range cmd.ValidArgs {
validArgs = append(validArgs, strings.Split(v, "\t")[0])
validArgs = append(validArgs, strings.SplitN(v, "\t", 2)[0])
}
for _, v := range args {
if !stringInSlice(v, validArgs) {
Expand Down
2 changes: 1 addition & 1 deletion bash_completions.go
Original file line number Diff line number Diff line change
Expand Up @@ -621,7 +621,7 @@ func writeRequiredNouns(buf io.StringWriter, cmd *Command) {
for _, value := range cmd.ValidArgs {
// Remove any description that may be included following a tab character.
// Descriptions are not supported by bash completion.
value = strings.Split(value, "\t")[0]
value = strings.SplitN(value, "\t", 2)[0]
WriteStringAndCheck(buf, fmt.Sprintf(" must_have_one_noun+=(%q)\n", value))
}
if cmd.ValidArgsFunction != nil {
Expand Down
2 changes: 0 additions & 2 deletions cobra.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,8 +193,6 @@ func ld(s, t string, ignoreCase bool) int {
d := make([][]int, len(s)+1)
for i := range d {
d[i] = make([]int, len(t)+1)
}
for i := range d {
d[i][0] = i
}
for j := range d[0] {
Expand Down
182 changes: 182 additions & 0 deletions cobra_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,185 @@ func TestAddTemplateFunctions(t *testing.T) {
t.Errorf("Expected UsageString: %v\nGot: %v", expected, got)
}
}

func TestLevenshteinDistance(t *testing.T) {
tests := []struct {
name string
s string
t string
ignoreCase bool
expected int
}{
{
name: "Equal strings (case-sensitive)",
s: "hello",
t: "hello",
ignoreCase: false,
expected: 0,
},
{
name: "Equal strings (case-insensitive)",
s: "Hello",
t: "hello",
ignoreCase: true,
expected: 0,
},
{
name: "Different strings (case-sensitive)",
s: "kitten",
t: "sitting",
ignoreCase: false,
expected: 3,
},
{
name: "Different strings (case-insensitive)",
s: "Kitten",
t: "Sitting",
ignoreCase: true,
expected: 3,
},
{
name: "Empty strings",
s: "",
t: "",
ignoreCase: false,
expected: 0,
},
{
name: "One empty string",
s: "abc",
t: "",
ignoreCase: false,
expected: 3,
},
{
name: "Both empty strings",
s: "",
t: "",
ignoreCase: true,
expected: 0,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Act
got := ld(tt.s, tt.t, tt.ignoreCase)

// Assert
if got != tt.expected {
t.Errorf("Expected ld: %v\nGot: %v", tt.expected, got)
}
})
}
}

func TestStringInSlice(t *testing.T) {
tests := []struct {
name string
a string
list []string
expected bool
}{
{
name: "String in slice (case-sensitive)",
a: "apple",
list: []string{"orange", "banana", "apple", "grape"},
expected: true,
},
{
name: "String not in slice (case-sensitive)",
a: "pear",
list: []string{"orange", "banana", "apple", "grape"},
expected: false,
},
{
name: "String in slice (case-insensitive)",
a: "APPLE",
list: []string{"orange", "banana", "apple", "grape"},
expected: false,
},
{
name: "Empty slice",
a: "apple",
list: []string{},
expected: false,
},
{
name: "Empty string",
a: "",
list: []string{"orange", "banana", "apple", "grape"},
expected: false,
},
{
name: "Empty strings match",
a: "",
list: []string{"orange", ""},
expected: true,
},
{
name: "Empty string in empty slice",
a: "",
list: []string{},
expected: false,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Act
got := stringInSlice(tt.a, tt.list)

// Assert
if got != tt.expected {
t.Errorf("Expected stringInSlice: %v\nGot: %v", tt.expected, got)
}
})
}
}

func TestRpad(t *testing.T) {
tests := []struct {
name string
inputString string
padding int
expected string
}{
{
name: "Padding required",
inputString: "Hello",
padding: 10,
expected: "Hello ",
},
{
name: "No padding required",
inputString: "World",
padding: 5,
expected: "World",
},
{
name: "Empty string",
inputString: "",
padding: 8,
expected: " ",
},
{
name: "Zero padding",
inputString: "cobra",
padding: 0,
expected: "cobra",
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Act
got := rpad(tt.inputString, tt.padding)

// Assert
if got != tt.expected {
t.Errorf("Expected rpad: %v\nGot: %v", tt.expected, got)
}
})
}
}
Loading

0 comments on commit d35fd5f

Please sign in to comment.