Compare commits

...

11 commits

Author SHA1 Message Date
Jeffrey Faer 4cc03be307
Merge 9ac0f55513 into 5a1acea321 2024-05-01 18:54:47 +00:00
Jeffrey Faer 9ac0f55513 Don't quote different completion types.
They're not going through compgen so they don't need it.
2024-05-01 12:54:23 -06:00
dependabot[bot] 5a1acea321
build(deps): bump github.com/cpuguy83/go-md2man/v2 from 2.0.3 to 2.0.4 (#2127) 2024-04-13 02:21:03 +00:00
Xinwei Xiong 0fc86c2ffd
docs: update user guide (#2128) 2024-04-08 06:47:35 -04:00
Ville Skyttä 6b5f577ebc
More linting (#2099)
* Address gocritic findings, enable it

* Enable gosimple, no new findings to address
2024-04-01 08:42:08 -04:00
Pedro Mota bd914e58d6
fix: remove deprecated io/ioutils package (#2120)
ioutils.ReadAll is deprecated since Go 1.16. This commit replaces it with
io.ReadAll. See https://pkg.go.dev/io/ioutil\#ReadAll for reference

Issue #2119
2024-03-12 06:42:46 -04:00
racerole 1f80fa2e23
chore: remove repetitive words (#2122)
Signed-off-by: racerole <jiangyifeng@outlook.com>
2024-03-12 06:40:19 -04:00
damas c69ae4c36b
ci: test golang 1.22 (#2113) 2024-03-12 06:40:01 -04:00
dependabot[bot] a30cee5e5a
build(deps): bump actions/cache from 3 to 4 (#2102)
Bumps [actions/cache](https://github.com/actions/cache) from 3 to 4.
- [Release notes](https://github.com/actions/cache/releases)
- [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md)
- [Commits](https://github.com/actions/cache/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/cache
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-11 19:36:37 -06:00
dependabot[bot] f34069ccf5
build(deps): bump golangci/golangci-lint-action from 3.7.0 to 4.0.0 (#2108)
Bumps [golangci/golangci-lint-action](https://github.com/golangci/golangci-lint-action) from 3.7.0 to 4.0.0.
- [Release notes](https://github.com/golangci/golangci-lint-action/releases)
- [Commits](https://github.com/golangci/golangci-lint-action/compare/v3.7.0...v4.0.0)

---
updated-dependencies:
- dependency-name: golangci/golangci-lint-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-11 19:35:05 -06:00
montag451 bd2655e76c
Add Incus to the list of projects using Cobra (#2118) 2024-03-07 19:36:58 -05:00
14 changed files with 40 additions and 44 deletions

View file

@ -43,11 +43,11 @@ jobs:
- uses: actions/setup-go@v5 - uses: actions/setup-go@v5
with: with:
go-version: '^1.21' go-version: '^1.22'
check-latest: true check-latest: true
cache: true cache: true
- uses: golangci/golangci-lint-action@v3.7.0 - uses: golangci/golangci-lint-action@v4.0.0
with: with:
version: latest version: latest
args: --verbose args: --verbose
@ -66,6 +66,7 @@ jobs:
- 19 - 19
- 20 - 20
- 21 - 21
- 22
name: '${{ matrix.platform }} | 1.${{ matrix.go }}.x' name: '${{ matrix.platform }} | 1.${{ matrix.go }}.x'
runs-on: ${{ matrix.platform }}-latest runs-on: ${{ matrix.platform }}-latest
steps: steps:
@ -108,7 +109,7 @@ jobs:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: actions/cache@v3 - uses: actions/cache@v4
with: with:
path: ~/go/pkg/mod path: ~/go/pkg/mod
key: ${{ runner.os }}-${{ matrix.go }}-${{ hashFiles('**/go.sum') }} key: ${{ runner.os }}-${{ matrix.go }}-${{ hashFiles('**/go.sum') }}

View file

@ -29,7 +29,7 @@ linters:
- gas - gas
#- gochecknoinits #- gochecknoinits
- goconst - goconst
#- gocritic - gocritic
#- gocyclo #- gocyclo
#- gofmt #- gofmt
- goimports - goimports
@ -37,7 +37,7 @@ linters:
#- gomnd #- gomnd
#- goprintffuncname #- goprintffuncname
#- gosec #- gosec
#- gosimple - gosimple
- govet - govet
- ineffassign - ineffassign
- interfacer - interfacer

View file

@ -597,19 +597,16 @@ func writeRequiredFlag(buf io.StringWriter, cmd *Command) {
if nonCompletableFlag(flag) { if nonCompletableFlag(flag) {
return return
} }
for key := range flag.Annotations { if _, ok := flag.Annotations[BashCompOneRequiredFlag]; ok {
switch key { format := " must_have_one_flag+=(\"--%s"
case BashCompOneRequiredFlag: if flag.Value.Type() != "bool" {
format := " must_have_one_flag+=(\"--%s" format += "="
if flag.Value.Type() != "bool" { }
format += "=" format += cbn
} WriteStringAndCheck(buf, fmt.Sprintf(format, flag.Name))
format += cbn
WriteStringAndCheck(buf, fmt.Sprintf(format, flag.Name))
if len(flag.Shorthand) > 0 { if len(flag.Shorthand) > 0 {
WriteStringAndCheck(buf, fmt.Sprintf(" must_have_one_flag+=(\"-%s"+cbn, flag.Shorthand)) WriteStringAndCheck(buf, fmt.Sprintf(" must_have_one_flag+=(\"-%s"+cbn, flag.Shorthand))
}
} }
} }
}) })

View file

@ -220,24 +220,15 @@ __%[1]s_handle_completion_types() {
# completions at once on the command-line we must remove the descriptions. # completions at once on the command-line we must remove the descriptions.
# https://github.com/spf13/cobra/issues/1508 # https://github.com/spf13/cobra/issues/1508
local tab=$'\t' comp local tab=$'\t' comp
local matches=()
for comp in "${completions[@]}"; do for comp in "${completions[@]}"; do
[[ -z $comp ]] && continue [[ -z $comp ]] && continue
# Strip any description # Strip any description
comp=${comp%%%%$tab*} comp=${comp%%%%$tab*}
# Only consider the completions that match # Only consider the completions that match
if [[ $comp == "$cur"* ]]; then if [[ $comp == "$cur"* ]]; then
# Strictly speaking we could append directly to COMPREPLY here. COMPREPLY+=( "$comp" )
# But there's a pretty big performance hit involved with
# creating one subshell to printf %%q for each completion that
# matches. Instead, batch all the matches up so we can quote
# them all at once in a single printf call.
matches+=( "$comp" )
fi fi
done done
while IFS='' read -r comp; do
COMPREPLY+=( "$comp" )
done < <(printf "%%q\n" "${matches[@]}")
;; ;;
*) *)

View file

@ -18,7 +18,7 @@ import (
"bytes" "bytes"
"context" "context"
"fmt" "fmt"
"io/ioutil" "io"
"os" "os"
"reflect" "reflect"
"strings" "strings"
@ -2092,12 +2092,12 @@ func TestCommandPrintRedirection(t *testing.T) {
t.Error(err) t.Error(err)
} }
gotErrBytes, err := ioutil.ReadAll(errBuff) gotErrBytes, err := io.ReadAll(errBuff)
if err != nil { if err != nil {
t.Error(err) t.Error(err)
} }
gotOutBytes, err := ioutil.ReadAll(outBuff) gotOutBytes, err := io.ReadAll(outBuff)
if err != nil { if err != nil {
t.Error(err) t.Error(err)
} }
@ -2777,7 +2777,7 @@ func TestFind(t *testing.T) {
func TestUnknownFlagShouldReturnSameErrorRegardlessOfArgPosition(t *testing.T) { func TestUnknownFlagShouldReturnSameErrorRegardlessOfArgPosition(t *testing.T) {
testCases := [][]string{ testCases := [][]string{
//{"--unknown", "--namespace", "foo", "child", "--bar"}, // FIXME: This test case fails, returning the error `unknown command "foo" for "root"` instead of the expected error `unknown flag: --unknown` // {"--unknown", "--namespace", "foo", "child", "--bar"}, // FIXME: This test case fails, returning the error `unknown command "foo" for "root"` instead of the expected error `unknown flag: --unknown`
{"--namespace", "foo", "--unknown", "child", "--bar"}, {"--namespace", "foo", "--unknown", "child", "--bar"},
{"--namespace", "foo", "child", "--unknown", "--bar"}, {"--namespace", "foo", "child", "--unknown", "--bar"},
{"--namespace", "foo", "child", "--bar", "--unknown"}, {"--namespace", "foo", "child", "--bar", "--unknown"},

View file

@ -133,7 +133,7 @@ func fillHeader(header *GenManHeader, name string, disableAutoGen bool) error {
} }
header.Date = &now header.Date = &now
} }
header.date = (*header.Date).Format("Jan 2006") header.date = header.Date.Format("Jan 2006")
if header.Source == "" && !disableAutoGen { if header.Source == "" && !disableAutoGen {
header.Source = "Auto generated by spf13/cobra" header.Source = "Auto generated by spf13/cobra"
} }

View file

@ -128,7 +128,7 @@ func GenMarkdownTree(cmd *cobra.Command, dir string) error {
return GenMarkdownTreeCustom(cmd, dir, emptyStr, identity) return GenMarkdownTreeCustom(cmd, dir, emptyStr, identity)
} }
// GenMarkdownTreeCustom is the the same as GenMarkdownTree, but // GenMarkdownTreeCustom is the same as GenMarkdownTree, but
// with custom filePrepender and linkHandler. // with custom filePrepender and linkHandler.
func GenMarkdownTreeCustom(cmd *cobra.Command, dir string, filePrepender, linkHandler func(string) string) error { func GenMarkdownTreeCustom(cmd *cobra.Command, dir string, filePrepender, linkHandler func(string) string) error {
for _, c := range cmd.Commands() { for _, c := range cmd.Commands() {

View file

@ -140,7 +140,7 @@ func GenReSTTree(cmd *cobra.Command, dir string) error {
return GenReSTTreeCustom(cmd, dir, emptyStr, defaultLinkHandler) return GenReSTTreeCustom(cmd, dir, emptyStr, defaultLinkHandler)
} }
// GenReSTTreeCustom is the the same as GenReSTTree, but // GenReSTTreeCustom is the same as GenReSTTree, but
// with custom filePrepender and linkHandler. // with custom filePrepender and linkHandler.
func GenReSTTreeCustom(cmd *cobra.Command, dir string, filePrepender func(string) string, linkHandler func(string, string) string) error { func GenReSTTreeCustom(cmd *cobra.Command, dir string, filePrepender func(string) string, linkHandler func(string, string) string) error {
for _, c := range cmd.Commands() { for _, c := range cmd.Commands() {

View file

@ -40,7 +40,7 @@ func hasSeeAlso(cmd *cobra.Command) bool {
// that do not contain \n. // that do not contain \n.
func forceMultiLine(s string) string { func forceMultiLine(s string) string {
if len(s) > 60 && !strings.Contains(s, "\n") { if len(s) > 60 && !strings.Contains(s, "\n") {
s = s + "\n" s += "\n"
} }
return s return s
} }

2
go.mod
View file

@ -3,7 +3,7 @@ module github.com/spf13/cobra
go 1.15 go 1.15
require ( require (
github.com/cpuguy83/go-md2man/v2 v2.0.3 github.com/cpuguy83/go-md2man/v2 v2.0.4
github.com/inconshreveable/mousetrap v1.1.0 github.com/inconshreveable/mousetrap v1.1.0
github.com/spf13/pflag v1.0.5 github.com/spf13/pflag v1.0.5
gopkg.in/yaml.v3 v3.0.1 gopkg.in/yaml.v3 v3.0.1

4
go.sum
View file

@ -1,5 +1,5 @@
github.com/cpuguy83/go-md2man/v2 v2.0.3 h1:qMCsGGgs+MAzDFyp9LpAe1Lqy/fY/qCovCm0qnXZOBM= github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4=
github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=

View file

@ -28,8 +28,8 @@ import (
func genPowerShellComp(buf io.StringWriter, name string, includeDesc bool) { func genPowerShellComp(buf io.StringWriter, name string, includeDesc bool) {
// Variables should not contain a '-' or ':' character // Variables should not contain a '-' or ':' character
nameForVar := name nameForVar := name
nameForVar = strings.Replace(nameForVar, "-", "_", -1) nameForVar = strings.ReplaceAll(nameForVar, "-", "_")
nameForVar = strings.Replace(nameForVar, ":", "_", -1) nameForVar = strings.ReplaceAll(nameForVar, ":", "_")
compCmd := ShellCompRequestCmd compCmd := ShellCompRequestCmd
if !includeDesc { if !includeDesc {

View file

@ -24,6 +24,7 @@
- [GoReleaser](https://goreleaser.com) - [GoReleaser](https://goreleaser.com)
- [Helm](https://helm.sh) - [Helm](https://helm.sh)
- [Hugo](https://gohugo.io) - [Hugo](https://gohugo.io)
- [Incus](https://linuxcontainers.org/incus/)
- [Infracost](https://github.com/infracost/infracost) - [Infracost](https://github.com/infracost/infracost)
- [Istio](https://istio.io) - [Istio](https://istio.io)
- [Kool](https://github.com/kool-dev/kool) - [Kool](https://github.com/kool-dev/kool)

View file

@ -3,7 +3,7 @@
While you are welcome to provide your own organization, typically a Cobra-based While you are welcome to provide your own organization, typically a Cobra-based
application will follow the following organizational structure: application will follow the following organizational structure:
``` ```test
▾ appName/ ▾ appName/
▾ cmd/ ▾ cmd/
add.go add.go
@ -301,6 +301,7 @@ command := cobra.Command{
### Bind Flags with Config ### Bind Flags with Config
You can also bind your flags with [viper](https://github.com/spf13/viper): You can also bind your flags with [viper](https://github.com/spf13/viper):
```go ```go
var author string var author string
@ -320,12 +321,14 @@ More in [viper documentation](https://github.com/spf13/viper#working-with-flags)
Flags are optional by default. If instead you wish your command to report an error Flags are optional by default. If instead you wish your command to report an error
when a flag has not been set, mark it as required: when a flag has not been set, mark it as required:
```go ```go
rootCmd.Flags().StringVarP(&Region, "region", "r", "", "AWS region (required)") rootCmd.Flags().StringVarP(&Region, "region", "r", "", "AWS region (required)")
rootCmd.MarkFlagRequired("region") rootCmd.MarkFlagRequired("region")
``` ```
Or, for persistent flags: Or, for persistent flags:
```go ```go
rootCmd.PersistentFlags().StringVarP(&Region, "region", "r", "", "AWS region (required)") rootCmd.PersistentFlags().StringVarP(&Region, "region", "r", "", "AWS region (required)")
rootCmd.MarkPersistentFlagRequired("region") rootCmd.MarkPersistentFlagRequired("region")
@ -335,6 +338,7 @@ rootCmd.MarkPersistentFlagRequired("region")
If you have different flags that must be provided together (e.g. if they provide the `--username` flag they MUST provide the `--password` flag as well) then If you have different flags that must be provided together (e.g. if they provide the `--username` flag they MUST provide the `--password` flag as well) then
Cobra can enforce that requirement: Cobra can enforce that requirement:
```go ```go
rootCmd.Flags().StringVarP(&u, "username", "u", "", "Username (required if password is set)") rootCmd.Flags().StringVarP(&u, "username", "u", "", "Username (required if password is set)")
rootCmd.Flags().StringVarP(&pw, "password", "p", "", "Password (required if username is set)") rootCmd.Flags().StringVarP(&pw, "password", "p", "", "Password (required if username is set)")
@ -343,6 +347,7 @@ rootCmd.MarkFlagsRequiredTogether("username", "password")
You can also prevent different flags from being provided together if they represent mutually You can also prevent different flags from being provided together if they represent mutually
exclusive options such as specifying an output format as either `--json` or `--yaml` but never both: exclusive options such as specifying an output format as either `--json` or `--yaml` but never both:
```go ```go
rootCmd.Flags().BoolVar(&ofJson, "json", false, "Output in JSON") rootCmd.Flags().BoolVar(&ofJson, "json", false, "Output in JSON")
rootCmd.Flags().BoolVar(&ofYaml, "yaml", false, "Output in YAML") rootCmd.Flags().BoolVar(&ofYaml, "yaml", false, "Output in YAML")
@ -351,6 +356,7 @@ rootCmd.MarkFlagsMutuallyExclusive("json", "yaml")
If you want to require at least one flag from a group to be present, you can use `MarkFlagsOneRequired`. If you want to require at least one flag from a group to be present, you can use `MarkFlagsOneRequired`.
This can be combined with `MarkFlagsMutuallyExclusive` to enforce exactly one flag from a given group: This can be combined with `MarkFlagsMutuallyExclusive` to enforce exactly one flag from a given group:
```go ```go
rootCmd.Flags().BoolVar(&ofJson, "json", false, "Output in JSON") rootCmd.Flags().BoolVar(&ofJson, "json", false, "Output in JSON")
rootCmd.Flags().BoolVar(&ofYaml, "yaml", false, "Output in YAML") rootCmd.Flags().BoolVar(&ofYaml, "yaml", false, "Output in YAML")
@ -428,7 +434,7 @@ by not providing a 'Run' for the 'rootCmd'.
We have only defined one flag for a single command. We have only defined one flag for a single command.
More documentation about flags is available at https://github.com/spf13/pflag More documentation about flags is available at https://github.com/spf13/pflag.
```go ```go
package main package main
@ -722,7 +728,7 @@ command.SuggestionsMinimumDistance = 1
You can also explicitly set names for which a given command will be suggested using the `SuggestFor` attribute. This allows suggestions for strings that are not close in terms of string distance, but make sense in your set of commands but for which You can also explicitly set names for which a given command will be suggested using the `SuggestFor` attribute. This allows suggestions for strings that are not close in terms of string distance, but make sense in your set of commands but for which
you don't want aliases. Example: you don't want aliases. Example:
``` ```bash
$ kubectl remove $ kubectl remove
Error: unknown command "remove" for "kubectl" Error: unknown command "remove" for "kubectl"
@ -787,7 +793,7 @@ func main() {
Example run as a kubectl plugin: Example run as a kubectl plugin:
``` ```bash
$ kubectl myplugin $ kubectl myplugin
Usage: Usage:
kubectl myplugin [command] kubectl myplugin [command]