Address PR #1519 review round 2 · Entire
Address PR #1519 review round 2
0b20568→main·
toothbrush·3w ago·4 files·+23 added/-21 removed
- handleFormCancellation: also treat a cancelled/expired context as a clean
cancel, so a RunWithContext form whose context is cancelled exits quietly
instead of "prompt failed: huh: context canceled" (Cursor).
- Drop internal terminology from suspended/failed user messages: the wizard now
says "the mirror is suspended; contact support" / "the initial clone failed;
contact support", and explainSuspendedMirror points at support instead of the
internal entire-core admin mirrors resume command (Cursor).
Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com
Sessions
9ea51e10ee42View transcript
?\ Interactive Repo Mirror Onboarding WizardClaude Code·2 steps
Changes
4
cmd/entire/cli
Mrepo_mirror_create_wizard.go+2/-6
Mrepo_mirror_probe.go+9/-9
Mrepo_mirror_test.go+6/-3
Mutils.go+6/-3
534 unmodified lines
535
536
537
538
539
540
541
538
539
543
544
540
541
542
543
534 unmodified lines
case coreapi.MirrorStatusReady:
res.status = mirrorStatusReady
case coreapi.MirrorStatusSuspended:
// Carry the mirror id + resume command so the failure summary is
// actionable, matching the one-shot's explainSuspendedMirror guidance.
res.status, res.err = mirrorStatusSuspended,
fmt.Errorf("suspended — an operator can resume it: entire-core admin mirrors resume %s", outcome.created.MirrorId)
res.status, res.err = mirrorStatusSuspended, errors.New("the mirror is suspended; contact support")
case coreapi.MirrorStatusFailed:
res.status, res.err = mirrorStatusFailed,
fmt.Errorf("initial clone failed (mirror %s)", outcome.created.MirrorId)
res.status, res.err = mirrorStatusFailed, errors.New("the initial clone failed; contact support")
case coreapi.MirrorStatusProcessing:
nonTerminal()
default:
Mcmd/entire/cli/repo_mirror_create_wizard.go+2/-6
149 unmodified lines
150
151
152
153
154
155
156
153
154
155
156
157
158
159
159
160
161
161
162
163
164
162
163
164
165
149 unmodified lines
return fmt.Errorf("timed out waiting for initial clone: %w", err)
}
// explainSuspendedMirror prints operator-recovery guidance for a suspended
// placement: the cluster won't serve clones until upstream GitHub access is
// restored and an operator resumes it. Suspension usually follows upstream
// access loss (App uninstalled, repo went private, or a transient API error).
// explainSuspendedMirror tells the user a suspended placement can't be served
// and to contact support. Suspension usually follows a loss of upstream GitHub
// access (App uninstalled, repo went private, or a transient API error); the
// fix is operator-side, so we point at support rather than leaking an internal
// admin command.
func explainSuspendedMirror(w io.Writer, mirrorID string) {
fmt.Fprintf(w,
"\nMirror %s is registered but suspended — the cluster won't serve it.\n"+
"\nMirror %s is registered but suspended, so it can't be cloned yet.\n"+
"This usually means upstream GitHub access was lost (App uninstalled,\n"+
"the repo went private, or a transient API error). An operator can\n"+
"re-enable it once access is restored:\n"+
" entire-core admin mirrors resume %s\n",
mirrorID, mirrorID)
"the repo went private, or a transient API error). Contact support to\n"+
"restore it.\n",
mirrorID)
}
Mcmd/entire/cli/repo_mirror_probe.go+9/-9
21 unmodified lines
22
23
24
25
25
26
27
28
29
30
113 unmodified lines
144
145
146
145
147
148
149
150
151
152
153
152
154
155
156
157
158
21 unmodified lines
explainSuspendedMirror(&buf, id)
out := buf.String()
require.Contains(t, out, id, "message must name the mirror")
require.Contains(t, out, "entire-core admin mirrors resume "+id, "message must give the resume command")
require.Contains(t, out, "suspended")
require.Contains(t, out, "Contact support", "must point at support, not an internal admin command")
require.NotContains(t, out, "entire-core", "must not leak internal terminology")
// fakeMirrorGetter feeds awaitMirrorReady a scripted sequence of statuses (the
113 unmodified lines
require.Contains(t, out.String(), "git clone "+mirrorURL)
})
t.Run("suspended surfaces resume guidance as SilentError", func(t *testing.T) {
t.Run("suspended surfaces support guidance as SilentError", func(t *testing.T) {
t.Parallel()
var out, errW bytes.Buffer
outcome := mirrorCreateOutcome{created: mk(false, false), status: coreapi.MirrorStatusSuspended, polled: true}
err := reportOneShotMirror(&out, &errW, outcome, errMirrorSuspended)
var silent *SilentError
require.ErrorAs(t, err, &silent)
require.Contains(t, errW.String(), "entire-core admin mirrors resume "+id)
require.Contains(t, errW.String(), "Contact support")
require.NotContains(t, errW.String(), "entire-core")
require.NotContains(t, out.String(), "git clone")
})
}
Mcmd/entire/cli/repo_mirror_test.go+6/-3
27 unmodified lines
28
29
30
31
32
31
32
33
34
35
34
36
37
38
39
40
27 unmodified lines
// handleFormCancellation handles cancellation from huh form prompts.
// User abort (Ctrl+C) and timeout both print a cancelled message and return nil.
// Other errors are wrapped with the action name for context.
// User abort (Ctrl+C), timeout, and a cancelled/expired context (when the form
// ran via RunWithContext and the command's context was cancelled) all print a
// cancelled message and return nil. Other errors are wrapped with the action
// name for context.
func handleFormCancellation(w io.Writer, action string, err error) error {
if errors.Is(err, huh.ErrUserAborted) || errors.Is(err, huh.ErrTimeout) {
if errors.Is(err, huh.ErrUserAborted) || errors.Is(err, huh.ErrTimeout) ||
errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) {
fmt.Fprintf(w, "%s cancelled.\n", action)
return nil
}