fix(control-plane): show resolved ULID in delete success messages · Entire

fix(control-plane): show resolved ULID in delete success messages

eb2c0db·

toothbrush·3w ago·5 files·+35 added/-3 removed

org/project/repo delete echoed the user-supplied arg, so a name-based delete confirmed a name while the operation used the resolved ULID — ambiguous where names are reused. Add resolvedRefLabel to render "name (ULID)" for names and the bare ULID otherwise.

Addresses trail #642 finding.

Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com

Sessions

c14749e12a9dView transcript

Changes

5

106 unmodified lines

107
108
109
110
110
111
112
113

106 unmodified lines

if err := c.DeleteOrg(ctx, coreapi.DeleteOrgParams{OrgId: orgID}); err != nil {
                return err
            }
            cmd.Printf("Deleted org %s\n", args[0])
            cmd.Printf("Deleted org %s\n", resolvedRefLabel(args[0], orgID))
            return nil
        },

Mcmd/entire/cli/org.go+1/-1

184 unmodified lines

185
186
187
188
188
189
190
191

184 unmodified lines

if err := c.DeleteProject(ctx, coreapi.DeleteProjectParams{ProjectId: projID}); err != nil {
                return err
            }
            cmd.Printf("Deleted project %s\n", args[0])
            cmd.Printf("Deleted project %s\n", resolvedRefLabel(args[0], projID))
            return nil
        },

Mcmd/entire/cli/project.go+1/-1

190 unmodified lines

191
192
193
194
194
195
196
197

190 unmodified lines

if err := c.DeleteRepo(ctx, coreapi.DeleteRepoParams{RepoId: repoID}); err != nil {
                return err
            }
            cmd.Printf("Deleted repo %s\n", args[0])
            cmd.Printf("Deleted repo %s\n", resolvedRefLabel(args[0], repoID))
            return nil
        },

Mcmd/entire/cli/repo.go+1/-1

138 unmodified lines

139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155

138 unmodified lines

return out.Repo.Value.ID, nil

// resolvedRefLabel formats a reference for a success message so it always
// names the resolved ULID. When the user passed a ULID (ref == id) it returns
// the id alone; when they passed a name it returns "name (id)" so the message
// is unambiguous in environments where names can be reused across orgs/projects.
func resolvedRefLabel(ref, id string) string {
    if ref == id {
        return id
    }
    return fmt.Sprintf("%s (%s)", ref, id)
}

// isNotFound reports whether err is a control-plane 404. The exact-name
// lookups (resolveOrgRef/resolveProjectRef/resolveRepoRef) map it to a
// friendly "no X named …" hint rather than surfacing the raw problem detail.

Mcmd/entire/cli/resolveref.go+11

270 unmodified lines

271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294

270 unmodified lines

}
})
}

func TestResolvedRefLabel(t *testing.T) {
    t.Parallel()

const id = "01J0REPO000000000000000001"

t.Run("ulid passes through", func(t *testing.T) {
        t.Parallel()
        if got := resolvedRefLabel(id, id); got != id {
            t.Errorf("got %q, want %q", got, id)
        }
    })

t.Run("name includes resolved id", func(t *testing.T) {
        t.Parallel()
        want := fmt.Sprintf("acme (%s)", id)
        if got := resolvedRefLabel("acme", id); got != want {
            t.Errorf("got %q, want %q", got, want)
        }
    })
}

Mcmd/entire/cli/resolveref_test.go+21