Skip to content

Commit e253035

Browse files
committed
Update linter
1 parent 39e2110 commit e253035

File tree

12 files changed

+116
-67
lines changed

12 files changed

+116
-67
lines changed

.golangci.yml

+27-11
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
# schema: https://golangci-lint.run/jsonschema/golangci.jsonschema.json
2+
13
issues:
24
exclude-rules:
35
- path: cmd/
@@ -9,7 +11,7 @@ linters:
911
presets:
1012
- bugs
1113
- comment
12-
# - complexity # limits cyclomatic complexity—typically results in hard-to-follow code
14+
- complexity
1315
- error
1416
- format
1517
- import
@@ -23,17 +25,31 @@ linters:
2325

2426
disable:
2527
- depguard # enforces dependency allow list; not using allow list
26-
- paralleltest # not enough tests to matter; not helpful
2728

2829
# annoying/bad
29-
- exhaustruct # enforces exhaustive structs; often incorrect; bad
30-
- goerr113 # disallows returning one-off errors; annoying
30+
- err113 # disallows returning one-off errors; annoying
3131
- gofumpt # different code formatter; bad
32-
- gomnd # disallows magic numbers; annoying
33-
- ireturn # bans returning interfaces; often incorrect; bad
34-
- lll # limits line length; annoying
3532
- nlreturn # requires blank line before return; annoying
36-
- nonamedreturns # disallows named returns; often required for defer error checking; bad
37-
- tagliatelle # enforces tag name style; often incorrect; bad
38-
- varnamelen # limits variable name length; annoying
39-
- wsl # tedious whitespace rules; annoying
33+
- varnamelen # limits variable name length; too many false positives
34+
- wsl # whitespace/cuddle rules; tedious
35+
36+
linters-settings:
37+
cyclop:
38+
max-complexity: 30
39+
40+
exhaustruct:
41+
exclude:
42+
- "^github.com/jclem/konk/konk.Command$"
43+
- "^github.com/jclem/konk/konk.CommandConfig$"
44+
- "^github.com/jclem/konk/konk.RunCommandConfig$"
45+
- "^github.com/jclem/konk/konk.ShellCommandConfig$"
46+
- "^github.com/jclem/konk/konk.RunConcurrentlyConfig$"
47+
- "^github.com/spf13/cobra.Command$"
48+
49+
funlen:
50+
lines: 100
51+
ignore-comments: true
52+
53+
mnd:
54+
ignored-functions:
55+
- strings.SplitN

cmd/proc.go

+4-2
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,10 @@ var procCommand = cobra.Command{
108108
}
109109

110110
func init() {
111-
procCommand.Flags().StringVarP(&workingDirectory, "working-directory", "w", "", "set the working directory for all commands")
112-
procCommand.Flags().BoolVarP(&continueOnError, "continue-on-error", "c", false, "continue running commands after a failure")
111+
procCommand.Flags().StringVarP(&workingDirectory,
112+
"working-directory", "w", "", "set the working directory for all commands")
113+
procCommand.Flags().BoolVarP(&continueOnError,
114+
"continue-on-error", "c", false, "continue running commands after a failure")
113115
procCommand.Flags().BoolVarP(&noShell, "no-subshell", "S", false, "do not run commands in a subshell")
114116
procCommand.Flags().BoolVarP(&noColor, "no-color", "C", false, "do not colorize label output")
115117

cmd/run.go

+58-30
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package cmd
22

33
import (
44
"encoding/json"
5-
"errors"
65
"fmt"
76
"os"
87
"sort"
@@ -29,8 +28,10 @@ var runCommand = cobra.Command{
2928
}
3029

3130
func init() {
32-
runCommand.PersistentFlags().StringVarP(&workingDirectory, "working-directory", "w", "", "set the working directory for all commands")
33-
runCommand.PersistentFlags().BoolVarP(&continueOnError, "continue-on-error", "c", false, "continue running commands after a failure")
31+
runCommand.PersistentFlags().StringVarP(&workingDirectory,
32+
"working-directory", "w", "", "set the working directory for all commands")
33+
runCommand.PersistentFlags().BoolVarP(&continueOnError,
34+
"continue-on-error", "c", false, "continue running commands after a failure")
3435
runCommand.PersistentFlags().BoolVarP(&noShell, "no-subshell", "S", false, "do not run commands in a subshell")
3536
runCommand.PersistentFlags().BoolVarP(&noColor, "no-color", "C", false, "do not colorize label output")
3637

@@ -43,60 +44,87 @@ func init() {
4344
}
4445

4546
func collectCommands(args []string) ([]string, []string, error) {
46-
commandStrings := []string{}
47-
commands := []string{}
47+
// The commands as provided by the user
48+
providedCommands := []string{}
49+
50+
// "Resolved" commands (e.g. prefixed with "bun run", etc.)
51+
runnableCommands := []string{}
4852

4953
for _, cmd := range args {
50-
commandStrings = append(commandStrings, cmd)
51-
commands = append(commands, cmd)
54+
providedCommands = append(providedCommands, cmd)
55+
runnableCommands = append(runnableCommands, cmd)
56+
}
57+
58+
var scripts []string
59+
60+
if len(npmCmds) > 0 {
61+
var err error
62+
scripts, err = getPackageJSONScripts()
63+
if err != nil {
64+
return nil, nil, err
65+
}
5266
}
5367

5468
for _, cmd := range npmCmds {
5569
if strings.HasSuffix(cmd, "*") {
5670
prefix := strings.TrimSuffix(cmd, "*")
57-
pkgFile, err := os.ReadFile("package.json")
58-
if err != nil {
59-
return nil, nil, fmt.Errorf("reading package.json: %w", err)
60-
}
61-
var pkg map[string]any
62-
if err := json.Unmarshal(pkgFile, &pkg); err != nil {
63-
return nil, nil, fmt.Errorf("unmarshalling package.json: %w", err)
64-
}
6571

6672
// See if any "scripts" match our prefix
6773
matchingScripts := []string{}
6874

69-
scripts, ok := pkg["scripts"].(map[string]any)
70-
if !ok {
71-
return nil, nil, errors.New("invalid scripts in package.json")
72-
}
73-
74-
for script := range scripts {
75+
for _, script := range scripts {
7576
if strings.HasPrefix(script, prefix) {
7677
matchingScripts = append(matchingScripts, script)
7778
}
7879
}
7980

80-
sort.Strings(matchingScripts)
81-
8281
for _, script := range matchingScripts {
83-
commandStrings = append(commandStrings, script)
82+
providedCommands = append(providedCommands, script)
83+
8484
if runWithBun {
85-
commands = append(commands, "bun run "+script)
85+
runnableCommands = append(runnableCommands, "bun run "+script)
8686
} else {
87-
commands = append(commands, "npm run "+script)
87+
runnableCommands = append(runnableCommands, "npm run "+script)
8888
}
8989
}
9090

9191
continue
9292
}
9393

94-
script := "npm run " + cmd
95-
commandStrings = append(commandStrings, cmd)
96-
commands = append(commands, script)
94+
providedCommands = append(providedCommands, cmd)
95+
96+
if runWithBun {
97+
runnableCommands = append(runnableCommands, "bun run "+cmd)
98+
} else {
99+
runnableCommands = append(runnableCommands, "npm run "+cmd)
100+
}
101+
}
102+
103+
return providedCommands, runnableCommands, nil
104+
}
105+
106+
func getPackageJSONScripts() ([]string, error) {
107+
pkgFile, err := os.ReadFile("package.json")
108+
if err != nil {
109+
return nil, fmt.Errorf("reading package.json: %w", err)
110+
}
111+
112+
var pkgJSON struct {
113+
Scripts map[string]string `json:"scripts"`
114+
}
115+
116+
if err := json.Unmarshal(pkgFile, &pkgJSON); err != nil {
117+
return nil, fmt.Errorf("unmarshalling package.json: %w", err)
97118
}
98119

99-
return commandStrings, commands, nil
120+
scripts := make([]string, 0, len(pkgJSON.Scripts))
121+
for script := range pkgJSON.Scripts {
122+
scripts = append(scripts, script)
123+
}
124+
125+
sort.Strings(scripts)
126+
127+
return scripts, nil
100128
}
101129

102130
func collectLabels(commandStrings []string) []string {

go.mod

+3-7
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
11
module github.com/jclem/konk
22

3-
go 1.18
3+
go 1.23
44

5-
require (
6-
github.com/spf13/cobra v1.4.0
7-
gopkg.in/yaml.v3 v3.0.1
8-
)
5+
require github.com/spf13/cobra v1.4.0
96

107
require (
118
github.com/davecgh/go-spew v1.1.1 // indirect
@@ -19,16 +16,15 @@ require (
1916
github.com/rivo/uniseg v0.2.0 // indirect
2017
github.com/rogpeppe/go-internal v1.6.1 // indirect
2118
golang.org/x/sys v0.1.0 // indirect
19+
gopkg.in/yaml.v3 v3.0.1 // indirect
2220
)
2321

2422
require (
25-
github.com/BurntSushi/toml v1.3.2
2623
github.com/charmbracelet/lipgloss v0.5.0
2724
github.com/inconshreveable/mousetrap v1.0.0 // indirect
2825
github.com/kr/pretty v0.3.0
2926
github.com/mattn/go-shellwords v1.0.12
3027
github.com/spf13/pflag v1.0.5 // indirect
3128
github.com/stretchr/testify v1.8.0
32-
golang.org/x/exp v0.0.0-20240318143956-a85f2c67cd81
3329
golang.org/x/sync v0.0.0-20220513210516-0976fa681c29
3430
)

go.sum

-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8=
2-
github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
31
github.com/charmbracelet/lipgloss v0.5.0 h1:lulQHuVeodSgDez+3rGiuxlPVXSnhth442DATR2/8t8=
42
github.com/charmbracelet/lipgloss v0.5.0/go.mod h1:EZLha/HbzEt7cYqdFPovlqy5FZPj0xFhg5SaqxScmgs=
53
github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
@@ -46,8 +44,6 @@ github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSS
4644
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
4745
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
4846
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
49-
golang.org/x/exp v0.0.0-20240318143956-a85f2c67cd81 h1:6R2FC06FonbXQ8pK11/PDFY6N6LWlf9KlzibaCapmqc=
50-
golang.org/x/exp v0.0.0-20240318143956-a85f2c67cd81/go.mod h1:CQ1k9gNrJ50XIzaKCRR2hssIjF07kZFEiieALBM/ARQ=
5147
golang.org/x/sync v0.0.0-20220513210516-0976fa681c29 h1:w8s32wxx3sY+OjLlv9qltkLU5yvJzxjjgiHWLjdIcw4=
5248
golang.org/x/sync v0.0.0-20220513210516-0976fa681c29/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
5349
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=

integration/helpers.go

+5-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,11 @@ type runner struct {
1414
}
1515

1616
func newRunner(cmd string) runner {
17-
return runner{cmd: cmd}
17+
return runner{
18+
cmd: cmd,
19+
flags: make([]string, 0),
20+
env: make([]string, 0),
21+
}
1822
}
1923

2024
func (r runner) withFlags(flags ...string) runner {

integration/run_c_test.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,11 @@ func TestRunConcurrentlyWithLabelsMismatch(t *testing.T) {
4747
"echo a", "echo b", "echo c").
4848
run(t)
4949

50-
if assert.Error(t, err) {
51-
assert.IsType(t, &exec.ExitError{}, err)
52-
}
50+
assert.IsType(t, &exec.ExitError{}, err) //nolint:exhaustruct
5351

54-
assert.Equal(t, "Error: number of names must match number of commands\n", out, "error output did not match expectation")
52+
assert.Equal(t,
53+
"Error: number of names must match number of commands\n", out,
54+
"error output did not match expectation")
5555
}
5656

5757
func TestRunConcurrentlyWithCommandLabels(t *testing.T) {

integration/run_s_test.go

+4-2
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,12 @@ func TestRunSeriallyWithLabelsMismatch(t *testing.T) {
4646
run(t)
4747

4848
if assert.Error(t, err) {
49-
assert.IsType(t, &exec.ExitError{}, err)
49+
assert.IsType(t, &exec.ExitError{}, err) //nolint:exhaustruct
5050
}
5151

52-
assert.Equal(t, "Error: number of names must match number of commands\n", out, "error output did not match expectation")
52+
assert.Equal(t,
53+
"Error: number of names must match number of commands\n", out,
54+
"error output did not match expectation")
5355
}
5456

5557
func TestRunSeriallyWithCommandLabels(t *testing.T) {

konk/command.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,8 @@ func newExitError(label string, err error) error {
182182
}
183183
}
184184

185+
const colors = 16
186+
185187
func getPrefix(label string, noColor bool) string {
186188
if label == "" {
187189
return ""
@@ -192,7 +194,7 @@ func getPrefix(label string, noColor bool) string {
192194
if noColor {
193195
prefix = fmt.Sprintf("[%s]", label)
194196
} else {
195-
prefixColor := rand.Intn(16) + 1 //nolint:gosec // No need for cryptographic randomness for process labels.
197+
prefixColor := rand.Intn(colors) + 1 //nolint:gosec // No need for strong rand here.
196198
prefixStyle := lipgloss.NewStyle().Foreground(lipgloss.Color(strconv.Itoa(prefixColor)))
197199
prefix = prefixStyle.Render(fmt.Sprintf("[%s]", label))
198200
}

konk/debugger/debugger.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,15 @@ import (
99
"github.com/spf13/cobra"
1010
)
1111

12-
var contextKey = struct{}{} //nolint:gochecknoglobals // we want to use a global key
12+
type contextKey struct{}
1313

1414
type Debugger struct {
1515
debug *bool
1616
}
1717

1818
func WithDebugger(ctx context.Context, debug *bool) context.Context {
1919
dbg := Debugger{debug}
20-
return context.WithValue(ctx, contextKey, &dbg)
20+
return context.WithValue(ctx, contextKey{}, &dbg)
2121
}
2222

2323
func (d *Debugger) Debugf(format string, args ...interface{}) {
@@ -39,7 +39,7 @@ func (d *Debugger) Prettyln(arg ...interface{}) {
3939
}
4040

4141
func Get(ctx context.Context) *Debugger {
42-
dbg, ok := ctx.Value(contextKey).(*Debugger)
42+
dbg, ok := ctx.Value(contextKey{}).(*Debugger)
4343
if !ok {
4444
panic("no debugger in context")
4545
}

konk/run.go

-2
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,6 @@ func RunConcurrently(ctx context.Context, cfg RunConcurrentlyConfig) ([]*Command
6565
}
6666

6767
for _, cmd := range commands {
68-
cmd := cmd
69-
7068
eg.Go(func() error {
7169
return cmd.Run(ctx, cancel, RunCommandConfig{
7270
AggregateOutput: cfg.AggregateOutput,

script/lint

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#!/usr/bin/env bash
2+
3+
set -eu
4+
5+
golangci-lint run

0 commit comments

Comments
 (0)