Skip to content

Commit

Permalink
deprecate <1.12.x, use golangci-lint (spf13#876)
Browse files Browse the repository at this point in the history
* deprecate go 1.10.x and 1.11.x
* use golangci-lint in Travis CI
* fix linting issues accordingly
  • Loading branch information
umarcor committed Oct 2, 2019
1 parent 2038338 commit e63a44d
Show file tree
Hide file tree
Showing 30 changed files with 350 additions and 457 deletions.
9 changes: 1 addition & 8 deletions .circleci/config.yml
Expand Up @@ -8,6 +8,7 @@ references:
run:
name: "All Commands"
command: |
export GO111MODULE=on
mkdir -p bin
curl -Lso bin/shellcheck https://github.com/caarlos0/shellcheck-docker/releases/download/v0.4.6/shellcheck
chmod +x bin/shellcheck
Expand All @@ -29,13 +30,6 @@ jobs:
- run:
name: "Check formatting"
command: diff -u <(echo -n) <(gofmt -d -s .)
go-previous:
docker:
- image: circleci/golang:1.11
working_directory: *workspace
steps:
- checkout
- *run_tests
go-latest:
docker:
- image: circleci/golang:latest
Expand All @@ -49,5 +43,4 @@ workflows:
main:
jobs:
- go-current
- go-previous
- go-latest
1 change: 1 addition & 0 deletions .gitattributes
@@ -0,0 +1 @@
* text=auto
3 changes: 3 additions & 0 deletions .gitignore
Expand Up @@ -37,3 +37,6 @@ cobra.test

.idea/
*.iml

# test-generated files
cobra/cmd/testproject
25 changes: 25 additions & 0 deletions .golangci.yml
@@ -0,0 +1,25 @@
run:
deadline: 5m

linters:
enable:
- deadcode
- errcheck
- gas
- goconst
- goimports
- golint
- govet
- ineffassign
- interfacer
- maligned
- megacheck
- structcheck
- unconvert
- varcheck
enable-all: false
disable-all: true
# presets:
# - bugs
# - unused
fast: false
26 changes: 11 additions & 15 deletions .travis.yml
@@ -1,31 +1,27 @@
language: go

stages:
- diff
- lint
- test

go:
- 1.11.x
- 1.12.x
- 1.13.x
- tip

env:
- GO111MODULE=on

matrix:
allow_failures:
- go: tip
include:
- stage: diff
go: 1.13.x
script: diff -u <(echo -n) <(gofmt -d -s .)
env: GO111MODULE=on

before_install: go get -u github.com/kyoh86/richgo

script:
- richgo test -v ./...
- go build
- if [ -z $NOVET ]; then
diff -u <(echo -n) <(go vet . 2>&1 | grep -vE 'ExampleCommand|bash_completions.*Fprint');
fi

matrix:
allow_failures:
- go: tip
include:
- stage: lint
go: 1.13.x
before_install: go install github.com/golangci/golangci-lint@v1.19.1
script: golangci-lint run -v
3 changes: 1 addition & 2 deletions README.md
Expand Up @@ -211,7 +211,6 @@ import (
"fmt"
"os"

homedir "github.com/mitchellh/go-homedir"
"github.com/umarcor/cobra"
"github.com/spf13/viper"
)
Expand Down Expand Up @@ -239,7 +238,7 @@ func initConfig() {
viper.SetConfigFile(cfgFile)
} else {
// Find home directory.
home, err := homedir.Dir()
home, err := os.UserHomeDir()
if err != nil {
fmt.Println(err)
os.Exit(1)
Expand Down
127 changes: 65 additions & 62 deletions bash_completions.go
Expand Up @@ -19,9 +19,9 @@ const (
BashCompSubdirsInDir = "cobra_annotation_bash_completion_subdirs_in_dir"
)

func writePreamble(buf *bytes.Buffer, name string) {
buf.WriteString(fmt.Sprintf("# bash completion for %-36s -*- shell-script -*-\n", name))
buf.WriteString(fmt.Sprintf(`
func writePreamble(buf io.StringWriter, name string) {
WrStringAndCheck(buf, fmt.Sprintf("# bash completion for %-36s -*- shell-script -*-\n", name))
WrStringAndCheck(buf, fmt.Sprintf(`
__%[1]s_debug()
{
if [[ -n ${BASH_COMP_DEBUG_FILE} ]]; then
Expand Down Expand Up @@ -281,10 +281,10 @@ __%[1]s_handle_word()
`, name))
}

func writePostscript(buf *bytes.Buffer, name string) {
func writePostscript(buf io.StringWriter, name string) {
name = strings.Replace(name, ":", "__", -1)
buf.WriteString(fmt.Sprintf("__start_%s()\n", name))
buf.WriteString(fmt.Sprintf(`{
WrStringAndCheck(buf, fmt.Sprintf("__start_%s()\n", name))
WrStringAndCheck(buf, fmt.Sprintf(`{
local cur prev words cword
declare -A flaghash 2>/dev/null || :
declare -A aliashash 2>/dev/null || :
Expand All @@ -310,101 +310,104 @@ func writePostscript(buf *bytes.Buffer, name string) {
}
`, name))
buf.WriteString(fmt.Sprintf(`if [[ $(type -t compopt) = "builtin" ]]; then
WrStringAndCheck(buf, fmt.Sprintf(`if [[ $(type -t compopt) = "builtin" ]]; then
complete -o default -F __start_%s %s
else
complete -o default -o nospace -F __start_%s %s
fi
`, name, name, name, name))
buf.WriteString("# ex: ts=4 sw=4 et filetype=sh\n")
WrStringAndCheck(buf, "# ex: ts=4 sw=4 et filetype=sh\n")
}

func writeCommands(buf *bytes.Buffer, cmd *Command) {
buf.WriteString(" commands=()\n")
func writeCommands(buf io.StringWriter, cmd *Command) {
WrStringAndCheck(buf, " commands=()\n")
for _, c := range cmd.Commands() {
if !c.IsAvailableCommand() || c == cmd.helpCommand {
continue
}
buf.WriteString(fmt.Sprintf(" commands+=(%q)\n", c.Name()))
WrStringAndCheck(buf, fmt.Sprintf(" commands+=(%q)\n", c.Name()))
writeCmdAliases(buf, c)
}
buf.WriteString("\n")
WrStringAndCheck(buf, "\n")
}

func writeFlagHandler(buf *bytes.Buffer, name string, annotations map[string][]string, cmd *Command) {
func writeFlagHandler(buf io.StringWriter, name string, annotations map[string][]string, cmd *Command) {
for key, value := range annotations {
switch key {
case BashCompFilenameExt:
buf.WriteString(fmt.Sprintf(" flags_with_completion+=(%q)\n", name))
WrStringAndCheck(buf, fmt.Sprintf(" flags_with_completion+=(%q)\n", name))

var ext string
if len(value) > 0 {
ext = fmt.Sprintf("__%s_handle_filename_extension_flag ", cmd.Root().Name()) + strings.Join(value, "|")
} else {
ext = "_filedir"
}
buf.WriteString(fmt.Sprintf(" flags_completion+=(%q)\n", ext))
WrStringAndCheck(buf, fmt.Sprintf(" flags_completion+=(%q)\n", ext))
case BashCompCustom:
buf.WriteString(fmt.Sprintf(" flags_with_completion+=(%q)\n", name))
WrStringAndCheck(buf, fmt.Sprintf(" flags_with_completion+=(%q)\n", name))

if len(value) > 0 {
handlers := strings.Join(value, "; ")
buf.WriteString(fmt.Sprintf(" flags_completion+=(%q)\n", handlers))
WrStringAndCheck(buf, fmt.Sprintf(" flags_completion+=(%q)\n", handlers))
} else {
buf.WriteString(" flags_completion+=(:)\n")
WrStringAndCheck(buf, " flags_completion+=(:)\n")
}
case BashCompSubdirsInDir:
buf.WriteString(fmt.Sprintf(" flags_with_completion+=(%q)\n", name))
WrStringAndCheck(buf, fmt.Sprintf(" flags_with_completion+=(%q)\n", name))

var ext string
if len(value) == 1 {
ext = fmt.Sprintf("__%s_handle_subdirs_in_dir_flag ", cmd.Root().Name()) + value[0]
} else {
ext = "_filedir -d"
}
buf.WriteString(fmt.Sprintf(" flags_completion+=(%q)\n", ext))
WrStringAndCheck(buf, fmt.Sprintf(" flags_completion+=(%q)\n", ext))
}
}
}

func writeShortFlag(buf *bytes.Buffer, flag *pflag.Flag, cmd *Command) {
const cbn = "\")\n"

func writeShortFlag(buf io.StringWriter, flag *pflag.Flag, cmd *Command) {
name := flag.Shorthand
format := " "
if len(flag.NoOptDefVal) == 0 {
format += "two_word_"
}
format += "flags+=(\"-%s\")\n"
buf.WriteString(fmt.Sprintf(format, name))
format += "flags+=(\"-%s" + cbn
WrStringAndCheck(buf, fmt.Sprintf(format, name))
writeFlagHandler(buf, "-"+name, flag.Annotations, cmd)
}

func writeFlag(buf *bytes.Buffer, flag *pflag.Flag, cmd *Command) {
func writeFlag(buf io.StringWriter, flag *pflag.Flag, cmd *Command) {
name := flag.Name
format := " flags+=(\"--%s"
if len(flag.NoOptDefVal) == 0 {
format += "="
}
format += "\")\n"
buf.WriteString(fmt.Sprintf(format, name))
format += cbn
WrStringAndCheck(buf, fmt.Sprintf(format, name))
if len(flag.NoOptDefVal) == 0 {
format = " two_word_flags+=(\"--%s\")\n"
buf.WriteString(fmt.Sprintf(format, name))
format = " two_word_flags+=(\"--%s" + cbn
WrStringAndCheck(buf, fmt.Sprintf(format, name))
}
writeFlagHandler(buf, "--"+name, flag.Annotations, cmd)
}

func writeLocalNonPersistentFlag(buf *bytes.Buffer, flag *pflag.Flag) {
func writeLocalNonPersistentFlag(buf io.StringWriter, flag *pflag.Flag) {
name := flag.Name
format := " local_nonpersistent_flags+=(\"--%s"
if len(flag.NoOptDefVal) == 0 {
format += "="
}
format += "\")\n"
buf.WriteString(fmt.Sprintf(format, name))
format += cbn
WrStringAndCheck(buf, fmt.Sprintf(format, name))
}

func writeFlags(buf *bytes.Buffer, cmd *Command) {
buf.WriteString(` flags=()
func writeFlags(buf io.StringWriter, cmd *Command) {
WrStringAndCheck(buf, ` flags=()
two_word_flags=()
local_nonpersistent_flags=()
flags_with_completion=()
Expand Down Expand Up @@ -434,11 +437,11 @@ func writeFlags(buf *bytes.Buffer, cmd *Command) {
}
})

buf.WriteString("\n")
WrStringAndCheck(buf, "\n")
}

func writeRequiredFlag(buf *bytes.Buffer, cmd *Command) {
buf.WriteString(" must_have_one_flag=()\n")
func writeRequiredFlag(buf io.StringWriter, cmd *Command) {
WrStringAndCheck(buf, " must_have_one_flag=()\n")
flags := cmd.NonInheritedFlags()
flags.VisitAll(func(flag *pflag.Flag) {
if nonCompletableFlag(flag) {
Expand All @@ -451,49 +454,49 @@ func writeRequiredFlag(buf *bytes.Buffer, cmd *Command) {
if flag.Value.Type() != "bool" {
format += "="
}
format += "\")\n"
buf.WriteString(fmt.Sprintf(format, flag.Name))
format += cbn
WrStringAndCheck(buf, fmt.Sprintf(format, flag.Name))

if len(flag.Shorthand) > 0 {
buf.WriteString(fmt.Sprintf(" must_have_one_flag+=(\"-%s\")\n", flag.Shorthand))
WrStringAndCheck(buf, fmt.Sprintf(" must_have_one_flag+=(\"-%s"+cbn, flag.Shorthand))
}
}
}
})
}

func writeRequiredNouns(buf *bytes.Buffer, cmd *Command) {
buf.WriteString(" must_have_one_noun=()\n")
sort.Sort(sort.StringSlice(cmd.ValidArgs))
func writeRequiredNouns(buf io.StringWriter, cmd *Command) {
WrStringAndCheck(buf, " must_have_one_noun=()\n")
sort.Strings(cmd.ValidArgs)
for _, value := range cmd.ValidArgs {
buf.WriteString(fmt.Sprintf(" must_have_one_noun+=(%q)\n", value))
WrStringAndCheck(buf, fmt.Sprintf(" must_have_one_noun+=(%q)\n", value))
}
}

func writeCmdAliases(buf *bytes.Buffer, cmd *Command) {
func writeCmdAliases(buf io.StringWriter, cmd *Command) {
if len(cmd.Aliases) == 0 {
return
}

sort.Sort(sort.StringSlice(cmd.Aliases))
sort.Strings(cmd.Aliases)

buf.WriteString(fmt.Sprint(` if [[ -z "${BASH_VERSION}" || "${BASH_VERSINFO[0]}" -gt 3 ]]; then`, "\n"))
WrStringAndCheck(buf, fmt.Sprint(` if [[ -z "${BASH_VERSION}" || "${BASH_VERSINFO[0]}" -gt 3 ]]; then`, "\n"))
for _, value := range cmd.Aliases {
buf.WriteString(fmt.Sprintf(" command_aliases+=(%q)\n", value))
buf.WriteString(fmt.Sprintf(" aliashash[%q]=%q\n", value, cmd.Name()))
WrStringAndCheck(buf, fmt.Sprintf(" command_aliases+=(%q)\n", value))
WrStringAndCheck(buf, fmt.Sprintf(" aliashash[%q]=%q\n", value, cmd.Name()))
}
buf.WriteString(` fi`)
buf.WriteString("\n")
WrStringAndCheck(buf, ` fi`)
WrStringAndCheck(buf, "\n")
}
func writeArgAliases(buf *bytes.Buffer, cmd *Command) {
buf.WriteString(" noun_aliases=()\n")
sort.Sort(sort.StringSlice(cmd.ArgAliases))
func writeArgAliases(buf io.StringWriter, cmd *Command) {
WrStringAndCheck(buf, " noun_aliases=()\n")
sort.Strings(cmd.ArgAliases)
for _, value := range cmd.ArgAliases {
buf.WriteString(fmt.Sprintf(" noun_aliases+=(%q)\n", value))
WrStringAndCheck(buf, fmt.Sprintf(" noun_aliases+=(%q)\n", value))
}
}

func gen(buf *bytes.Buffer, cmd *Command) {
func gen(buf io.StringWriter, cmd *Command) {
for _, c := range cmd.Commands() {
if !c.IsAvailableCommand() || c == cmd.helpCommand {
continue
Expand All @@ -505,22 +508,22 @@ func gen(buf *bytes.Buffer, cmd *Command) {
commandName = strings.Replace(commandName, ":", "__", -1)

if cmd.Root() == cmd {
buf.WriteString(fmt.Sprintf("_%s_root_command()\n{\n", commandName))
WrStringAndCheck(buf, fmt.Sprintf("_%s_root_command()\n{\n", commandName))
} else {
buf.WriteString(fmt.Sprintf("_%s()\n{\n", commandName))
WrStringAndCheck(buf, fmt.Sprintf("_%s()\n{\n", commandName))
}

buf.WriteString(fmt.Sprintf(" last_command=%q\n", commandName))
buf.WriteString("\n")
buf.WriteString(" command_aliases=()\n")
buf.WriteString("\n")
WrStringAndCheck(buf, fmt.Sprintf(" last_command=%q\n", commandName))
WrStringAndCheck(buf, "\n")
WrStringAndCheck(buf, " command_aliases=()\n")
WrStringAndCheck(buf, "\n")

writeCommands(buf, cmd)
writeFlags(buf, cmd)
writeRequiredFlag(buf, cmd)
writeRequiredNouns(buf, cmd)
writeArgAliases(buf, cmd)
buf.WriteString("}\n\n")
WrStringAndCheck(buf, "}\n\n")
}

// GenBashCompletion generates bash completion file and writes to the passed writer.
Expand Down

0 comments on commit e63a44d

Please sign in to comment.