mirror of https://github.com/charmbracelet/gum
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:
parent
e4fc0c2e74
commit
66993d8ef1
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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."`
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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")
|
||||
}
|
||||
|
|
|
@ -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"`
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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"`
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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:"> "`
|
||||
|
|
|
@ -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", "."}
|
||||
|
|
2
main.go
2
main.go
|
@ -54,5 +54,5 @@ func main() {
|
|||
"defaultUnderline": "false",
|
||||
},
|
||||
)
|
||||
ctx.Run()
|
||||
_ = ctx.Run()
|
||||
}
|
||||
|
|
|
@ -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"`
|
||||
|
||||
|
|
|
@ -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)}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"`
|
||||
|
|
Loading…
Reference in New Issue