[chore]: Bump github.com/spf13/cobra from 1.6.1 to 1.7.0 (#1686)
Bumps [github.com/spf13/cobra](https://github.com/spf13/cobra) from 1.6.1 to 1.7.0. - [Release notes](https://github.com/spf13/cobra/releases) - [Commits](https://github.com/spf13/cobra/compare/v1.6.1...v1.7.0) --- updated-dependencies: - dependency-name: github.com/spf13/cobra dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
This commit is contained in:
parent
158facf011
commit
014d7ac131
4
go.mod
4
go.mod
|
@ -39,7 +39,7 @@ require (
|
||||||
github.com/minio/minio-go/v7 v7.0.50
|
github.com/minio/minio-go/v7 v7.0.50
|
||||||
github.com/mitchellh/mapstructure v1.5.0
|
github.com/mitchellh/mapstructure v1.5.0
|
||||||
github.com/oklog/ulid v1.3.1
|
github.com/oklog/ulid v1.3.1
|
||||||
github.com/spf13/cobra v1.6.1
|
github.com/spf13/cobra v1.7.0
|
||||||
github.com/spf13/viper v1.15.0
|
github.com/spf13/viper v1.15.0
|
||||||
github.com/stretchr/testify v1.8.2
|
github.com/stretchr/testify v1.8.2
|
||||||
github.com/superseriousbusiness/activity v1.2.2-gts
|
github.com/superseriousbusiness/activity v1.2.2-gts
|
||||||
|
@ -108,7 +108,7 @@ require (
|
||||||
github.com/gorilla/securecookie v1.1.1 // indirect
|
github.com/gorilla/securecookie v1.1.1 // indirect
|
||||||
github.com/gorilla/sessions v1.2.1 // indirect
|
github.com/gorilla/sessions v1.2.1 // indirect
|
||||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||||
github.com/inconshreveable/mousetrap v1.0.1 // indirect
|
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||||
github.com/jackc/chunkreader/v2 v2.0.1 // indirect
|
github.com/jackc/chunkreader/v2 v2.0.1 // indirect
|
||||||
github.com/jackc/pgio v1.0.0 // indirect
|
github.com/jackc/pgio v1.0.0 // indirect
|
||||||
github.com/jackc/pgpassfile v1.0.0 // indirect
|
github.com/jackc/pgpassfile v1.0.0 // indirect
|
||||||
|
|
8
go.sum
8
go.sum
|
@ -331,8 +331,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:
|
||||||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||||
github.com/imkira/go-interpol v1.1.0 h1:KIiKr0VSG2CUW1hl1jpiyuzuJeKUUpC8iM1AIE7N1Vk=
|
github.com/imkira/go-interpol v1.1.0 h1:KIiKr0VSG2CUW1hl1jpiyuzuJeKUUpC8iM1AIE7N1Vk=
|
||||||
github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA=
|
github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA=
|
||||||
github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc=
|
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||||
github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||||
github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo=
|
github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo=
|
||||||
github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
|
github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
|
||||||
github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8=
|
github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8=
|
||||||
|
@ -516,8 +516,8 @@ github.com/spf13/afero v1.9.3 h1:41FoI0fD7OR7mGcKE/aOiLkGreyf8ifIOQmJANWogMk=
|
||||||
github.com/spf13/afero v1.9.3/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y=
|
github.com/spf13/afero v1.9.3/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y=
|
||||||
github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w=
|
github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w=
|
||||||
github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU=
|
github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU=
|
||||||
github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA=
|
github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I=
|
||||||
github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY=
|
github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0=
|
||||||
github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
|
github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
|
||||||
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
|
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
|
||||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
//go:build !windows
|
||||||
// +build !windows
|
// +build !windows
|
||||||
|
|
||||||
package mousetrap
|
package mousetrap
|
||||||
|
|
|
@ -1,79 +1,30 @@
|
||||||
// +build windows
|
|
||||||
// +build !go1.4
|
|
||||||
|
|
||||||
package mousetrap
|
package mousetrap
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"syscall"
|
"syscall"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
func getProcessEntry(pid int) (*syscall.ProcessEntry32, error) {
|
||||||
// defined by the Win32 API
|
snapshot, err := syscall.CreateToolhelp32Snapshot(syscall.TH32CS_SNAPPROCESS, 0)
|
||||||
th32cs_snapprocess uintptr = 0x2
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
kernel = syscall.MustLoadDLL("kernel32.dll")
|
|
||||||
CreateToolhelp32Snapshot = kernel.MustFindProc("CreateToolhelp32Snapshot")
|
|
||||||
Process32First = kernel.MustFindProc("Process32FirstW")
|
|
||||||
Process32Next = kernel.MustFindProc("Process32NextW")
|
|
||||||
)
|
|
||||||
|
|
||||||
// ProcessEntry32 structure defined by the Win32 API
|
|
||||||
type processEntry32 struct {
|
|
||||||
dwSize uint32
|
|
||||||
cntUsage uint32
|
|
||||||
th32ProcessID uint32
|
|
||||||
th32DefaultHeapID int
|
|
||||||
th32ModuleID uint32
|
|
||||||
cntThreads uint32
|
|
||||||
th32ParentProcessID uint32
|
|
||||||
pcPriClassBase int32
|
|
||||||
dwFlags uint32
|
|
||||||
szExeFile [syscall.MAX_PATH]uint16
|
|
||||||
}
|
|
||||||
|
|
||||||
func getProcessEntry(pid int) (pe *processEntry32, err error) {
|
|
||||||
snapshot, _, e1 := CreateToolhelp32Snapshot.Call(th32cs_snapprocess, uintptr(0))
|
|
||||||
if snapshot == uintptr(syscall.InvalidHandle) {
|
|
||||||
err = fmt.Errorf("CreateToolhelp32Snapshot: %v", e1)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer syscall.CloseHandle(syscall.Handle(snapshot))
|
|
||||||
|
|
||||||
var processEntry processEntry32
|
|
||||||
processEntry.dwSize = uint32(unsafe.Sizeof(processEntry))
|
|
||||||
ok, _, e1 := Process32First.Call(snapshot, uintptr(unsafe.Pointer(&processEntry)))
|
|
||||||
if ok == 0 {
|
|
||||||
err = fmt.Errorf("Process32First: %v", e1)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
for {
|
|
||||||
if processEntry.th32ProcessID == uint32(pid) {
|
|
||||||
pe = &processEntry
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
ok, _, e1 = Process32Next.Call(snapshot, uintptr(unsafe.Pointer(&processEntry)))
|
|
||||||
if ok == 0 {
|
|
||||||
err = fmt.Errorf("Process32Next: %v", e1)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func getppid() (pid int, err error) {
|
|
||||||
pe, err := getProcessEntry(os.Getpid())
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return nil, err
|
||||||
|
}
|
||||||
|
defer syscall.CloseHandle(snapshot)
|
||||||
|
var procEntry syscall.ProcessEntry32
|
||||||
|
procEntry.Size = uint32(unsafe.Sizeof(procEntry))
|
||||||
|
if err = syscall.Process32First(snapshot, &procEntry); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for {
|
||||||
|
if procEntry.ProcessID == uint32(pid) {
|
||||||
|
return &procEntry, nil
|
||||||
|
}
|
||||||
|
err = syscall.Process32Next(snapshot, &procEntry)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pid = int(pe.th32ParentProcessID)
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// StartedByExplorer returns true if the program was invoked by the user double-clicking
|
// StartedByExplorer returns true if the program was invoked by the user double-clicking
|
||||||
|
@ -83,16 +34,9 @@ func getppid() (pid int, err error) {
|
||||||
// It does not guarantee that the program was run from a terminal. It only can tell you
|
// It does not guarantee that the program was run from a terminal. It only can tell you
|
||||||
// whether it was launched from explorer.exe
|
// whether it was launched from explorer.exe
|
||||||
func StartedByExplorer() bool {
|
func StartedByExplorer() bool {
|
||||||
ppid, err := getppid()
|
pe, err := getProcessEntry(syscall.Getppid())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
return "explorer.exe" == syscall.UTF16ToString(pe.ExeFile[:])
|
||||||
pe, err := getProcessEntry(ppid)
|
|
||||||
if err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
name := syscall.UTF16ToString(pe.szExeFile[:])
|
|
||||||
return name == "explorer.exe"
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,46 +0,0 @@
|
||||||
// +build windows
|
|
||||||
// +build go1.4
|
|
||||||
|
|
||||||
package mousetrap
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
"syscall"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
func getProcessEntry(pid int) (*syscall.ProcessEntry32, error) {
|
|
||||||
snapshot, err := syscall.CreateToolhelp32Snapshot(syscall.TH32CS_SNAPPROCESS, 0)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
defer syscall.CloseHandle(snapshot)
|
|
||||||
var procEntry syscall.ProcessEntry32
|
|
||||||
procEntry.Size = uint32(unsafe.Sizeof(procEntry))
|
|
||||||
if err = syscall.Process32First(snapshot, &procEntry); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
for {
|
|
||||||
if procEntry.ProcessID == uint32(pid) {
|
|
||||||
return &procEntry, nil
|
|
||||||
}
|
|
||||||
err = syscall.Process32Next(snapshot, &procEntry)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// StartedByExplorer returns true if the program was invoked by the user double-clicking
|
|
||||||
// on the executable from explorer.exe
|
|
||||||
//
|
|
||||||
// It is conservative and returns false if any of the internal calls fail.
|
|
||||||
// It does not guarantee that the program was run from a terminal. It only can tell you
|
|
||||||
// whether it was launched from explorer.exe
|
|
||||||
func StartedByExplorer() bool {
|
|
||||||
pe, err := getProcessEntry(os.Getppid())
|
|
||||||
if err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return "explorer.exe" == syscall.UTF16ToString(pe.ExeFile[:])
|
|
||||||
}
|
|
|
@ -1,4 +1,4 @@
|
||||||
# Copyright 2013-2022 The Cobra Authors
|
# Copyright 2013-2023 The Cobra Authors
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
|
|
|
@ -5,10 +5,6 @@ ifeq (, $(shell which golangci-lint))
|
||||||
$(warning "could not find golangci-lint in $(PATH), run: curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh")
|
$(warning "could not find golangci-lint in $(PATH), run: curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh")
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq (, $(shell which richgo))
|
|
||||||
$(warning "could not find richgo in $(PATH), run: go install github.com/kyoh86/richgo@latest")
|
|
||||||
endif
|
|
||||||
|
|
||||||
.PHONY: fmt lint test install_deps clean
|
.PHONY: fmt lint test install_deps clean
|
||||||
|
|
||||||
default: all
|
default: all
|
||||||
|
@ -25,6 +21,10 @@ lint:
|
||||||
|
|
||||||
test: install_deps
|
test: install_deps
|
||||||
$(info ******************** running tests ********************)
|
$(info ******************** running tests ********************)
|
||||||
|
go test -v ./...
|
||||||
|
|
||||||
|
richtest: install_deps
|
||||||
|
$(info ******************** running tests with kyoh86/richgo ********************)
|
||||||
richgo test -v ./...
|
richgo test -v ./...
|
||||||
|
|
||||||
install_deps:
|
install_deps:
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
![cobra logo](https://cloud.githubusercontent.com/assets/173412/10886352/ad566232-814f-11e5-9cd0-aa101788c117.png)
|
![cobra logo](assets/CobraMain.png)
|
||||||
|
|
||||||
Cobra is a library for creating powerful modern CLI applications.
|
Cobra is a library for creating powerful modern CLI applications.
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ Cobra is used in many Go projects such as [Kubernetes](https://kubernetes.io/),
|
||||||
[Hugo](https://gohugo.io), and [GitHub CLI](https://github.com/cli/cli) to
|
[Hugo](https://gohugo.io), and [GitHub CLI](https://github.com/cli/cli) to
|
||||||
name a few. [This list](./projects_using_cobra.md) contains a more extensive list of projects using Cobra.
|
name a few. [This list](./projects_using_cobra.md) contains a more extensive list of projects using Cobra.
|
||||||
|
|
||||||
[![](https://img.shields.io/github/workflow/status/spf13/cobra/Test?longCache=tru&label=Test&logo=github%20actions&logoColor=fff)](https://github.com/spf13/cobra/actions?query=workflow%3ATest)
|
[![](https://img.shields.io/github/actions/workflow/status/spf13/cobra/test.yml?branch=main&longCache=true&label=Test&logo=github%20actions&logoColor=fff)](https://github.com/spf13/cobra/actions?query=workflow%3ATest)
|
||||||
[![Go Reference](https://pkg.go.dev/badge/github.com/spf13/cobra.svg)](https://pkg.go.dev/github.com/spf13/cobra)
|
[![Go Reference](https://pkg.go.dev/badge/github.com/spf13/cobra.svg)](https://pkg.go.dev/github.com/spf13/cobra)
|
||||||
[![Go Report Card](https://goreportcard.com/badge/github.com/spf13/cobra)](https://goreportcard.com/report/github.com/spf13/cobra)
|
[![Go Report Card](https://goreportcard.com/badge/github.com/spf13/cobra)](https://goreportcard.com/report/github.com/spf13/cobra)
|
||||||
[![Slack](https://img.shields.io/badge/Slack-cobra-brightgreen)](https://gophers.slack.com/archives/CD3LP1199)
|
[![Slack](https://img.shields.io/badge/Slack-cobra-brightgreen)](https://gophers.slack.com/archives/CD3LP1199)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2013-2022 The Cobra Authors
|
// Copyright 2013-2023 The Cobra Authors
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2013-2022 The Cobra Authors
|
// Copyright 2013-2023 The Cobra Authors
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
|
@ -21,7 +21,7 @@ import (
|
||||||
|
|
||||||
type PositionalArgs func(cmd *Command, args []string) error
|
type PositionalArgs func(cmd *Command, args []string) error
|
||||||
|
|
||||||
// Legacy arg validation has the following behaviour:
|
// legacyArgs validation has the following behaviour:
|
||||||
// - root commands with no subcommands can take arbitrary arguments
|
// - root commands with no subcommands can take arbitrary arguments
|
||||||
// - root commands with subcommands will do subcommand validity checking
|
// - root commands with subcommands will do subcommand validity checking
|
||||||
// - subcommands will always accept arbitrary arguments
|
// - subcommands will always accept arbitrary arguments
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2013-2022 The Cobra Authors
|
// Copyright 2013-2023 The Cobra Authors
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
|
@ -532,7 +532,7 @@ func writeLocalNonPersistentFlag(buf io.StringWriter, flag *pflag.Flag) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup annotations for go completions for registered flags
|
// prepareCustomAnnotationsForFlags setup annotations for go completions for registered flags
|
||||||
func prepareCustomAnnotationsForFlags(cmd *Command) {
|
func prepareCustomAnnotationsForFlags(cmd *Command) {
|
||||||
flagCompletionMutex.RLock()
|
flagCompletionMutex.RLock()
|
||||||
defer flagCompletionMutex.RUnlock()
|
defer flagCompletionMutex.RUnlock()
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2013-2022 The Cobra Authors
|
// Copyright 2013-2023 The Cobra Authors
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
|
@ -38,7 +38,7 @@ func genBashComp(buf io.StringWriter, name string, includeDesc bool) {
|
||||||
|
|
||||||
__%[1]s_debug()
|
__%[1]s_debug()
|
||||||
{
|
{
|
||||||
if [[ -n ${BASH_COMP_DEBUG_FILE:-} ]]; then
|
if [[ -n ${BASH_COMP_DEBUG_FILE-} ]]; then
|
||||||
echo "$*" >> "${BASH_COMP_DEBUG_FILE}"
|
echo "$*" >> "${BASH_COMP_DEBUG_FILE}"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
@ -65,7 +65,7 @@ __%[1]s_get_completion_results() {
|
||||||
lastChar=${lastParam:$((${#lastParam}-1)):1}
|
lastChar=${lastParam:$((${#lastParam}-1)):1}
|
||||||
__%[1]s_debug "lastParam ${lastParam}, lastChar ${lastChar}"
|
__%[1]s_debug "lastParam ${lastParam}, lastChar ${lastChar}"
|
||||||
|
|
||||||
if [ -z "${cur}" ] && [ "${lastChar}" != "=" ]; then
|
if [[ -z ${cur} && ${lastChar} != = ]]; then
|
||||||
# If the last parameter is complete (there is a space following it)
|
# If the last parameter is complete (there is a space following it)
|
||||||
# We add an extra empty parameter so we can indicate this to the go method.
|
# We add an extra empty parameter so we can indicate this to the go method.
|
||||||
__%[1]s_debug "Adding extra empty parameter"
|
__%[1]s_debug "Adding extra empty parameter"
|
||||||
|
@ -75,7 +75,7 @@ __%[1]s_get_completion_results() {
|
||||||
# When completing a flag with an = (e.g., %[1]s -n=<TAB>)
|
# When completing a flag with an = (e.g., %[1]s -n=<TAB>)
|
||||||
# bash focuses on the part after the =, so we need to remove
|
# bash focuses on the part after the =, so we need to remove
|
||||||
# the flag part from $cur
|
# the flag part from $cur
|
||||||
if [[ "${cur}" == -*=* ]]; then
|
if [[ ${cur} == -*=* ]]; then
|
||||||
cur="${cur#*=}"
|
cur="${cur#*=}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -87,7 +87,7 @@ __%[1]s_get_completion_results() {
|
||||||
directive=${out##*:}
|
directive=${out##*:}
|
||||||
# Remove the directive
|
# Remove the directive
|
||||||
out=${out%%:*}
|
out=${out%%:*}
|
||||||
if [ "${directive}" = "${out}" ]; then
|
if [[ ${directive} == "${out}" ]]; then
|
||||||
# There is not directive specified
|
# There is not directive specified
|
||||||
directive=0
|
directive=0
|
||||||
fi
|
fi
|
||||||
|
@ -101,22 +101,36 @@ __%[1]s_process_completion_results() {
|
||||||
local shellCompDirectiveNoFileComp=%[5]d
|
local shellCompDirectiveNoFileComp=%[5]d
|
||||||
local shellCompDirectiveFilterFileExt=%[6]d
|
local shellCompDirectiveFilterFileExt=%[6]d
|
||||||
local shellCompDirectiveFilterDirs=%[7]d
|
local shellCompDirectiveFilterDirs=%[7]d
|
||||||
|
local shellCompDirectiveKeepOrder=%[8]d
|
||||||
|
|
||||||
if [ $((directive & shellCompDirectiveError)) -ne 0 ]; then
|
if (((directive & shellCompDirectiveError) != 0)); then
|
||||||
# Error code. No completion.
|
# Error code. No completion.
|
||||||
__%[1]s_debug "Received error from custom completion go code"
|
__%[1]s_debug "Received error from custom completion go code"
|
||||||
return
|
return
|
||||||
else
|
else
|
||||||
if [ $((directive & shellCompDirectiveNoSpace)) -ne 0 ]; then
|
if (((directive & shellCompDirectiveNoSpace) != 0)); then
|
||||||
if [[ $(type -t compopt) = "builtin" ]]; then
|
if [[ $(type -t compopt) == builtin ]]; then
|
||||||
__%[1]s_debug "Activating no space"
|
__%[1]s_debug "Activating no space"
|
||||||
compopt -o nospace
|
compopt -o nospace
|
||||||
else
|
else
|
||||||
__%[1]s_debug "No space directive not supported in this version of bash"
|
__%[1]s_debug "No space directive not supported in this version of bash"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
if [ $((directive & shellCompDirectiveNoFileComp)) -ne 0 ]; then
|
if (((directive & shellCompDirectiveKeepOrder) != 0)); then
|
||||||
if [[ $(type -t compopt) = "builtin" ]]; then
|
if [[ $(type -t compopt) == builtin ]]; then
|
||||||
|
# no sort isn't supported for bash less than < 4.4
|
||||||
|
if [[ ${BASH_VERSINFO[0]} -lt 4 || ( ${BASH_VERSINFO[0]} -eq 4 && ${BASH_VERSINFO[1]} -lt 4 ) ]]; then
|
||||||
|
__%[1]s_debug "No sort directive not supported in this version of bash"
|
||||||
|
else
|
||||||
|
__%[1]s_debug "Activating keep order"
|
||||||
|
compopt -o nosort
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
__%[1]s_debug "No sort directive not supported in this version of bash"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if (((directive & shellCompDirectiveNoFileComp) != 0)); then
|
||||||
|
if [[ $(type -t compopt) == builtin ]]; then
|
||||||
__%[1]s_debug "Activating no file completion"
|
__%[1]s_debug "Activating no file completion"
|
||||||
compopt +o default
|
compopt +o default
|
||||||
else
|
else
|
||||||
|
@ -130,7 +144,7 @@ __%[1]s_process_completion_results() {
|
||||||
local activeHelp=()
|
local activeHelp=()
|
||||||
__%[1]s_extract_activeHelp
|
__%[1]s_extract_activeHelp
|
||||||
|
|
||||||
if [ $((directive & shellCompDirectiveFilterFileExt)) -ne 0 ]; then
|
if (((directive & shellCompDirectiveFilterFileExt) != 0)); then
|
||||||
# File extension filtering
|
# File extension filtering
|
||||||
local fullFilter filter filteringCmd
|
local fullFilter filter filteringCmd
|
||||||
|
|
||||||
|
@ -143,13 +157,12 @@ __%[1]s_process_completion_results() {
|
||||||
filteringCmd="_filedir $fullFilter"
|
filteringCmd="_filedir $fullFilter"
|
||||||
__%[1]s_debug "File filtering command: $filteringCmd"
|
__%[1]s_debug "File filtering command: $filteringCmd"
|
||||||
$filteringCmd
|
$filteringCmd
|
||||||
elif [ $((directive & shellCompDirectiveFilterDirs)) -ne 0 ]; then
|
elif (((directive & shellCompDirectiveFilterDirs) != 0)); then
|
||||||
# File completion for directories only
|
# File completion for directories only
|
||||||
|
|
||||||
# Use printf to strip any trailing newline
|
|
||||||
local subdir
|
local subdir
|
||||||
subdir=$(printf "%%s" "${completions[0]}")
|
subdir=${completions[0]}
|
||||||
if [ -n "$subdir" ]; then
|
if [[ -n $subdir ]]; then
|
||||||
__%[1]s_debug "Listing directories in $subdir"
|
__%[1]s_debug "Listing directories in $subdir"
|
||||||
pushd "$subdir" >/dev/null 2>&1 && _filedir -d && popd >/dev/null 2>&1 || return
|
pushd "$subdir" >/dev/null 2>&1 && _filedir -d && popd >/dev/null 2>&1 || return
|
||||||
else
|
else
|
||||||
|
@ -164,7 +177,7 @@ __%[1]s_process_completion_results() {
|
||||||
__%[1]s_handle_special_char "$cur" =
|
__%[1]s_handle_special_char "$cur" =
|
||||||
|
|
||||||
# Print the activeHelp statements before we finish
|
# Print the activeHelp statements before we finish
|
||||||
if [ ${#activeHelp[*]} -ne 0 ]; then
|
if ((${#activeHelp[*]} != 0)); then
|
||||||
printf "\n";
|
printf "\n";
|
||||||
printf "%%s\n" "${activeHelp[@]}"
|
printf "%%s\n" "${activeHelp[@]}"
|
||||||
printf "\n"
|
printf "\n"
|
||||||
|
@ -184,21 +197,21 @@ __%[1]s_process_completion_results() {
|
||||||
# Separate activeHelp lines from real completions.
|
# Separate activeHelp lines from real completions.
|
||||||
# Fills the $activeHelp and $completions arrays.
|
# Fills the $activeHelp and $completions arrays.
|
||||||
__%[1]s_extract_activeHelp() {
|
__%[1]s_extract_activeHelp() {
|
||||||
local activeHelpMarker="%[8]s"
|
local activeHelpMarker="%[9]s"
|
||||||
local endIndex=${#activeHelpMarker}
|
local endIndex=${#activeHelpMarker}
|
||||||
|
|
||||||
while IFS='' read -r comp; do
|
while IFS='' read -r comp; do
|
||||||
if [ "${comp:0:endIndex}" = "$activeHelpMarker" ]; then
|
if [[ ${comp:0:endIndex} == $activeHelpMarker ]]; then
|
||||||
comp=${comp:endIndex}
|
comp=${comp:endIndex}
|
||||||
__%[1]s_debug "ActiveHelp found: $comp"
|
__%[1]s_debug "ActiveHelp found: $comp"
|
||||||
if [ -n "$comp" ]; then
|
if [[ -n $comp ]]; then
|
||||||
activeHelp+=("$comp")
|
activeHelp+=("$comp")
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
# Not an activeHelp line but a normal completion
|
# Not an activeHelp line but a normal completion
|
||||||
completions+=("$comp")
|
completions+=("$comp")
|
||||||
fi
|
fi
|
||||||
done < <(printf "%%s\n" "${out}")
|
done <<<"${out}"
|
||||||
}
|
}
|
||||||
|
|
||||||
__%[1]s_handle_completion_types() {
|
__%[1]s_handle_completion_types() {
|
||||||
|
@ -254,7 +267,7 @@ __%[1]s_handle_standard_completion_case() {
|
||||||
done < <(printf "%%s\n" "${completions[@]}")
|
done < <(printf "%%s\n" "${completions[@]}")
|
||||||
|
|
||||||
# If there is a single completion left, remove the description text
|
# If there is a single completion left, remove the description text
|
||||||
if [ ${#COMPREPLY[*]} -eq 1 ]; then
|
if ((${#COMPREPLY[*]} == 1)); then
|
||||||
__%[1]s_debug "COMPREPLY[0]: ${COMPREPLY[0]}"
|
__%[1]s_debug "COMPREPLY[0]: ${COMPREPLY[0]}"
|
||||||
comp="${COMPREPLY[0]%%%%$tab*}"
|
comp="${COMPREPLY[0]%%%%$tab*}"
|
||||||
__%[1]s_debug "Removed description from single completion, which is now: ${comp}"
|
__%[1]s_debug "Removed description from single completion, which is now: ${comp}"
|
||||||
|
@ -271,8 +284,8 @@ __%[1]s_handle_special_char()
|
||||||
if [[ "$comp" == *${char}* && "$COMP_WORDBREAKS" == *${char}* ]]; then
|
if [[ "$comp" == *${char}* && "$COMP_WORDBREAKS" == *${char}* ]]; then
|
||||||
local word=${comp%%"${comp##*${char}}"}
|
local word=${comp%%"${comp##*${char}}"}
|
||||||
local idx=${#COMPREPLY[*]}
|
local idx=${#COMPREPLY[*]}
|
||||||
while [[ $((--idx)) -ge 0 ]]; do
|
while ((--idx >= 0)); do
|
||||||
COMPREPLY[$idx]=${COMPREPLY[$idx]#"$word"}
|
COMPREPLY[idx]=${COMPREPLY[idx]#"$word"}
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
@ -298,7 +311,7 @@ __%[1]s_format_comp_descriptions()
|
||||||
|
|
||||||
# Make sure we can fit a description of at least 8 characters
|
# Make sure we can fit a description of at least 8 characters
|
||||||
# if we are to align the descriptions.
|
# if we are to align the descriptions.
|
||||||
if [[ $maxdesclength -gt 8 ]]; then
|
if ((maxdesclength > 8)); then
|
||||||
# Add the proper number of spaces to align the descriptions
|
# Add the proper number of spaces to align the descriptions
|
||||||
for ((i = ${#comp} ; i < longest ; i++)); do
|
for ((i = ${#comp} ; i < longest ; i++)); do
|
||||||
comp+=" "
|
comp+=" "
|
||||||
|
@ -310,8 +323,8 @@ __%[1]s_format_comp_descriptions()
|
||||||
|
|
||||||
# If there is enough space for any description text,
|
# If there is enough space for any description text,
|
||||||
# truncate the descriptions that are too long for the shell width
|
# truncate the descriptions that are too long for the shell width
|
||||||
if [ $maxdesclength -gt 0 ]; then
|
if ((maxdesclength > 0)); then
|
||||||
if [ ${#desc} -gt $maxdesclength ]; then
|
if ((${#desc} > maxdesclength)); then
|
||||||
desc=${desc:0:$(( maxdesclength - 1 ))}
|
desc=${desc:0:$(( maxdesclength - 1 ))}
|
||||||
desc+="…"
|
desc+="…"
|
||||||
fi
|
fi
|
||||||
|
@ -332,9 +345,9 @@ __start_%[1]s()
|
||||||
# Call _init_completion from the bash-completion package
|
# Call _init_completion from the bash-completion package
|
||||||
# to prepare the arguments properly
|
# to prepare the arguments properly
|
||||||
if declare -F _init_completion >/dev/null 2>&1; then
|
if declare -F _init_completion >/dev/null 2>&1; then
|
||||||
_init_completion -n "=:" || return
|
_init_completion -n =: || return
|
||||||
else
|
else
|
||||||
__%[1]s_init_completion -n "=:" || return
|
__%[1]s_init_completion -n =: || return
|
||||||
fi
|
fi
|
||||||
|
|
||||||
__%[1]s_debug
|
__%[1]s_debug
|
||||||
|
@ -361,7 +374,7 @@ fi
|
||||||
# ex: ts=4 sw=4 et filetype=sh
|
# ex: ts=4 sw=4 et filetype=sh
|
||||||
`, name, compCmd,
|
`, name, compCmd,
|
||||||
ShellCompDirectiveError, ShellCompDirectiveNoSpace, ShellCompDirectiveNoFileComp,
|
ShellCompDirectiveError, ShellCompDirectiveNoSpace, ShellCompDirectiveNoFileComp,
|
||||||
ShellCompDirectiveFilterFileExt, ShellCompDirectiveFilterDirs,
|
ShellCompDirectiveFilterFileExt, ShellCompDirectiveFilterDirs, ShellCompDirectiveKeepOrder,
|
||||||
activeHelpMarker))
|
activeHelpMarker))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2013-2022 The Cobra Authors
|
// Copyright 2013-2023 The Cobra Authors
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
|
@ -167,8 +167,8 @@ func appendIfNotPresent(s, stringToAppend string) string {
|
||||||
|
|
||||||
// rpad adds padding to the right of a string.
|
// rpad adds padding to the right of a string.
|
||||||
func rpad(s string, padding int) string {
|
func rpad(s string, padding int) string {
|
||||||
template := fmt.Sprintf("%%-%ds", padding)
|
formattedString := fmt.Sprintf("%%-%ds", padding)
|
||||||
return fmt.Sprintf(template, s)
|
return fmt.Sprintf(formattedString, s)
|
||||||
}
|
}
|
||||||
|
|
||||||
// tmpl executes the given template text on data, writing the result to w.
|
// tmpl executes the given template text on data, writing the result to w.
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2013-2022 The Cobra Authors
|
// Copyright 2013-2023 The Cobra Authors
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
|
@ -35,7 +35,7 @@ const FlagSetByCobraAnnotation = "cobra_annotation_flag_set_by_cobra"
|
||||||
// FParseErrWhitelist configures Flag parse errors to be ignored
|
// FParseErrWhitelist configures Flag parse errors to be ignored
|
||||||
type FParseErrWhitelist flag.ParseErrorsWhitelist
|
type FParseErrWhitelist flag.ParseErrorsWhitelist
|
||||||
|
|
||||||
// Structure to manage groups for commands
|
// Group Structure to manage groups for commands
|
||||||
type Group struct {
|
type Group struct {
|
||||||
ID string
|
ID string
|
||||||
Title string
|
Title string
|
||||||
|
@ -47,7 +47,7 @@ type Group struct {
|
||||||
// definition to ensure usability.
|
// definition to ensure usability.
|
||||||
type Command struct {
|
type Command struct {
|
||||||
// Use is the one-line usage message.
|
// Use is the one-line usage message.
|
||||||
// Recommended syntax is as follow:
|
// Recommended syntax is as follows:
|
||||||
// [ ] identifies an optional argument. Arguments that are not enclosed in brackets are required.
|
// [ ] identifies an optional argument. Arguments that are not enclosed in brackets are required.
|
||||||
// ... indicates that you can specify multiple values for the previous argument.
|
// ... indicates that you can specify multiple values for the previous argument.
|
||||||
// | indicates mutually exclusive information. You can use the argument to the left of the separator or the
|
// | indicates mutually exclusive information. You can use the argument to the left of the separator or the
|
||||||
|
@ -321,7 +321,7 @@ func (c *Command) SetHelpCommand(cmd *Command) {
|
||||||
c.helpCommand = cmd
|
c.helpCommand = cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetHelpCommandGroup sets the group id of the help command.
|
// SetHelpCommandGroupID sets the group id of the help command.
|
||||||
func (c *Command) SetHelpCommandGroupID(groupID string) {
|
func (c *Command) SetHelpCommandGroupID(groupID string) {
|
||||||
if c.helpCommand != nil {
|
if c.helpCommand != nil {
|
||||||
c.helpCommand.GroupID = groupID
|
c.helpCommand.GroupID = groupID
|
||||||
|
@ -330,7 +330,7 @@ func (c *Command) SetHelpCommandGroupID(groupID string) {
|
||||||
c.helpCommandGroupID = groupID
|
c.helpCommandGroupID = groupID
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetCompletionCommandGroup sets the group id of the completion command.
|
// SetCompletionCommandGroupID sets the group id of the completion command.
|
||||||
func (c *Command) SetCompletionCommandGroupID(groupID string) {
|
func (c *Command) SetCompletionCommandGroupID(groupID string) {
|
||||||
// completionCommandGroupID is used if no completion command is defined by the user
|
// completionCommandGroupID is used if no completion command is defined by the user
|
||||||
c.Root().completionCommandGroupID = groupID
|
c.Root().completionCommandGroupID = groupID
|
||||||
|
@ -655,20 +655,44 @@ Loop:
|
||||||
|
|
||||||
// argsMinusFirstX removes only the first x from args. Otherwise, commands that look like
|
// argsMinusFirstX removes only the first x from args. Otherwise, commands that look like
|
||||||
// openshift admin policy add-role-to-user admin my-user, lose the admin argument (arg[4]).
|
// openshift admin policy add-role-to-user admin my-user, lose the admin argument (arg[4]).
|
||||||
func argsMinusFirstX(args []string, x string) []string {
|
// Special care needs to be taken not to remove a flag value.
|
||||||
for i, y := range args {
|
func (c *Command) argsMinusFirstX(args []string, x string) []string {
|
||||||
if x == y {
|
if len(args) == 0 {
|
||||||
ret := []string{}
|
return args
|
||||||
ret = append(ret, args[:i]...)
|
}
|
||||||
ret = append(ret, args[i+1:]...)
|
c.mergePersistentFlags()
|
||||||
return ret
|
flags := c.Flags()
|
||||||
|
|
||||||
|
Loop:
|
||||||
|
for pos := 0; pos < len(args); pos++ {
|
||||||
|
s := args[pos]
|
||||||
|
switch {
|
||||||
|
case s == "--":
|
||||||
|
// -- means we have reached the end of the parseable args. Break out of the loop now.
|
||||||
|
break Loop
|
||||||
|
case strings.HasPrefix(s, "--") && !strings.Contains(s, "=") && !hasNoOptDefVal(s[2:], flags):
|
||||||
|
fallthrough
|
||||||
|
case strings.HasPrefix(s, "-") && !strings.Contains(s, "=") && len(s) == 2 && !shortHasNoOptDefVal(s[1:], flags):
|
||||||
|
// This is a flag without a default value, and an equal sign is not used. Increment pos in order to skip
|
||||||
|
// over the next arg, because that is the value of this flag.
|
||||||
|
pos++
|
||||||
|
continue
|
||||||
|
case !strings.HasPrefix(s, "-"):
|
||||||
|
// This is not a flag or a flag value. Check to see if it matches what we're looking for, and if so,
|
||||||
|
// return the args, excluding the one at this position.
|
||||||
|
if s == x {
|
||||||
|
ret := []string{}
|
||||||
|
ret = append(ret, args[:pos]...)
|
||||||
|
ret = append(ret, args[pos+1:]...)
|
||||||
|
return ret
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return args
|
return args
|
||||||
}
|
}
|
||||||
|
|
||||||
func isFlagArg(arg string) bool {
|
func isFlagArg(arg string) bool {
|
||||||
return ((len(arg) >= 3 && arg[1] == '-') ||
|
return ((len(arg) >= 3 && arg[0:2] == "--") ||
|
||||||
(len(arg) >= 2 && arg[0] == '-' && arg[1] != '-'))
|
(len(arg) >= 2 && arg[0] == '-' && arg[1] != '-'))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -686,7 +710,7 @@ func (c *Command) Find(args []string) (*Command, []string, error) {
|
||||||
|
|
||||||
cmd := c.findNext(nextSubCmd)
|
cmd := c.findNext(nextSubCmd)
|
||||||
if cmd != nil {
|
if cmd != nil {
|
||||||
return innerfind(cmd, argsMinusFirstX(innerArgs, nextSubCmd))
|
return innerfind(cmd, c.argsMinusFirstX(innerArgs, nextSubCmd))
|
||||||
}
|
}
|
||||||
return c, innerArgs
|
return c, innerArgs
|
||||||
}
|
}
|
||||||
|
@ -1272,7 +1296,7 @@ func (c *Command) AllChildCommandsHaveGroup() bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// ContainGroups return if groupID exists in the list of command groups.
|
// ContainsGroup return if groupID exists in the list of command groups.
|
||||||
func (c *Command) ContainsGroup(groupID string) bool {
|
func (c *Command) ContainsGroup(groupID string) bool {
|
||||||
for _, x := range c.commandgroups {
|
for _, x := range c.commandgroups {
|
||||||
if x.ID == groupID {
|
if x.ID == groupID {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2013-2022 The Cobra Authors
|
// Copyright 2013-2023 The Cobra Authors
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2013-2022 The Cobra Authors
|
// Copyright 2013-2023 The Cobra Authors
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2013-2022 The Cobra Authors
|
// Copyright 2013-2023 The Cobra Authors
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
|
@ -77,6 +77,10 @@ const (
|
||||||
// obtain the same behavior but only for flags.
|
// obtain the same behavior but only for flags.
|
||||||
ShellCompDirectiveFilterDirs
|
ShellCompDirectiveFilterDirs
|
||||||
|
|
||||||
|
// ShellCompDirectiveKeepOrder indicates that the shell should preserve the order
|
||||||
|
// in which the completions are provided
|
||||||
|
ShellCompDirectiveKeepOrder
|
||||||
|
|
||||||
// ===========================================================================
|
// ===========================================================================
|
||||||
|
|
||||||
// All directives using iota should be above this one.
|
// All directives using iota should be above this one.
|
||||||
|
@ -159,6 +163,9 @@ func (d ShellCompDirective) string() string {
|
||||||
if d&ShellCompDirectiveFilterDirs != 0 {
|
if d&ShellCompDirectiveFilterDirs != 0 {
|
||||||
directives = append(directives, "ShellCompDirectiveFilterDirs")
|
directives = append(directives, "ShellCompDirectiveFilterDirs")
|
||||||
}
|
}
|
||||||
|
if d&ShellCompDirectiveKeepOrder != 0 {
|
||||||
|
directives = append(directives, "ShellCompDirectiveKeepOrder")
|
||||||
|
}
|
||||||
if len(directives) == 0 {
|
if len(directives) == 0 {
|
||||||
directives = append(directives, "ShellCompDirectiveDefault")
|
directives = append(directives, "ShellCompDirectiveDefault")
|
||||||
}
|
}
|
||||||
|
@ -169,7 +176,7 @@ func (d ShellCompDirective) string() string {
|
||||||
return strings.Join(directives, ", ")
|
return strings.Join(directives, ", ")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adds a special hidden command that can be used to request custom completions.
|
// initCompleteCmd adds a special hidden command that can be used to request custom completions.
|
||||||
func (c *Command) initCompleteCmd(args []string) {
|
func (c *Command) initCompleteCmd(args []string) {
|
||||||
completeCmd := &Command{
|
completeCmd := &Command{
|
||||||
Use: fmt.Sprintf("%s [command-line]", ShellCompRequestCmd),
|
Use: fmt.Sprintf("%s [command-line]", ShellCompRequestCmd),
|
||||||
|
@ -727,7 +734,7 @@ to enable it. You can execute the following once:
|
||||||
|
|
||||||
To load completions in your current shell session:
|
To load completions in your current shell session:
|
||||||
|
|
||||||
source <(%[1]s completion zsh); compdef _%[1]s %[1]s
|
source <(%[1]s completion zsh)
|
||||||
|
|
||||||
To load completions for every new session, execute once:
|
To load completions for every new session, execute once:
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2013-2022 The Cobra Authors
|
// Copyright 2013-2023 The Cobra Authors
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
|
@ -53,7 +53,7 @@ function __%[1]s_perform_completion
|
||||||
__%[1]s_debug "last arg: $lastArg"
|
__%[1]s_debug "last arg: $lastArg"
|
||||||
|
|
||||||
# Disable ActiveHelp which is not supported for fish shell
|
# Disable ActiveHelp which is not supported for fish shell
|
||||||
set -l requestComp "%[9]s=0 $args[1] %[3]s $args[2..-1] $lastArg"
|
set -l requestComp "%[10]s=0 $args[1] %[3]s $args[2..-1] $lastArg"
|
||||||
|
|
||||||
__%[1]s_debug "Calling $requestComp"
|
__%[1]s_debug "Calling $requestComp"
|
||||||
set -l results (eval $requestComp 2> /dev/null)
|
set -l results (eval $requestComp 2> /dev/null)
|
||||||
|
@ -89,6 +89,60 @@ function __%[1]s_perform_completion
|
||||||
printf "%%s\n" "$directiveLine"
|
printf "%%s\n" "$directiveLine"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# this function limits calls to __%[1]s_perform_completion, by caching the result behind $__%[1]s_perform_completion_once_result
|
||||||
|
function __%[1]s_perform_completion_once
|
||||||
|
__%[1]s_debug "Starting __%[1]s_perform_completion_once"
|
||||||
|
|
||||||
|
if test -n "$__%[1]s_perform_completion_once_result"
|
||||||
|
__%[1]s_debug "Seems like a valid result already exists, skipping __%[1]s_perform_completion"
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
|
||||||
|
set --global __%[1]s_perform_completion_once_result (__%[1]s_perform_completion)
|
||||||
|
if test -z "$__%[1]s_perform_completion_once_result"
|
||||||
|
__%[1]s_debug "No completions, probably due to a failure"
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
|
||||||
|
__%[1]s_debug "Performed completions and set __%[1]s_perform_completion_once_result"
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
|
||||||
|
# this function is used to clear the $__%[1]s_perform_completion_once_result variable after completions are run
|
||||||
|
function __%[1]s_clear_perform_completion_once_result
|
||||||
|
__%[1]s_debug ""
|
||||||
|
__%[1]s_debug "========= clearing previously set __%[1]s_perform_completion_once_result variable =========="
|
||||||
|
set --erase __%[1]s_perform_completion_once_result
|
||||||
|
__%[1]s_debug "Succesfully erased the variable __%[1]s_perform_completion_once_result"
|
||||||
|
end
|
||||||
|
|
||||||
|
function __%[1]s_requires_order_preservation
|
||||||
|
__%[1]s_debug ""
|
||||||
|
__%[1]s_debug "========= checking if order preservation is required =========="
|
||||||
|
|
||||||
|
__%[1]s_perform_completion_once
|
||||||
|
if test -z "$__%[1]s_perform_completion_once_result"
|
||||||
|
__%[1]s_debug "Error determining if order preservation is required"
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
|
||||||
|
set -l directive (string sub --start 2 $__%[1]s_perform_completion_once_result[-1])
|
||||||
|
__%[1]s_debug "Directive is: $directive"
|
||||||
|
|
||||||
|
set -l shellCompDirectiveKeepOrder %[9]d
|
||||||
|
set -l keeporder (math (math --scale 0 $directive / $shellCompDirectiveKeepOrder) %% 2)
|
||||||
|
__%[1]s_debug "Keeporder is: $keeporder"
|
||||||
|
|
||||||
|
if test $keeporder -ne 0
|
||||||
|
__%[1]s_debug "This does require order preservation"
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
|
||||||
|
__%[1]s_debug "This doesn't require order preservation"
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
# This function does two things:
|
# This function does two things:
|
||||||
# - Obtain the completions and store them in the global __%[1]s_comp_results
|
# - Obtain the completions and store them in the global __%[1]s_comp_results
|
||||||
# - Return false if file completion should be performed
|
# - Return false if file completion should be performed
|
||||||
|
@ -99,17 +153,17 @@ function __%[1]s_prepare_completions
|
||||||
# Start fresh
|
# Start fresh
|
||||||
set --erase __%[1]s_comp_results
|
set --erase __%[1]s_comp_results
|
||||||
|
|
||||||
set -l results (__%[1]s_perform_completion)
|
__%[1]s_perform_completion_once
|
||||||
__%[1]s_debug "Completion results: $results"
|
__%[1]s_debug "Completion results: $__%[1]s_perform_completion_once_result"
|
||||||
|
|
||||||
if test -z "$results"
|
if test -z "$__%[1]s_perform_completion_once_result"
|
||||||
__%[1]s_debug "No completion, probably due to a failure"
|
__%[1]s_debug "No completion, probably due to a failure"
|
||||||
# Might as well do file completion, in case it helps
|
# Might as well do file completion, in case it helps
|
||||||
return 1
|
return 1
|
||||||
end
|
end
|
||||||
|
|
||||||
set -l directive (string sub --start 2 $results[-1])
|
set -l directive (string sub --start 2 $__%[1]s_perform_completion_once_result[-1])
|
||||||
set --global __%[1]s_comp_results $results[1..-2]
|
set --global __%[1]s_comp_results $__%[1]s_perform_completion_once_result[1..-2]
|
||||||
|
|
||||||
__%[1]s_debug "Completions are: $__%[1]s_comp_results"
|
__%[1]s_debug "Completions are: $__%[1]s_comp_results"
|
||||||
__%[1]s_debug "Directive is: $directive"
|
__%[1]s_debug "Directive is: $directive"
|
||||||
|
@ -205,13 +259,17 @@ end
|
||||||
# Remove any pre-existing completions for the program since we will be handling all of them.
|
# Remove any pre-existing completions for the program since we will be handling all of them.
|
||||||
complete -c %[2]s -e
|
complete -c %[2]s -e
|
||||||
|
|
||||||
|
# this will get called after the two calls below and clear the $__%[1]s_perform_completion_once_result global
|
||||||
|
complete -c %[2]s -n '__%[1]s_clear_perform_completion_once_result'
|
||||||
# The call to __%[1]s_prepare_completions will setup __%[1]s_comp_results
|
# The call to __%[1]s_prepare_completions will setup __%[1]s_comp_results
|
||||||
# which provides the program's completion choices.
|
# which provides the program's completion choices.
|
||||||
complete -c %[2]s -n '__%[1]s_prepare_completions' -f -a '$__%[1]s_comp_results'
|
# If this doesn't require order preservation, we don't use the -k flag
|
||||||
|
complete -c %[2]s -n 'not __%[1]s_requires_order_preservation && __%[1]s_prepare_completions' -f -a '$__%[1]s_comp_results'
|
||||||
|
# otherwise we use the -k flag
|
||||||
|
complete -k -c %[2]s -n '__%[1]s_requires_order_preservation && __%[1]s_prepare_completions' -f -a '$__%[1]s_comp_results'
|
||||||
`, nameForVar, name, compCmd,
|
`, nameForVar, name, compCmd,
|
||||||
ShellCompDirectiveError, ShellCompDirectiveNoSpace, ShellCompDirectiveNoFileComp,
|
ShellCompDirectiveError, ShellCompDirectiveNoSpace, ShellCompDirectiveNoFileComp,
|
||||||
ShellCompDirectiveFilterFileExt, ShellCompDirectiveFilterDirs, activeHelpEnvVar(name)))
|
ShellCompDirectiveFilterFileExt, ShellCompDirectiveFilterDirs, ShellCompDirectiveKeepOrder, activeHelpEnvVar(name)))
|
||||||
}
|
}
|
||||||
|
|
||||||
// GenFishCompletion generates fish completion file and writes to the passed writer.
|
// GenFishCompletion generates fish completion file and writes to the passed writer.
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2013-2022 The Cobra Authors
|
// Copyright 2013-2023 The Cobra Authors
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2013-2022 The Cobra Authors
|
// Copyright 2013-2023 The Cobra Authors
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
|
@ -77,6 +77,7 @@ filter __%[1]s_escapeStringWithSpecialChars {
|
||||||
$ShellCompDirectiveNoFileComp=%[6]d
|
$ShellCompDirectiveNoFileComp=%[6]d
|
||||||
$ShellCompDirectiveFilterFileExt=%[7]d
|
$ShellCompDirectiveFilterFileExt=%[7]d
|
||||||
$ShellCompDirectiveFilterDirs=%[8]d
|
$ShellCompDirectiveFilterDirs=%[8]d
|
||||||
|
$ShellCompDirectiveKeepOrder=%[9]d
|
||||||
|
|
||||||
# Prepare the command to request completions for the program.
|
# Prepare the command to request completions for the program.
|
||||||
# Split the command at the first space to separate the program and arguments.
|
# Split the command at the first space to separate the program and arguments.
|
||||||
|
@ -106,13 +107,22 @@ filter __%[1]s_escapeStringWithSpecialChars {
|
||||||
# If the last parameter is complete (there is a space following it)
|
# If the last parameter is complete (there is a space following it)
|
||||||
# We add an extra empty parameter so we can indicate this to the go method.
|
# We add an extra empty parameter so we can indicate this to the go method.
|
||||||
__%[1]s_debug "Adding extra empty parameter"
|
__%[1]s_debug "Adding extra empty parameter"
|
||||||
`+" # We need to use `\"`\" to pass an empty argument a \"\" or '' does not work!!!"+`
|
# PowerShell 7.2+ changed the way how the arguments are passed to executables,
|
||||||
`+" $RequestComp=\"$RequestComp\" + ' `\"`\"'"+`
|
# so for pre-7.2 or when Legacy argument passing is enabled we need to use
|
||||||
|
`+" # `\"`\" to pass an empty argument, a \"\" or '' does not work!!!"+`
|
||||||
|
if ($PSVersionTable.PsVersion -lt [version]'7.2.0' -or
|
||||||
|
($PSVersionTable.PsVersion -lt [version]'7.3.0' -and -not [ExperimentalFeature]::IsEnabled("PSNativeCommandArgumentPassing")) -or
|
||||||
|
(($PSVersionTable.PsVersion -ge [version]'7.3.0' -or [ExperimentalFeature]::IsEnabled("PSNativeCommandArgumentPassing")) -and
|
||||||
|
$PSNativeCommandArgumentPassing -eq 'Legacy')) {
|
||||||
|
`+" $RequestComp=\"$RequestComp\" + ' `\"`\"'"+`
|
||||||
|
} else {
|
||||||
|
$RequestComp="$RequestComp" + ' ""'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
__%[1]s_debug "Calling $RequestComp"
|
__%[1]s_debug "Calling $RequestComp"
|
||||||
# First disable ActiveHelp which is not supported for Powershell
|
# First disable ActiveHelp which is not supported for Powershell
|
||||||
$env:%[9]s=0
|
$env:%[10]s=0
|
||||||
|
|
||||||
#call the command store the output in $out and redirect stderr and stdout to null
|
#call the command store the output in $out and redirect stderr and stdout to null
|
||||||
# $Out is an array contains each line per element
|
# $Out is an array contains each line per element
|
||||||
|
@ -137,7 +147,7 @@ filter __%[1]s_escapeStringWithSpecialChars {
|
||||||
}
|
}
|
||||||
|
|
||||||
$Longest = 0
|
$Longest = 0
|
||||||
$Values = $Out | ForEach-Object {
|
[Array]$Values = $Out | ForEach-Object {
|
||||||
#Split the output in name and description
|
#Split the output in name and description
|
||||||
`+" $Name, $Description = $_.Split(\"`t\",2)"+`
|
`+" $Name, $Description = $_.Split(\"`t\",2)"+`
|
||||||
__%[1]s_debug "Name: $Name Description: $Description"
|
__%[1]s_debug "Name: $Name Description: $Description"
|
||||||
|
@ -182,6 +192,11 @@ filter __%[1]s_escapeStringWithSpecialChars {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# we sort the values in ascending order by name if keep order isn't passed
|
||||||
|
if (($Directive -band $ShellCompDirectiveKeepOrder) -eq 0 ) {
|
||||||
|
$Values = $Values | Sort-Object -Property Name
|
||||||
|
}
|
||||||
|
|
||||||
if (($Directive -band $ShellCompDirectiveNoFileComp) -ne 0 ) {
|
if (($Directive -band $ShellCompDirectiveNoFileComp) -ne 0 ) {
|
||||||
__%[1]s_debug "ShellCompDirectiveNoFileComp is called"
|
__%[1]s_debug "ShellCompDirectiveNoFileComp is called"
|
||||||
|
|
||||||
|
@ -267,7 +282,7 @@ filter __%[1]s_escapeStringWithSpecialChars {
|
||||||
Register-ArgumentCompleter -CommandName '%[1]s' -ScriptBlock $__%[2]sCompleterBlock
|
Register-ArgumentCompleter -CommandName '%[1]s' -ScriptBlock $__%[2]sCompleterBlock
|
||||||
`, name, nameForVar, compCmd,
|
`, name, nameForVar, compCmd,
|
||||||
ShellCompDirectiveError, ShellCompDirectiveNoSpace, ShellCompDirectiveNoFileComp,
|
ShellCompDirectiveError, ShellCompDirectiveNoSpace, ShellCompDirectiveNoFileComp,
|
||||||
ShellCompDirectiveFilterFileExt, ShellCompDirectiveFilterDirs, activeHelpEnvVar(name)))
|
ShellCompDirectiveFilterFileExt, ShellCompDirectiveFilterDirs, ShellCompDirectiveKeepOrder, activeHelpEnvVar(name)))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Command) genPowerShellCompletion(w io.Writer, includeDesc bool) error {
|
func (c *Command) genPowerShellCompletion(w io.Writer, includeDesc bool) error {
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
## Projects using Cobra
|
## Projects using Cobra
|
||||||
|
|
||||||
- [Allero](https://github.com/allero-io/allero)
|
- [Allero](https://github.com/allero-io/allero)
|
||||||
|
- [Arewefastyet](https://benchmark.vitess.io)
|
||||||
- [Arduino CLI](https://github.com/arduino/arduino-cli)
|
- [Arduino CLI](https://github.com/arduino/arduino-cli)
|
||||||
- [Bleve](https://blevesearch.com/)
|
- [Bleve](https://blevesearch.com/)
|
||||||
- [Cilium](https://cilium.io/)
|
- [Cilium](https://cilium.io/)
|
||||||
- [CloudQuery](https://github.com/cloudquery/cloudquery)
|
- [CloudQuery](https://github.com/cloudquery/cloudquery)
|
||||||
- [CockroachDB](https://www.cockroachlabs.com/)
|
- [CockroachDB](https://www.cockroachlabs.com/)
|
||||||
|
- [Constellation](https://github.com/edgelesssys/constellation)
|
||||||
- [Cosmos SDK](https://github.com/cosmos/cosmos-sdk)
|
- [Cosmos SDK](https://github.com/cosmos/cosmos-sdk)
|
||||||
- [Datree](https://github.com/datreeio/datree)
|
- [Datree](https://github.com/datreeio/datree)
|
||||||
- [Delve](https://github.com/derekparker/delve)
|
- [Delve](https://github.com/derekparker/delve)
|
||||||
|
@ -25,7 +27,7 @@
|
||||||
- [Istio](https://istio.io)
|
- [Istio](https://istio.io)
|
||||||
- [Kool](https://github.com/kool-dev/kool)
|
- [Kool](https://github.com/kool-dev/kool)
|
||||||
- [Kubernetes](https://kubernetes.io/)
|
- [Kubernetes](https://kubernetes.io/)
|
||||||
- [Kubescape](https://github.com/armosec/kubescape)
|
- [Kubescape](https://github.com/kubescape/kubescape)
|
||||||
- [KubeVirt](https://github.com/kubevirt/kubevirt)
|
- [KubeVirt](https://github.com/kubevirt/kubevirt)
|
||||||
- [Linkerd](https://linkerd.io/)
|
- [Linkerd](https://linkerd.io/)
|
||||||
- [Mattermost-server](https://github.com/mattermost/mattermost-server)
|
- [Mattermost-server](https://github.com/mattermost/mattermost-server)
|
||||||
|
@ -51,10 +53,12 @@
|
||||||
- [Random](https://github.com/erdaltsksn/random)
|
- [Random](https://github.com/erdaltsksn/random)
|
||||||
- [Rclone](https://rclone.org/)
|
- [Rclone](https://rclone.org/)
|
||||||
- [Scaleway CLI](https://github.com/scaleway/scaleway-cli)
|
- [Scaleway CLI](https://github.com/scaleway/scaleway-cli)
|
||||||
|
- [Sia](https://github.com/SiaFoundation/siad)
|
||||||
- [Skaffold](https://skaffold.dev/)
|
- [Skaffold](https://skaffold.dev/)
|
||||||
- [Tendermint](https://github.com/tendermint/tendermint)
|
- [Tendermint](https://github.com/tendermint/tendermint)
|
||||||
- [Twitch CLI](https://github.com/twitchdev/twitch-cli)
|
- [Twitch CLI](https://github.com/twitchdev/twitch-cli)
|
||||||
- [UpCloud CLI (`upctl`)](https://github.com/UpCloudLtd/upcloud-cli)
|
- [UpCloud CLI (`upctl`)](https://github.com/UpCloudLtd/upcloud-cli)
|
||||||
|
- [Vitess](https://vitess.io)
|
||||||
- VMware's [Tanzu Community Edition](https://github.com/vmware-tanzu/community-edition) & [Tanzu Framework](https://github.com/vmware-tanzu/tanzu-framework)
|
- VMware's [Tanzu Community Edition](https://github.com/vmware-tanzu/community-edition) & [Tanzu Framework](https://github.com/vmware-tanzu/tanzu-framework)
|
||||||
- [Werf](https://werf.io/)
|
- [Werf](https://werf.io/)
|
||||||
- [ZITADEL](https://github.com/zitadel/zitadel)
|
- [ZITADEL](https://github.com/zitadel/zitadel)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2013-2022 The Cobra Authors
|
// Copyright 2013-2023 The Cobra Authors
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
|
|
|
@ -71,7 +71,7 @@ PowerShell:
|
||||||
`,cmd.Root().Name()),
|
`,cmd.Root().Name()),
|
||||||
DisableFlagsInUseLine: true,
|
DisableFlagsInUseLine: true,
|
||||||
ValidArgs: []string{"bash", "zsh", "fish", "powershell"},
|
ValidArgs: []string{"bash", "zsh", "fish", "powershell"},
|
||||||
Args: cobra.ExactValidArgs(1),
|
Args: cobra.MatchAll(cobra.ExactArgs(1), cobra.OnlyValidArgs),
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
switch args[0] {
|
switch args[0] {
|
||||||
case "bash":
|
case "bash":
|
||||||
|
@ -162,16 +162,7 @@ cmd := &cobra.Command{
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
The aliases are not shown to the user on tab completion, but they are accepted as valid nouns by
|
The aliases are shown to the user on tab completion only if no completions were found within sub-commands or `ValidArgs`.
|
||||||
the completion algorithm if entered manually, e.g. in:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
$ kubectl get rc [tab][tab]
|
|
||||||
backend frontend database
|
|
||||||
```
|
|
||||||
|
|
||||||
Note that without declaring `rc` as an alias, the completion algorithm would not know to show the list of
|
|
||||||
replication controllers following `rc`.
|
|
||||||
|
|
||||||
### Dynamic completion of nouns
|
### Dynamic completion of nouns
|
||||||
|
|
||||||
|
@ -237,6 +228,10 @@ ShellCompDirectiveFilterFileExt
|
||||||
// return []string{"themes"}, ShellCompDirectiveFilterDirs
|
// return []string{"themes"}, ShellCompDirectiveFilterDirs
|
||||||
//
|
//
|
||||||
ShellCompDirectiveFilterDirs
|
ShellCompDirectiveFilterDirs
|
||||||
|
|
||||||
|
// ShellCompDirectiveKeepOrder indicates that the shell should preserve the order
|
||||||
|
// in which the completions are provided
|
||||||
|
ShellCompDirectiveKeepOrder
|
||||||
```
|
```
|
||||||
|
|
||||||
***Note***: When using the `ValidArgsFunction`, Cobra will call your registered function after having parsed all flags and arguments provided in the command-line. You therefore don't need to do this parsing yourself. For example, when a user calls `helm status --namespace my-rook-ns [tab][tab]`, Cobra will call your registered `ValidArgsFunction` after having parsed the `--namespace` flag, as it would have done when calling the `RunE` function.
|
***Note***: When using the `ValidArgsFunction`, Cobra will call your registered function after having parsed all flags and arguments provided in the command-line. You therefore don't need to do this parsing yourself. For example, when a user calls `helm status --namespace my-rook-ns [tab][tab]`, Cobra will call your registered `ValidArgsFunction` after having parsed the `--namespace` flag, as it would have done when calling the `RunE` function.
|
||||||
|
@ -385,6 +380,19 @@ or
|
||||||
```go
|
```go
|
||||||
ValidArgs: []string{"bash\tCompletions for bash", "zsh\tCompletions for zsh"}
|
ValidArgs: []string{"bash\tCompletions for bash", "zsh\tCompletions for zsh"}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
If you don't want to show descriptions in the completions, you can add `--no-descriptions` to the default `completion` command to disable them, like:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ source <(helm completion bash)
|
||||||
|
$ helm completion [tab][tab]
|
||||||
|
bash (generate autocompletion script for bash) powershell (generate autocompletion script for powershell)
|
||||||
|
fish (generate autocompletion script for fish) zsh (generate autocompletion script for zsh)
|
||||||
|
|
||||||
|
$ source <(helm completion bash --no-descriptions)
|
||||||
|
$ helm completion [tab][tab]
|
||||||
|
bash fish powershell zsh
|
||||||
|
```
|
||||||
## Bash completions
|
## Bash completions
|
||||||
|
|
||||||
### Dependencies
|
### Dependencies
|
||||||
|
|
|
@ -188,6 +188,37 @@ var versionCmd = &cobra.Command{
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Organizing subcommands
|
||||||
|
|
||||||
|
A command may have subcommands which in turn may have other subcommands. This is achieved by using
|
||||||
|
`AddCommand`. In some cases, especially in larger applications, each subcommand may be defined in
|
||||||
|
its own go package.
|
||||||
|
|
||||||
|
The suggested approach is for the parent command to use `AddCommand` to add its most immediate
|
||||||
|
subcommands. For example, consider the following directory structure:
|
||||||
|
|
||||||
|
```text
|
||||||
|
├── cmd
|
||||||
|
│ ├── root.go
|
||||||
|
│ └── sub1
|
||||||
|
│ ├── sub1.go
|
||||||
|
│ └── sub2
|
||||||
|
│ ├── leafA.go
|
||||||
|
│ ├── leafB.go
|
||||||
|
│ └── sub2.go
|
||||||
|
└── main.go
|
||||||
|
```
|
||||||
|
|
||||||
|
In this case:
|
||||||
|
|
||||||
|
* The `init` function of `root.go` adds the command defined in `sub1.go` to the root command.
|
||||||
|
* The `init` function of `sub1.go` adds the command defined in `sub2.go` to the sub1 command.
|
||||||
|
* The `init` function of `sub2.go` adds the commands defined in `leafA.go` and `leafB.go` to the
|
||||||
|
sub2 command.
|
||||||
|
|
||||||
|
This approach ensures the subcommands are always included at compile time while avoiding cyclic
|
||||||
|
references.
|
||||||
|
|
||||||
### Returning and handling errors
|
### Returning and handling errors
|
||||||
|
|
||||||
If you wish to return an error to the caller of a command, `RunE` can be used.
|
If you wish to return an error to the caller of a command, `RunE` can be used.
|
||||||
|
@ -313,8 +344,8 @@ 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(&u, "json", false, "Output in JSON")
|
rootCmd.Flags().BoolVar(&ofJson, "json", false, "Output in JSON")
|
||||||
rootCmd.Flags().BoolVar(&pw, "yaml", false, "Output in YAML")
|
rootCmd.Flags().BoolVar(&ofYaml, "yaml", false, "Output in YAML")
|
||||||
rootCmd.MarkFlagsMutuallyExclusive("json", "yaml")
|
rootCmd.MarkFlagsMutuallyExclusive("json", "yaml")
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -349,7 +380,7 @@ shown below:
|
||||||
```go
|
```go
|
||||||
var cmd = &cobra.Command{
|
var cmd = &cobra.Command{
|
||||||
Short: "hello",
|
Short: "hello",
|
||||||
Args: MatchAll(ExactArgs(2), OnlyValidArgs),
|
Args: cobra.MatchAll(cobra.ExactArgs(2), cobra.OnlyValidArgs),
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
fmt.Println("Hello, World!")
|
fmt.Println("Hello, World!")
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2013-2022 The Cobra Authors
|
// Copyright 2013-2023 The Cobra Authors
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
|
@ -90,6 +90,7 @@ func genZshComp(buf io.StringWriter, name string, includeDesc bool) {
|
||||||
compCmd = ShellCompNoDescRequestCmd
|
compCmd = ShellCompNoDescRequestCmd
|
||||||
}
|
}
|
||||||
WriteStringAndCheck(buf, fmt.Sprintf(`#compdef %[1]s
|
WriteStringAndCheck(buf, fmt.Sprintf(`#compdef %[1]s
|
||||||
|
compdef _%[1]s %[1]s
|
||||||
|
|
||||||
# zsh completion for %-36[1]s -*- shell-script -*-
|
# zsh completion for %-36[1]s -*- shell-script -*-
|
||||||
|
|
||||||
|
@ -108,8 +109,9 @@ _%[1]s()
|
||||||
local shellCompDirectiveNoFileComp=%[5]d
|
local shellCompDirectiveNoFileComp=%[5]d
|
||||||
local shellCompDirectiveFilterFileExt=%[6]d
|
local shellCompDirectiveFilterFileExt=%[6]d
|
||||||
local shellCompDirectiveFilterDirs=%[7]d
|
local shellCompDirectiveFilterDirs=%[7]d
|
||||||
|
local shellCompDirectiveKeepOrder=%[8]d
|
||||||
|
|
||||||
local lastParam lastChar flagPrefix requestComp out directive comp lastComp noSpace
|
local lastParam lastChar flagPrefix requestComp out directive comp lastComp noSpace keepOrder
|
||||||
local -a completions
|
local -a completions
|
||||||
|
|
||||||
__%[1]s_debug "\n========= starting completion logic =========="
|
__%[1]s_debug "\n========= starting completion logic =========="
|
||||||
|
@ -177,7 +179,7 @@ _%[1]s()
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
|
|
||||||
local activeHelpMarker="%[8]s"
|
local activeHelpMarker="%[9]s"
|
||||||
local endIndex=${#activeHelpMarker}
|
local endIndex=${#activeHelpMarker}
|
||||||
local startIndex=$((${#activeHelpMarker}+1))
|
local startIndex=$((${#activeHelpMarker}+1))
|
||||||
local hasActiveHelp=0
|
local hasActiveHelp=0
|
||||||
|
@ -227,6 +229,11 @@ _%[1]s()
|
||||||
noSpace="-S ''"
|
noSpace="-S ''"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ $((directive & shellCompDirectiveKeepOrder)) -ne 0 ]; then
|
||||||
|
__%[1]s_debug "Activating keep order."
|
||||||
|
keepOrder="-V"
|
||||||
|
fi
|
||||||
|
|
||||||
if [ $((directive & shellCompDirectiveFilterFileExt)) -ne 0 ]; then
|
if [ $((directive & shellCompDirectiveFilterFileExt)) -ne 0 ]; then
|
||||||
# File extension filtering
|
# File extension filtering
|
||||||
local filteringCmd
|
local filteringCmd
|
||||||
|
@ -262,7 +269,7 @@ _%[1]s()
|
||||||
return $result
|
return $result
|
||||||
else
|
else
|
||||||
__%[1]s_debug "Calling _describe"
|
__%[1]s_debug "Calling _describe"
|
||||||
if eval _describe "completions" completions $flagPrefix $noSpace; then
|
if eval _describe $keepOrder "completions" completions $flagPrefix $noSpace; then
|
||||||
__%[1]s_debug "_describe found some completions"
|
__%[1]s_debug "_describe found some completions"
|
||||||
|
|
||||||
# Return the success of having called _describe
|
# Return the success of having called _describe
|
||||||
|
@ -296,6 +303,6 @@ if [ "$funcstack[1]" = "_%[1]s" ]; then
|
||||||
fi
|
fi
|
||||||
`, name, compCmd,
|
`, name, compCmd,
|
||||||
ShellCompDirectiveError, ShellCompDirectiveNoSpace, ShellCompDirectiveNoFileComp,
|
ShellCompDirectiveError, ShellCompDirectiveNoSpace, ShellCompDirectiveNoFileComp,
|
||||||
ShellCompDirectiveFilterFileExt, ShellCompDirectiveFilterDirs,
|
ShellCompDirectiveFilterFileExt, ShellCompDirectiveFilterDirs, ShellCompDirectiveKeepOrder,
|
||||||
activeHelpMarker))
|
activeHelpMarker))
|
||||||
}
|
}
|
||||||
|
|
|
@ -284,7 +284,7 @@ github.com/hashicorp/hcl/hcl/token
|
||||||
github.com/hashicorp/hcl/json/parser
|
github.com/hashicorp/hcl/json/parser
|
||||||
github.com/hashicorp/hcl/json/scanner
|
github.com/hashicorp/hcl/json/scanner
|
||||||
github.com/hashicorp/hcl/json/token
|
github.com/hashicorp/hcl/json/token
|
||||||
# github.com/inconshreveable/mousetrap v1.0.1
|
# github.com/inconshreveable/mousetrap v1.1.0
|
||||||
## explicit; go 1.18
|
## explicit; go 1.18
|
||||||
github.com/inconshreveable/mousetrap
|
github.com/inconshreveable/mousetrap
|
||||||
# github.com/jackc/chunkreader/v2 v2.0.1
|
# github.com/jackc/chunkreader/v2 v2.0.1
|
||||||
|
@ -417,7 +417,7 @@ github.com/spf13/afero/mem
|
||||||
# github.com/spf13/cast v1.5.0
|
# github.com/spf13/cast v1.5.0
|
||||||
## explicit; go 1.18
|
## explicit; go 1.18
|
||||||
github.com/spf13/cast
|
github.com/spf13/cast
|
||||||
# github.com/spf13/cobra v1.6.1
|
# github.com/spf13/cobra v1.7.0
|
||||||
## explicit; go 1.15
|
## explicit; go 1.15
|
||||||
github.com/spf13/cobra
|
github.com/spf13/cobra
|
||||||
# github.com/spf13/jwalterweatherman v1.1.0
|
# github.com/spf13/jwalterweatherman v1.1.0
|
||||||
|
|
Loading…
Reference in New Issue