diff --git a/docs/deployment/methods/git.md b/docs/deployment/methods/git.md index 64a7e61c3..c7290bf5a 100644 --- a/docs/deployment/methods/git.md +++ b/docs/deployment/methods/git.md @@ -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 diff --git a/plugins/git/internal-functions b/plugins/git/internal-functions index 7fcca2bf4..50857cf34 100644 --- a/plugins/git/internal-functions +++ b/plugins/git/internal-functions @@ -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() { diff --git a/tests/unit/git_3.bats b/tests/unit/git_3.bats index 069816cd4..049cbda6b 100644 --- a/tests/unit/git_3.bats +++ b/tests/unit/git_3.bats @@ -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]" {