Report JSON output failures from recovery commands
This commit is contained in:
@@ -102,14 +102,17 @@ func runRecovery(ctx context.Context, invocation cli.Invocation, stdout, stderr
|
||||
for _, item := range listed.Diagnostics {
|
||||
diagnostics = append(diagnostics, diagnostic(item))
|
||||
}
|
||||
writeJSON(stdout, attemptsDocument{
|
||||
if writeErr := writeJSON(stdout, attemptsDocument{
|
||||
SchemaVersion: 1,
|
||||
Command: "publication-attempts",
|
||||
RecordDir: git.DisplayDiagnostic(listed.RecordDir),
|
||||
Attempts: attempts,
|
||||
Diagnostics: diagnostics,
|
||||
Diagnostic: diagnostic(err),
|
||||
})
|
||||
}); writeErr != nil {
|
||||
fmt.Fprintf(stderr, "write recovery output: %v\n", git.DisplayError(writeErr))
|
||||
return 1
|
||||
}
|
||||
} else {
|
||||
fmt.Fprintf(stdout, "publication records in %s\n", git.DisplayDiagnostic(listed.RecordDir))
|
||||
for _, item := range listed.Attempts {
|
||||
@@ -149,7 +152,10 @@ func runReconcile(ctx context.Context, invocation cli.Invocation, stdout, stderr
|
||||
dto.ObservedCommit = result.ObservedCommit
|
||||
}
|
||||
dto.Diagnostic = diagnostic(err)
|
||||
writeJSON(stdout, dto)
|
||||
if writeErr := writeJSON(stdout, dto); writeErr != nil {
|
||||
fmt.Fprintf(stderr, "write recovery output: %v\n", git.DisplayError(writeErr))
|
||||
return 1
|
||||
}
|
||||
} else if err == nil {
|
||||
fmt.Fprintf(stdout, "reconciled %s module=%s tag=%s state=%s\n", git.DisplayDiagnostic(invocation.RecordPath), git.DisplayDiagnostic(evidence.ModulePath), git.DisplayDiagnostic(evidence.Tag), result.State)
|
||||
if result.State == releasekit.PublicationConflict {
|
||||
@@ -243,7 +249,7 @@ func humanDiagnostic(err error) string {
|
||||
return git.DisplayError(err).Error()
|
||||
}
|
||||
|
||||
func writeJSON(writer io.Writer, value any) {
|
||||
func writeJSON(writer io.Writer, value any) error {
|
||||
encoder := json.NewEncoder(writer)
|
||||
_ = encoder.Encode(value)
|
||||
return encoder.Encode(value)
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
@@ -14,6 +15,41 @@ import (
|
||||
"go.maximumdirect.net/releasekit/internal/publish"
|
||||
)
|
||||
|
||||
type failingRecoveryWriter struct{ err error }
|
||||
|
||||
func (writer failingRecoveryWriter) Write([]byte) (int, error) { return 0, writer.err }
|
||||
|
||||
func TestRecoveryCommandsReportJSONWriteFailure(t *testing.T) {
|
||||
repo := newCLIRepository(t)
|
||||
cliGitRun(t, repo, "tag", "-a", "v1.2.3", "-m", "Release")
|
||||
store := t.TempDir()
|
||||
path, err := publish.SaveEvidence(t.Context(), repo, store, publish.Evidence{
|
||||
RepositoryDir: repo, Endpoint: repo, Tag: "v1.2.3",
|
||||
CandidateCommit: cliGitOutput(t, repo, "rev-parse", "HEAD"),
|
||||
TagObject: cliGitOutput(t, repo, "rev-parse", "v1.2.3"),
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
failure := errors.New("output unavailable: https://user:audit-secret@example.invalid/output")
|
||||
for _, args := range [][]string{{"reconcile", "--record", path, "--json"}, {"publication-attempts", "--record-dir", store, "--json"}} {
|
||||
var normal, stderr bytes.Buffer
|
||||
if status := run(t.Context(), args, &normal, &stderr); status != 0 {
|
||||
t.Fatalf("normal output status=%d: %s", status, &stderr)
|
||||
}
|
||||
stderr.Reset()
|
||||
if status := run(t.Context(), args, failingRecoveryWriter{failure}, &stderr); status != 1 {
|
||||
t.Fatalf("failed output status=%d: %s", status, &stderr)
|
||||
}
|
||||
if !strings.Contains(stderr.String(), "output unavailable") || strings.Contains(stderr.String(), "audit-secret") {
|
||||
t.Fatalf("output diagnostic: %s", &stderr)
|
||||
}
|
||||
if args[0] == "reconcile" && !strings.Contains(normal.String(), `"state":"published"`) {
|
||||
t.Fatalf("observation changed: %s", &normal)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestRecoveryDisplaysRedactCredentialPathsAndMetadata(t *testing.T) {
|
||||
secret := "audit-secret"
|
||||
raw := "https://audit-user:" + secret + "@example.invalid/attempt.json"
|
||||
|
||||
Reference in New Issue
Block a user