feat(credential-helper): add error code and host to error responses
Description
glab auth credential-helper error responses only had type and message, so callers had to match the message text to know what failed. Now error responses also have:
code: one ofnot_authenticated,unsupported_auth_source,refresh_failed,keyring_unavailable,invalid_repo_override, orunknown. The list is in the command's--helptext.host: the GitLab host of the repository glab resolved, from the git remote or--repo. It is left out when glab cannot resolve a repository (no usable git remote and no--repo, or an invalid--repo).oauth_error: the OAuth2 error code, likeinvalid_grant, when the token refresh fails with an OAuth2 error response.
The message text is the same as before, including the keyring error messages.
The two "not logged in" errors (OAuth2 is configured but there is no token, and the token is missing from the keyring) also return not_authenticated. They keep their own message, which names the host to log in to.
I also made the test factory check --repo right away, like the real factory does, so the invalid_repo_override response can be tested.
I kept the exit codes as they are and documented them in the help text. Errors while reading the credentials exit with 0, and the error is in the JSON on stdout. An invalid --repo exits with 1. Which do you prefer?
- Keep the current exit codes, documented in the help text.
- Use the same exit code for both error paths.
Related Issues
Closes #8611
How has this been tested?
I built glab from main and from this branch, then ran the credential helper outside a git repository, with an empty config (temporary GLAB_CONFIG_DIR and HOME, no token in the environment).
On main:
$ ./glab-main auth credential-helper -R https://gitlab.example.com/group/project
{"type":"error","message":"glab is not authenticated. Use glab auth login to authenticate"}
$ echo $?
0
$ ./glab-main auth credential-helper -R not-a-valid-repo
{"type":"error","message":"expected the \"[HOST/]OWNER/[NAMESPACE/]REPO\" format, got \"not-a-valid-repo\""}
$ echo $?
1On this branch (the last command has no --repo, so there is no host):
$ ./glab-branch auth credential-helper -R https://gitlab.example.com/group/project
{"type":"error","code":"not_authenticated","host":"gitlab.example.com","message":"glab is not authenticated. Use glab auth login to authenticate"}
$ echo $?
0
$ ./glab-branch auth credential-helper -R not-a-valid-repo
{"type":"error","code":"invalid_repo_override","message":"expected the \"[HOST/]OWNER/[NAMESPACE/]REPO\" format, got \"not-a-valid-repo\""}
$ echo $?
1
$ ./glab-branch auth credential-helper
{"type":"error","code":"not_authenticated","message":"glab is not authenticated. Use glab auth login to authenticate"}
$ echo $?
0The unit tests now check every code, host and oauth_error, the two "not logged in" errors, and the full message text of keyring read and write failures. The two "not logged in" tests fail if I undo only the "not logged in" part of the change (they get unknown).
$ GOFLAGS=-p=2 go test -count=1 ./internal/commands/auth/credentialhelper/ ./internal/api/ ./internal/config/
ok gitlab.com/gitlab-org/cli/internal/commands/auth/credentialhelper 0.031s
ok gitlab.com/gitlab-org/cli/internal/api 0.142s
ok gitlab.com/gitlab-org/cli/internal/config 1.785sThe rest runs in the pipeline.
Implemented with AI assistance; I reviewed and tested the changes.