Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add golangci-lint and GitHub Actions workflow #968

Closed
wants to merge 11 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitattributes
@@ -0,0 +1 @@
* text=auto
60 changes: 60 additions & 0 deletions .github/workflows/push.yml
@@ -0,0 +1,60 @@
name: 'push'

on:
push:
pull_request:

env:
GO111MODULE: on

jobs:

test:
strategy:
fail-fast: false
matrix:
os: [ ubuntu, windows, macOS ]
go: [
1.10.x,
1.11.x,
1.12.x,
1.13.x,
1.14.x
]

runs-on: ${{ matrix.os }}-latest

steps:

- name: Setup go
uses: actions/setup-go@v1
with:
go-version: ${{ matrix.go }}


- run: git config --global core.autocrlf input
if: matrix.os == 'windows'
shell: bash

- uses: actions/checkout@v2

- name: Install golangci-lint, richgo and gox
run: |
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $HOME/go/bin/ latest
go install github.com/kyoh86/richgo
go install github.com/mitchellh/gox

- name: Run tests
shell: bash
run: |
export PATH=$PATH:$HOME/go/bin/
make test

- name: Check formatting
run: make fmt

- name: Build generator
shell: bash
run: |
export PATH=$PATH:$HOME/go/bin/
make cobra_generator
48 changes: 48 additions & 0 deletions .golangci.yml
@@ -0,0 +1,48 @@
run:
deadline: 5m

linters:
disable-all: true
enable:
#- bodyclose
- deadcode
#- depguard
#- dogsled
#- dupl
- errcheck
#- exhaustive
#- funlen
- gas
#- gochecknoinits
- goconst
#- gocritic
#- gocyclo
#- gofmt
- goimports
- golint
#- gomnd
#- goprintffuncname
#- gosec
#- gosimple
- govet
- ineffassign
#- interfacer
#- lll
- maligned
- megacheck
#- misspell
#- nakedret
#- noctx
#- nolintlint
#- rowserrcheck
#- scopelint
#- staticcheck
- structcheck
#- stylecheck
#- typecheck
- unconvert
#- unparam
#- unused
- varcheck
#- whitespace
fast: false
11 changes: 6 additions & 5 deletions .travis.yml
@@ -1,29 +1,30 @@
language: go

stages:
- diff
- test
- build

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

env: GO111MODULE=on

before_install:
- go get -u github.com/kyoh86/richgo
- go get -u github.com/mitchellh/gox
- curl -sfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin latest

matrix:
allow_failures:
- go: tip
include:
- stage: diff
go: 1.13.x
script: make fmt
- stage: build
go: 1.13.x
script: make cobra_generator

script:
script:
- make test
18 changes: 11 additions & 7 deletions Makefile
@@ -1,21 +1,29 @@
BIN="./bin"
SRC=$(shell find . -name "*.go")

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")
endif

ifeq (, $(shell which richgo))
$(warning "could not find richgo in $(PATH), run: go get github.com/kyoh86/richgo")
endif

.PHONY: fmt vet test cobra_generator install_deps clean
.PHONY: fmt lint test cobra_generator install_deps clean

default: all

all: fmt vet test cobra_generator
all: fmt test cobra_generator

fmt:
$(info ******************** checking formatting ********************)
@test -z $(shell gofmt -l $(SRC)) || (gofmt -d $(SRC); exit 1)

test: install_deps vet
lint:
$(info ******************** running lint tools ********************)
golangci-lint run -v

test: install_deps lint
$(info ******************** running tests ********************)
richgo test -v ./...

Expand All @@ -28,9 +36,5 @@ install_deps:
$(info ******************** downloading dependencies ********************)
go get -v ./...

vet:
$(info ******************** vetting ********************)
go vet ./...

clean:
rm -rf $(BIN)
9 changes: 1 addition & 8 deletions README.md
Expand Up @@ -234,21 +234,14 @@ func init() {
rootCmd.AddCommand(initCmd)
}

func er(msg interface{}) {
fmt.Println("Error:", msg)
os.Exit(1)
}

func initConfig() {
if cfgFile != "" {
// Use config file from the flag.
viper.SetConfigFile(cfgFile)
} else {
// Find home directory.
home, err := homedir.Dir()
if err != nil {
er(err)
}
cobra.CheckErr(err)

// Search config in home directory with name ".cobra" (without extension).
viper.AddConfigPath(home)
Expand Down
18 changes: 10 additions & 8 deletions bash_completions.go
Expand Up @@ -467,13 +467,15 @@ func writeFlagHandler(buf *bytes.Buffer, name string, annotations map[string][]s
}
}

const cbn = "\")\n"

func writeShortFlag(buf *bytes.Buffer, flag *pflag.Flag, cmd *Command) {
name := flag.Shorthand
format := " "
if len(flag.NoOptDefVal) == 0 {
format += "two_word_"
}
format += "flags+=(\"-%s\")\n"
format += "flags+=(\"-%s" + cbn
buf.WriteString(fmt.Sprintf(format, name))
writeFlagHandler(buf, "-"+name, flag.Annotations, cmd)
}
Expand All @@ -484,20 +486,20 @@ func writeFlag(buf *bytes.Buffer, flag *pflag.Flag, cmd *Command) {
if len(flag.NoOptDefVal) == 0 {
format += "="
}
format += "\")\n"
format += cbn
buf.WriteString(fmt.Sprintf(format, name))
if len(flag.NoOptDefVal) == 0 {
format = " two_word_flags+=(\"--%s\")\n"
format = " two_word_flags+=(\"--%s" + cbn
buf.WriteString(fmt.Sprintf(format, name))
}
writeFlagHandler(buf, "--"+name, flag.Annotations, cmd)
}

func writeLocalNonPersistentFlag(buf *bytes.Buffer, flag *pflag.Flag) {
name := flag.Name
format := " local_nonpersistent_flags+=(\"--%[1]s\")\n"
format := " local_nonpersistent_flags+=(\"--%[1]s" + cbn
if len(flag.NoOptDefVal) == 0 {
format += " local_nonpersistent_flags+=(\"--%[1]s=\")\n"
format += " local_nonpersistent_flags+=(\"--%[1]s=" + cbn
}
buf.WriteString(fmt.Sprintf(format, name))
if len(flag.Shorthand) > 0 {
Expand Down Expand Up @@ -583,7 +585,7 @@ func writeRequiredFlag(buf *bytes.Buffer, cmd *Command) {

func writeRequiredNouns(buf *bytes.Buffer, cmd *Command) {
buf.WriteString(" must_have_one_noun=()\n")
sort.Sort(sort.StringSlice(cmd.ValidArgs))
sort.Strings(cmd.ValidArgs)
for _, value := range cmd.ValidArgs {
// Remove any description that may be included following a tab character.
// Descriptions are not supported by bash completion.
Expand All @@ -600,7 +602,7 @@ func writeCmdAliases(buf *bytes.Buffer, cmd *Command) {
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"))
for _, value := range cmd.Aliases {
Expand All @@ -612,7 +614,7 @@ func writeCmdAliases(buf *bytes.Buffer, cmd *Command) {
}
func writeArgAliases(buf *bytes.Buffer, cmd *Command) {
buf.WriteString(" noun_aliases=()\n")
sort.Sort(sort.StringSlice(cmd.ArgAliases))
sort.Strings(cmd.ArgAliases)
for _, value := range cmd.ArgAliases {
buf.WriteString(fmt.Sprintf(" noun_aliases+=(%q)\n", value))
}
Expand Down
39 changes: 20 additions & 19 deletions bash_completions_test.go
Expand Up @@ -40,10 +40,9 @@ func checkRegex(t *testing.T, found, pattern string) {
}

func runShellCheck(s string) error {
excluded := []string{
cmd := exec.Command("shellcheck", "-s", "bash", "-", "-e",
"SC2034", // PREFIX appears unused. Verify it or export it.
}
cmd := exec.Command("shellcheck", "-s", "bash", "-", "-e", strings.Join(excluded, ","))
)
cmd.Stderr = os.Stderr
cmd.Stdout = os.Stdout

Expand All @@ -52,7 +51,9 @@ func runShellCheck(s string) error {
return err
}
go func() {
stdin.Write([]byte(s))
_, err := stdin.Write([]byte(s))
CheckErr(err)

stdin.Close()
}()

Expand All @@ -74,26 +75,26 @@ func TestBashCompletions(t *testing.T) {
Run: emptyRun,
}
rootCmd.Flags().IntP("introot", "i", -1, "help message for flag introot")
rootCmd.MarkFlagRequired("introot")
assertNoErr(t, rootCmd.MarkFlagRequired("introot"))

// Filename.
rootCmd.Flags().String("filename", "", "Enter a filename")
rootCmd.MarkFlagFilename("filename", "json", "yaml", "yml")
assertNoErr(t, rootCmd.MarkFlagFilename("filename", "json", "yaml", "yml"))

// Persistent filename.
rootCmd.PersistentFlags().String("persistent-filename", "", "Enter a filename")
rootCmd.MarkPersistentFlagFilename("persistent-filename")
rootCmd.MarkPersistentFlagRequired("persistent-filename")
assertNoErr(t, rootCmd.MarkPersistentFlagFilename("persistent-filename"))
assertNoErr(t, rootCmd.MarkPersistentFlagRequired("persistent-filename"))

// Filename extensions.
rootCmd.Flags().String("filename-ext", "", "Enter a filename (extension limited)")
rootCmd.MarkFlagFilename("filename-ext")
assertNoErr(t, rootCmd.MarkFlagFilename("filename-ext"))
rootCmd.Flags().String("custom", "", "Enter a filename (extension limited)")
rootCmd.MarkFlagCustom("custom", "__complete_custom")
assertNoErr(t, rootCmd.MarkFlagCustom("custom", "__complete_custom"))

// Subdirectories in a given directory.
rootCmd.Flags().String("theme", "", "theme to use (located in /themes/THEMENAME/)")
rootCmd.Flags().SetAnnotation("theme", BashCompSubdirsInDir, []string{"themes"})
assertNoErr(t, rootCmd.Flags().SetAnnotation("theme", BashCompSubdirsInDir, []string{"themes"}))

// For two word flags check
rootCmd.Flags().StringP("two", "t", "", "this is two word flags")
Expand All @@ -109,9 +110,9 @@ func TestBashCompletions(t *testing.T) {
}

echoCmd.Flags().String("filename", "", "Enter a filename")
echoCmd.MarkFlagFilename("filename", "json", "yaml", "yml")
assertNoErr(t, echoCmd.MarkFlagFilename("filename", "json", "yaml", "yml"))
echoCmd.Flags().String("config", "", "config to use (located in /config/PROFILE/)")
echoCmd.Flags().SetAnnotation("config", BashCompSubdirsInDir, []string{"config"})
assertNoErr(t, echoCmd.Flags().SetAnnotation("config", BashCompSubdirsInDir, []string{"config"}))

printCmd := &Command{
Use: "print [string to print]",
Expand Down Expand Up @@ -149,7 +150,7 @@ func TestBashCompletions(t *testing.T) {
rootCmd.AddCommand(echoCmd, printCmd, deprecatedCmd, colonCmd)

buf := new(bytes.Buffer)
rootCmd.GenBashCompletion(buf)
assertNoErr(t, rootCmd.GenBashCompletion(buf))
output := buf.String()

check(t, output, "_root")
Expand Down Expand Up @@ -216,10 +217,10 @@ func TestBashCompletionHiddenFlag(t *testing.T) {

const flagName = "hiddenFlag"
c.Flags().Bool(flagName, false, "")
c.Flags().MarkHidden(flagName)
assertNoErr(t, c.Flags().MarkHidden(flagName))

buf := new(bytes.Buffer)
c.GenBashCompletion(buf)
assertNoErr(t, c.GenBashCompletion(buf))
output := buf.String()

if strings.Contains(output, flagName) {
Expand All @@ -232,10 +233,10 @@ func TestBashCompletionDeprecatedFlag(t *testing.T) {

const flagName = "deprecated-flag"
c.Flags().Bool(flagName, false, "")
c.Flags().MarkDeprecated(flagName, "use --not-deprecated instead")
assertNoErr(t, c.Flags().MarkDeprecated(flagName, "use --not-deprecated instead"))

buf := new(bytes.Buffer)
c.GenBashCompletion(buf)
assertNoErr(t, c.GenBashCompletion(buf))
output := buf.String()

if strings.Contains(output, flagName) {
Expand All @@ -250,7 +251,7 @@ func TestBashCompletionTraverseChildren(t *testing.T) {
c.Flags().BoolP("bool-flag", "b", false, "bool flag")

buf := new(bytes.Buffer)
c.GenBashCompletion(buf)
assertNoErr(t, c.GenBashCompletion(buf))
output := buf.String()

// check that local nonpersistent flag are not set since we have TraverseChildren set to true
Expand Down