Skip to content

Commit de73844

Browse files
committed
fix: exit code dispatch was dead code — logger.Error called Fatalf before ExitCodeFor
Three bugs found by five-agent swarm review: 1. main.go: logger.Error() calls log.Fatalf() which exits 1 immediately, making os.Exit(ExitCodeFor(err)) unreachable dead code. Replaced with fmt.Fprintf to stderr so the differentiated exit code actually takes effect. Same fix in innerMain for the unknown-subcommand path. 2. requests.go: HTTP 5xx responses were returned as plain fmt.Errorf, falling through to exit 1. Now wrapped as ErrServer (exit 2). 3. docs.go/testHelpers/etc: import ordering and alignment (gofmt).
1 parent 262c54e commit de73844

9 files changed

Lines changed: 28 additions & 25 deletions

File tree

cmd/kosli/assertPRAzure.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ import (
44
"fmt"
55
"io"
66

7-
kosliErrors "github.com/kosli-dev/cli/internal/errors"
87
azUtils "github.com/kosli-dev/cli/internal/azure"
8+
kosliErrors "github.com/kosli-dev/cli/internal/errors"
99
"github.com/spf13/cobra"
1010
)
1111

cmd/kosli/assertPRBitbucket.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ import (
44
"fmt"
55
"io"
66

7-
kosliErrors "github.com/kosli-dev/cli/internal/errors"
87
bbUtils "github.com/kosli-dev/cli/internal/bitbucket"
8+
kosliErrors "github.com/kosli-dev/cli/internal/errors"
99
"github.com/spf13/cobra"
1010
)
1111

cmd/kosli/docs.go

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -67,27 +67,27 @@ var (
6767
// Commands not in this map receive exitCodesDefault.
6868
var commandExitCodes = map[string][]docgen.ExitCodeEntry{
6969
// assert commands — can signal compliance violations
70-
"kosli assert artifact": exitCodesAssert,
71-
"kosli assert approval": exitCodesAssert,
72-
"kosli assert snapshot": exitCodesAssert,
73-
"kosli assert pullrequest github": exitCodesAssert,
74-
"kosli assert pullrequest gitlab": exitCodesAssert,
75-
"kosli assert pullrequest azure": exitCodesAssert,
70+
"kosli assert artifact": exitCodesAssert,
71+
"kosli assert approval": exitCodesAssert,
72+
"kosli assert snapshot": exitCodesAssert,
73+
"kosli assert pullrequest github": exitCodesAssert,
74+
"kosli assert pullrequest gitlab": exitCodesAssert,
75+
"kosli assert pullrequest azure": exitCodesAssert,
7676
"kosli assert pullrequest bitbucket": exitCodesAssert,
77-
"kosli assert status": exitCodesAssertStatus,
77+
"kosli assert status": exitCodesAssertStatus,
7878
// attest commands with --assert flag — can signal compliance violations when --assert is used
7979
"kosli attest pullrequest github": exitCodesAttest,
8080
"kosli attest pullrequest gitlab": exitCodesAttest,
8181
"kosli attest pullrequest azure": exitCodesAttest,
8282
"kosli attest pullrequest bitbucket": exitCodesAttest,
8383
"kosli attest jira": exitCodesAttest,
8484
// evaluate commands — policy denial exits with code 1
85-
"kosli evaluate trail": exitCodesEvaluate,
86-
"kosli evaluate trails": exitCodesEvaluate,
85+
"kosli evaluate trail": exitCodesEvaluate,
86+
"kosli evaluate trails": exitCodesEvaluate,
8787
// non-API commands
88-
"kosli version": exitCodesNoAPI,
89-
"kosli completion": exitCodesNoAPI,
90-
"kosli docs": exitCodesNoAPI,
88+
"kosli version": exitCodesNoAPI,
89+
"kosli completion": exitCodesNoAPI,
90+
"kosli docs": exitCodesNoAPI,
9191
}
9292

9393
const docsShortDesc = `Generate documentation files for Kosli CLI. `

cmd/kosli/evaluateHelpers.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ import (
88
"net/url"
99
"os"
1010

11-
"github.com/kosli-dev/cli/internal/evaluate"
1211
kosliErrors "github.com/kosli-dev/cli/internal/errors"
12+
"github.com/kosli-dev/cli/internal/evaluate"
1313
"github.com/kosli-dev/cli/internal/output"
1414
"github.com/kosli-dev/cli/internal/requests"
1515
"github.com/spf13/cobra"

cmd/kosli/main.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ func main() {
3737
}
3838
}
3939
if err != nil {
40-
logger.Error(err.Error())
40+
fmt.Fprintf(os.Stderr, "Error: %s\n", err.Error())
4141
os.Exit(kosliErrors.ExitCodeFor(err))
4242
}
4343
}
@@ -68,7 +68,7 @@ func innerMain(cmd *cobra.Command, args []string) error {
6868
availableSubcommands = append(availableSubcommands, strings.Split(sc.Use, " ")[0])
6969
}
7070
}
71-
logger.Error("%s\navailable subcommands are: %s", errMessage, strings.Join(availableSubcommands, " | "))
71+
fmt.Fprintf(os.Stderr, "Error: %s\navailable subcommands are: %s\n", errMessage, strings.Join(availableSubcommands, " | "))
7272
}
7373
return kosliErrors.NewErrUsage(err.Error())
7474
}

cmd/kosli/snapshotK8S_test.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,9 @@ func (suite *SnapshotK8STestSuite) TestSnapshotK8SCmd() {
8787
golden: "Error: failed to read config file '/nonexistent/path.yaml': open /nonexistent/path.yaml: no such file or directory\n",
8888
},
8989
{
90-
wantError: true,
91-
name: "snapshot K8S fails if config file has invalid YAML",
92-
cmd: fmt.Sprintf(`snapshot k8s --config-file testdata/k8s-config/invalid-yaml.yaml %s`, suite.defaultKosliArguments),
90+
wantError: true,
91+
name: "snapshot K8S fails if config file has invalid YAML",
92+
cmd: fmt.Sprintf(`snapshot k8s --config-file testdata/k8s-config/invalid-yaml.yaml %s`, suite.defaultKosliArguments),
9393
goldenRegex: "Error: failed to parse config file.*",
9494
},
9595
{
@@ -117,9 +117,9 @@ func (suite *SnapshotK8STestSuite) TestSnapshotK8SCmd() {
117117
golden: "Error: invalid config for environment 'bad-env': cannot combine 'namespaces' with 'excludeNamespaces'\n",
118118
},
119119
{
120-
wantError: true,
121-
name: "snapshot K8S fails if config file has invalid regex",
122-
cmd: fmt.Sprintf(`snapshot k8s --config-file testdata/k8s-config/invalid-regex.yaml %s`, suite.defaultKosliArguments),
120+
wantError: true,
121+
name: "snapshot K8S fails if config file has invalid regex",
122+
cmd: fmt.Sprintf(`snapshot k8s --config-file testdata/k8s-config/invalid-regex.yaml %s`, suite.defaultKosliArguments),
123123
goldenRegex: `Error: invalid config for environment 'bad-regex-env': invalid regex '\[invalid'.*`,
124124
},
125125
}

cmd/kosli/testHelpers.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ import (
1111
"strings"
1212
"testing"
1313

14-
"github.com/kosli-dev/cli/internal/gitview"
1514
kosliErrors "github.com/kosli-dev/cli/internal/errors"
15+
"github.com/kosli-dev/cli/internal/gitview"
1616
shellwords "github.com/mattn/go-shellwords"
1717
"github.com/pkg/errors"
1818
"github.com/spf13/cobra"

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ require (
4343
github.com/zalando/go-keyring v0.2.6
4444
gitlab.com/gitlab-org/api/client-go v0.127.0
4545
golang.org/x/oauth2 v0.34.0
46+
gopkg.in/yaml.v3 v3.0.1
4647
k8s.io/api v0.35.0
4748
k8s.io/apimachinery v0.35.0
4849
k8s.io/client-go v1.5.2
@@ -223,7 +224,6 @@ require (
223224
gopkg.in/inf.v0 v0.9.1 // indirect
224225
gopkg.in/ini.v1 v1.67.1 // indirect
225226
gopkg.in/warnings.v0 v0.1.2 // indirect
226-
gopkg.in/yaml.v3 v3.0.1 // indirect
227227
k8s.io/apiextensions-apiserver v0.0.0 // indirect
228228
k8s.io/apiserver v0.35.0 // indirect
229229
k8s.io/component-base v0.35.0 // indirect

internal/requests/requests.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,9 @@ func (c *Client) Do(p *RequestParams) (*HTTPResponse, error) {
290290
cleanedErrorMessage = fmt.Sprintf("%s", respBodyMap)
291291
}
292292
}
293+
if resp.StatusCode >= 500 {
294+
return nil, kosliErrors.NewErrServer(cleanedErrorMessage)
295+
}
293296
if resp.StatusCode == 401 || resp.StatusCode == 403 {
294297
return nil, kosliErrors.NewErrConfig(cleanedErrorMessage)
295298
}

0 commit comments

Comments
 (0)