chore(control-plane): reconcile crud-gaps work onto friendly-names resolver · Entire
chore(control-plane): reconcile crud-gaps work onto friendly-names resolver
2d4b58a·
toothbrush·3w ago·3 files·+29 added/-3 removed
Rebased onto feat/control-plane-friendly-names, which had independently reworked name resolution to the client-side pickOrg/pickProject design. Kept that resolver and dropped crud-gaps' server-side ?name= variant; this pass adapts the seams:
- resolveOrgRef walks all pages (ListOrgs is now paginated) then pickOrg
- restore isNotFound + resolvedRefLabel helpers used by the delete commands
- writeNotFoundProblem test helper (friendly-names' resolver tests lack it)
Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com
Sessions
ae2378c10239View transcript
[?
Control Plane Delete and Revoke SafetyClaude Code·Opus 4.8[1m]·1 step](/content/gh/entireio/cli/session/8e196be2-884b-4372-a672-2e81e2857e10#timeline-ae2378c10239/index.html)
Changes
3
cmd/entire/cli
Mcorecmd_delete_test.go+14
Mresolveref.go+14/-3
Mresolveref_test.go+1
2 unmodified lines
3
4
5
6
7
8
9
9 unmodified lines
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
2 unmodified lines
import (
"bytes"
"context"
"fmt"
"net/http"
"net/http/httptest"
"testing"
9 unmodified lines
// lookup, addressing the resource by id directly.
const testDeleteULID = "01HZX7QABCDEFGHJKMNPQRSTVW"
// writeNotFoundProblem writes a control-plane RFC 7807 404 so the ogen client
// decodes it as *ErrorModelStatusCode (which isNotFound keys on). A bare
// WriteHeader without the problem+json content type would instead surface as a
// decode error.
func writeNotFoundProblem(t *testing.T, w http.ResponseWriter) {
t.Helper()
w.Header().Set("Content-Type", "application/problem+json")
w.WriteHeader(http.StatusNotFound)
if _, err := fmt.Fprintf(w, `{"status":%d,"detail":"not found"}`, http.StatusNotFound); err != nil {
t.Errorf("write problem: %v", err)
}
}
// runDeleteCmd points the active-context client at srv via the activeCoreClient
// seam, runs newCmd() with args, and returns its stdout and error. The caller
// must not be parallel: the seam is package-global.
Mcmd/entire/cli/corecmd_delete_test.go+14
38 unmodified lines
39
40
41
42
42
43
44
45
46
47
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
51
62
63
64
65
38 unmodified lines
// resolveOrgRef turns an org reference (ULID or name) into its ULID. A ULID is
// returned unchanged; a name is looked up against the caller's visible orgs.
// returned unchanged; a name is looked up against the caller's visible orgs,
// walking every page so a match isn't missed on a now-paginated list.
func resolveOrgRef(ctx context.Context, c *coreapi.Client, ref string) (string, error) {
if looksLikeULID(ref) {
return ref, nil
}
out, err := c.ListOrgs(ctx)
orgs, err := fetchAllPages(ctx, func(ctx context.Context, cursor string) ([]coreapi.Org, string, error) {
params := coreapi.ListOrgsParams{}
if cursor != "" {
params.PageToken = coreapi.NewOptString(cursor)
}
out, err := c.ListOrgs(ctx, params)
if err != nil {
return nil, "", err
}
return out.Orgs, out.NextPageToken.Or(""), nil
})
if err != nil {
return "", err
}
return pickOrg(out.Orgs, ref)
return pickOrg(orgs, ref)
}
// resolveAccountRef turns an account reference into its ULID. A ULID passes
Mcmd/entire/cli/resolveref.go+14/-3
1 unmodified line
2
3
4
5
6
7
8
1 unmodified line
import (
"context"
"fmt"
"net/http"
"net/http/httptest"
"sync/atomic"
Mcmd/entire/cli/resolveref_test.go+1