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:

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

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