Add soft & hard linter configs & workflows (#44)

* chore: add linter configs & workflows

* fix: ignore certain linter warnings

* fix: mark errors as intentionally ignored

* fix: avoid unnecessary conversion

* fix: handle template/renderer errors

* fix: mark intentionally unused code
This commit is contained in:
Christian Muehlhaeuser 2022-07-30 18:32:59 +02:00 committed by GitHub
parent e4fc0c2e74
commit 66993d8ef1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 181 additions and 48 deletions

28
.github/workflows/lint-soft.yml vendored Normal file
View File

@ -0,0 +1,28 @@
name: lint-soft
on:
push:
pull_request:
permissions:
contents: read
# Optional: allow read access to pull request. Use with `only-new-issues` option.
pull-requests: read
jobs:
golangci:
name: lint-soft
runs-on: ubuntu-latest
steps:
- name: Install Go
uses: actions/setup-go@v3
with:
go-version: ^1
- uses: actions/checkout@v3
- name: golangci-lint
uses: golangci/golangci-lint-action@v3
with:
# Optional: golangci-lint command line arguments.
args: --config .golangci-soft.yml --issues-exit-code=0
# Optional: show only new issues if it's a pull request. The default value is `false`.
only-new-issues: true

28
.github/workflows/lint.yml vendored Normal file
View File

@ -0,0 +1,28 @@
name: lint
on:
push:
pull_request:
permissions:
contents: read
# Optional: allow read access to pull request. Use with `only-new-issues` option.
pull-requests: read
jobs:
golangci:
name: lint
runs-on: ubuntu-latest
steps:
- name: Install Go
uses: actions/setup-go@v3
with:
go-version: ^1
- uses: actions/checkout@v3
- name: golangci-lint
uses: golangci/golangci-lint-action@v3
with:
# Optional: golangci-lint command line arguments.
#args:
# Optional: show only new issues if it's a pull request. The default value is `false`.
only-new-issues: true

47
.golangci-soft.yml Normal file
View File

@ -0,0 +1,47 @@
run:
tests: false
issues:
include:
- EXC0001
- EXC0005
- EXC0011
- EXC0012
- EXC0013
max-issues-per-linter: 0
max-same-issues: 0
linters:
enable:
# - dupl
- exhaustive
# - exhaustivestruct
- goconst
- godot
- godox
- gomnd
- gomoddirectives
- goprintffuncname
- ifshort
# - lll
- misspell
- nakedret
- nestif
- noctx
- nolintlint
- prealloc
- wrapcheck
# disable default linters, they are already enabled in .golangci.yml
disable:
- deadcode
- errcheck
- gosimple
- govet
- ineffassign
- staticcheck
- structcheck
- typecheck
- unused
- varcheck

29
.golangci.yml Normal file
View File

@ -0,0 +1,29 @@
run:
tests: false
issues:
include:
- EXC0001
- EXC0005
- EXC0011
- EXC0012
- EXC0013
max-issues-per-linter: 0
max-same-issues: 0
linters:
enable:
- bodyclose
- exportloopref
- goimports
- gosec
- nilerr
- predeclared
- revive
- rowserrcheck
- sqlclosecheck
- tparallel
- unconvert
- unparam
- whitespace

View File

@ -139,6 +139,7 @@ func (m model) View() string {
return s.String()
}
//nolint:unparam
func clamp(x, min, max int) int {
if x < min {
return min

View File

@ -3,6 +3,7 @@ package choose
import "github.com/charmbracelet/gum/style"
// Options is the customization options for the choose command.
// nolint:staticcheck
type Options struct {
Options []string `arg:"" optional:"" help:"Options to choose from."`

View File

@ -1,4 +1,3 @@
// TODO implement our own gum bash completion
package completion
import (
@ -59,7 +58,7 @@ const (
// All directives using iota should be above this one.
// For internal use.
shellCompDirectiveMaxValue
shellCompDirectiveMaxValue //nolint:deadcode,unused,varcheck
// ShellCompDirectiveDefault indicates to let the shell perform its default
// behavior after completions have been provided.
@ -576,6 +575,7 @@ func writeFlag(buf io.StringWriter, flag *kong.Flag, cmd *kong.Node) {
writeFlagHandler(buf, "--"+name, map[string][]string{}, cmd)
}
//nolint:deadcode,unused
func writeLocalNonPersistentFlag(buf io.StringWriter, flag *kong.Flag) {
name := flag.Name
format := " local_nonpersistent_flags+=(\"--%[1]s" + cbn

View File

@ -9,6 +9,7 @@ import (
"github.com/alecthomas/kong"
)
// Completion command.
type Completion struct {
Bash Bash `cmd:"" help:"Generate the autocompletion script for bash"`
Zsh Zsh `cmd:"" help:"Generate the autocompletion script for zsh"`
@ -31,6 +32,7 @@ func hasCommands(cmd *kong.Node) bool {
return false
}
//nolint:deadcode,unused
func isArgument(cmd *kong.Node) bool {
return cmd.Type == kong.ArgumentNode
}

View File

@ -34,10 +34,10 @@ func (f Fish) gen(buf io.StringWriter, cmd *kong.Node) {
}
rootName := root.Name
if cmd.Parent == nil {
buf.WriteString(fmt.Sprintf("# %s\n", rootName))
_, _ = buf.WriteString(fmt.Sprintf("# %s\n", rootName))
} else {
buf.WriteString(fmt.Sprintf("# %s\n", cmd.Path()))
buf.WriteString(
_, _ = buf.WriteString(fmt.Sprintf("# %s\n", cmd.Path()))
_, _ = buf.WriteString(
fmt.Sprintf("complete -c %s -f -n '__fish_use_subcommand' -a %s -d '%s'\n",
rootName,
cmd.Name,
@ -51,13 +51,13 @@ func (f Fish) gen(buf io.StringWriter, cmd *kong.Node) {
continue
}
if cmd.Parent == nil {
buf.WriteString(
_, _ = buf.WriteString(
fmt.Sprintf("complete -c %s -f",
rootName,
),
)
} else {
buf.WriteString(
_, _ = buf.WriteString(
fmt.Sprintf("complete -c %s -f -n '__fish_seen_subcommand_from %s'",
rootName,
cmd.Name,
@ -67,19 +67,19 @@ func (f Fish) gen(buf io.StringWriter, cmd *kong.Node) {
if !f.IsBool() {
enums := flagPossibleValues(f)
if len(enums) > 0 {
buf.WriteString(fmt.Sprintf(" -xa '%s'", strings.Join(enums, " ")))
_, _ = buf.WriteString(fmt.Sprintf(" -xa '%s'", strings.Join(enums, " ")))
} else {
buf.WriteString(" -x")
_, _ = buf.WriteString(" -x")
}
}
if f.Short != 0 {
buf.WriteString(fmt.Sprintf(" -s %c", f.Short))
_, _ = buf.WriteString(fmt.Sprintf(" -s %c", f.Short))
}
buf.WriteString(fmt.Sprintf(" -l %s", f.Name))
buf.WriteString(fmt.Sprintf(" -d '%s'", f.Help))
buf.WriteString("\n")
_, _ = buf.WriteString(fmt.Sprintf(" -l %s", f.Name))
_, _ = buf.WriteString(fmt.Sprintf(" -d '%s'", f.Help))
_, _ = buf.WriteString("\n")
}
buf.WriteString("\n")
_, _ = buf.WriteString("\n")
for _, c := range cmd.Children {
if c == nil || c.Hidden {

View File

@ -93,7 +93,7 @@ func (z Zsh) writeCommands(buf io.StringWriter, cmd *kong.Node) {
}
z.writeCommand(buf, c)
if i < len(cmd.Children)-1 {
buf.WriteString(" \\")
_, _ = buf.WriteString(" \\")
}
writeString(buf, "\n")
}

View File

@ -3,6 +3,7 @@ package confirm
import "github.com/charmbracelet/gum/style"
// Options is the customization options for the confirm command.
// nolint:staticcheck
type Options struct {
Affirmative string `help:"The title of the affirmative action" default:"Yes"`
Negative string `help:"The title of the negative action" default:"No"`

View File

@ -27,7 +27,7 @@ func (o Options) Run() error {
input, _ := stdin.Read()
var choices []string
if input != "" {
choices = strings.Split(string(input), "\n")
choices = strings.Split(input, "\n")
} else {
choices = files.List()
}

View File

@ -45,7 +45,6 @@ func (m model) View() string {
// Since there are matches, display them so that the user can see, in real
// time, what they are searching for.
for i, match := range m.matches {
// If this is the current selected index, we add a small indicator to
// represent it. Otherwise, simply pad the string.
if i == m.selected {

View File

@ -3,6 +3,7 @@ package filter
import "github.com/charmbracelet/gum/style"
// Options is the customization options for the filter command.
// nolint:staticcheck
type Options struct {
Indicator string `help:"Character for selection" default:"•"`
IndicatorStyle style.Styles `embed:"" prefix:"indicator." set:"defaultForeground=212" set:"name=indicator"`

View File

@ -19,7 +19,7 @@ import (
)
// Func is a function that formats some text
type Func func(string) string
type Func func(string) (string, error)
var formatType = map[string]Func{
"code": code,
@ -37,6 +37,11 @@ func (o Options) Run() error {
input, _ = stdin.Read()
}
fmt.Println(formatType[o.Type](input))
v, err := formatType[o.Type](input)
if err != nil {
return err
}
fmt.Println(v)
return nil
}

View File

@ -9,57 +9,46 @@ import (
"github.com/muesli/termenv"
)
var code Func = func(input string) string {
var code Func = func(input string) (string, error) {
renderer, err := glamour.NewTermRenderer(
glamour.WithAutoStyle(),
glamour.WithWordWrap(0),
)
if err != nil {
return ""
return "", err
}
out, err := renderer.Render(fmt.Sprintf("```\n%s\n```", input))
if err != nil {
return ""
}
return out
return renderer.Render(fmt.Sprintf("```\n%s\n```", input))
}
var emoji Func = func(input string) string {
var emoji Func = func(input string) (string, error) {
renderer, err := glamour.NewTermRenderer(
glamour.WithEmoji(),
)
if err != nil {
return ""
return "", err
}
out, err := renderer.Render(input)
if err != nil {
return ""
}
return out
return renderer.Render(input)
}
var markdown Func = func(input string) string {
var markdown Func = func(input string) (string, error) {
renderer, err := glamour.NewTermRenderer(
glamour.WithStandardStyle("pink"),
glamour.WithWordWrap(0),
)
if err != nil {
return ""
return "", err
}
out, err := renderer.Render(input)
if err != nil {
return ""
}
return out
return renderer.Render(input)
}
var template Func = func(input string) string {
var template Func = func(input string) (string, error) {
f := termenv.TemplateFuncs(termenv.ColorProfile())
t, err := tpl.New("tpl").Funcs(f).Parse(input)
if err != nil {
return ""
return "", err
}
var buf bytes.Buffer
t.Execute(&buf, nil)
return buf.String()
err = t.Execute(&buf, nil)
return buf.String(), err
}

View File

@ -3,6 +3,7 @@ package input
import "github.com/charmbracelet/gum/style"
// Options are the customization options for the input.
// nolint:staticcheck
type Options struct {
Placeholder string `help:"Placeholder value" default:"Type something..."`
Prompt string `help:"Prompt to display" default:"> "`

View File

@ -13,7 +13,7 @@ func List() []string {
err := filepath.Walk(".",
func(path string, info os.FileInfo, err error) error {
if shouldIgnore(path) || info.IsDir() || err != nil {
return nil
return nil //nolint:nilerr
}
files = append(files, path)
return nil
@ -23,7 +23,6 @@ func List() []string {
return []string{}
}
return files
}
var defaultIgnorePatterns = []string{"node_modules", ".git", "."}

View File

@ -54,5 +54,5 @@ func main() {
"defaultUnderline": "false",
},
)
ctx.Run()
_ = ctx.Run()
}

View File

@ -3,6 +3,7 @@ package spin
import "github.com/charmbracelet/gum/style"
// Options is the customization options for the spin command.
// nolint:staticcheck
type Options struct {
Command []string `arg:"" help:"Command to run"`

View File

@ -36,7 +36,7 @@ func commandStart(command []string) tea.Cmd {
if len(command) > 1 {
args = command[1:]
}
out, _ := exec.Command(command[0], args...).Output()
out, _ := exec.Command(command[0], args...).Output() //nolint:gosec
return finishCommandMsg{output: string(out)}
}
}

View File

@ -3,6 +3,7 @@ package write
import "github.com/charmbracelet/gum/style"
// Options are the customization options for the textarea.
// nolint:staticcheck
type Options struct {
Width int `help:"Text area width" default:"50"`
Height int `help:"Text area height" default:"5"`