feat: distinct git:auth-status exit codes for netrc state

The `git:auth-status` command returned `1` both when a host had no `netrc` entry and when it had one that differed, so tooling wanting to tell a credential that would be created apart from one that would be replaced had to issue a second call with no username purely to find out which of the two it was. A host with no entry now exits `1`, a host whose entry differs from what was passed exits `2`, and invalid arguments exit `3`, leaving `0` to mean the stored state already matches. Called without a username the requested state is that no entry exists, so an existing entry is reported as `2` and `1` is never returned. Callers that only test zero versus non-zero are unaffected.
This commit is contained in:
Jose Diaz-Gonzalez
2026-09-02 18:07:19 -04:00
parent 37e898be58
commit 96521de322
3 changed files with 86 additions and 15 deletions

View File

@@ -204,7 +204,7 @@ echo "personal-access-token" | dokku git:auth github.com username
> [!IMPORTANT]
> New as of 0.38.0
The `git:auth-status` command reports whether the configured `netrc` entry matches a desired state without exposing the underlying file. It exits `0` when the configured state matches and `1` otherwise. This allows external tooling such as configuration management systems to perform idempotent updates without reading `$DOKKU_ROOT/.netrc` directly.
The `git:auth-status` command reports whether the configured `netrc` entry matches a desired state without exposing the underlying file. This allows external tooling such as configuration management systems to perform idempotent updates without reading `$DOKKU_ROOT/.netrc` directly.
```shell
# check whether github.com is configured with the expected credentials
@@ -214,6 +214,19 @@ dokku git:auth-status github.com username personal-access-token
dokku git:auth-status github.com
```
The result is reported via the exit code:
| Exit code | Description |
| --------- | ----------- |
| `0` | The configured `netrc` entry matches the requested state. |
| `1` | There is no `netrc` entry for the specified host. |
| `2` | There is a `netrc` entry for the specified host, but it does not match the requested state. |
| `3` | The command was called with invalid arguments and the state could not be checked. |
The distinction between `1` and `2` allows a caller to tell a host that needs a `netrc` entry created apart from a host whose existing credentials would be replaced, without issuing a second call.
When called without a username, the requested state is that no `netrc` entry exists for the host. An existing entry is therefore reported as `2`, and `1` is never returned.
As with `git:auth`, the password may be provided via `STDIN`:
```shell

View File

@@ -108,25 +108,30 @@ cmd-git-auth-status() {
declare desc="reports whether netrc authentication matches the requested state"
local cmd="git:auth-status"
[[ "$1" == "$cmd" ]] && shift 1
local exit_code_missing_entry=1 exit_code_differing_entry=2 exit_code_invalid_arguments=3
declare HOST="$1" USERNAME="$2" PASSWORD="$3"
[[ -z "$HOST" ]] && dokku_log_fail "Please supply a git host"
[[ -z "$HOST" ]] && DOKKU_FAIL_EXIT_CODE="$exit_code_invalid_arguments" dokku_log_fail "Please supply a git host"
PASSWORD="$(fn-git-auth-read-password "$USERNAME" "$PASSWORD")"
if [[ -n "$USERNAME" ]] && [[ -z "$PASSWORD" ]]; then
dokku_log_fail "Missing password for netrc auth entry"
DOKKU_FAIL_EXIT_CODE="$exit_code_invalid_arguments" dokku_log_fail "Missing password for netrc auth entry"
fi
local current
current="$(netrc get "$HOST" 2>/dev/null)" || current=""
if [[ -z "$current" ]]; then
[[ -z "$USERNAME" ]] && return 0
return "$exit_code_missing_entry"
fi
if [[ -z "$USERNAME" ]]; then
[[ -z "$current" ]] && return 0
return 1
return "$exit_code_differing_entry"
fi
[[ "$current" == "${USERNAME}:${PASSWORD}" ]] && return 0
return 1
return "$exit_code_differing_entry"
}
fn-git-auth-read-password() {

View File

@@ -185,12 +185,18 @@ teardown() {
run /bin/bash -c "dokku git:auth-status"
echo "output: $output"
echo "status: $status"
assert_failure
assert_exit_status 3
assert_output_contains "Please supply a git host"
run /bin/bash -c "dokku git:auth-status github.com"
echo "output: $output"
echo "status: $status"
assert_success
assert_exit_status 0
run /bin/bash -c "dokku git:auth-status github.com username password"
echo "output: $output"
echo "status: $status"
assert_exit_status 1
run /bin/bash -c "dokku git:auth github.com username password"
echo "output: $output"
@@ -200,38 +206,85 @@ teardown() {
run /bin/bash -c "dokku git:auth-status github.com"
echo "output: $output"
echo "status: $status"
assert_failure
assert_exit_status 2
run /bin/bash -c "dokku git:auth-status github.com username password"
echo "output: $output"
echo "status: $status"
assert_success
assert_exit_status 0
run /bin/bash -c "dokku git:auth-status github.com username wrong-password"
echo "output: $output"
echo "status: $status"
assert_failure
assert_exit_status 2
run /bin/bash -c "dokku git:auth-status github.com other-username password"
echo "output: $output"
echo "status: $status"
assert_failure
assert_exit_status 2
run /bin/bash -c "dokku git:auth-status github.com username"
echo "output: $output"
echo "status: $status"
assert_failure
assert_exit_status 3
assert_output_contains "Missing password for netrc auth entry"
run /bin/bash -c "printf 'password' | dokku git:auth-status github.com username"
echo "output: $output"
echo "status: $status"
assert_success
assert_exit_status 0
run /bin/bash -c "printf 'wrong-password' | dokku git:auth-status github.com username"
echo "output: $output"
echo "status: $status"
assert_failure
assert_exit_status 2
}
@test "(git:auth-status) distinguishes a missing entry from a differing entry" {
run /bin/bash -c "dokku git:auth auth-status.example.com"
echo "output: $output"
echo "status: $status"
assert_success
run /bin/bash -c "dokku git:auth-status auth-status.example.com username password"
echo "output: $output"
echo "status: $status"
assert_exit_status 1
run /bin/bash -c "dokku git:auth-status auth-status.example.com"
echo "output: $output"
echo "status: $status"
assert_exit_status 0
run /bin/bash -c "dokku git:auth auth-status.example.com username password"
echo "output: $output"
echo "status: $status"
assert_success
run /bin/bash -c "dokku git:auth-status auth-status.example.com username password"
echo "output: $output"
echo "status: $status"
assert_exit_status 0
run /bin/bash -c "dokku git:auth-status auth-status.example.com username other-password"
echo "output: $output"
echo "status: $status"
assert_exit_status 2
run /bin/bash -c "dokku git:auth-status auth-status.example.com"
echo "output: $output"
echo "status: $status"
assert_exit_status 2
run /bin/bash -c "dokku git:auth auth-status.example.com"
echo "output: $output"
echo "status: $status"
assert_success
run /bin/bash -c "dokku git:auth-status auth-status.example.com username password"
echo "output: $output"
echo "status: $status"
assert_exit_status 1
}
@test "(git) git:sync new [errors]" {