Skip to content

Commit fe43c66

Browse files
authored
feat(internal/sidekick/gcloud): support delete methods in generator (#5883)
The gcloud CLI generator is updated to support Delete methods. Generated delete commands now invoke the client's Delete method instead of printing a placeholder.
1 parent 7b77a1f commit fe43c66

6 files changed

Lines changed: 173 additions & 9 deletions

File tree

internal/sidekick/gcloud/client.go

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -94,10 +94,10 @@ func clientInfoFromPath(clientImportPath string) *goClientInfo {
9494
}
9595
}
9696

97-
// buildClientCall returns a ClientCall for an AIP-131 Get or AIP-132 List
98-
// method when the model maps to a standard GAPIC Go package and the command
99-
// composes a resource path. It returns nil otherwise so the command keeps
100-
// its print-only action.
97+
// buildClientCall returns a ClientCall for an AIP-131 Get, AIP-132 List, or
98+
// AIP-135 Delete method when the model maps to a standard GAPIC Go package
99+
// and the command composes a resource path. It returns nil otherwise so the
100+
// command keeps its print-only action.
101101
func buildClientCall(method *api.Method, goClient *goClientInfo, hasPath bool) *ClientCall {
102102
if goClient == nil || !hasPath {
103103
return nil
@@ -122,6 +122,15 @@ func buildClientCall(method *api.Method, goClient *goClientInfo, hasPath bool) *
122122
RequestType: goClient.Alias + "pb." + method.InputType.Name,
123123
IsList: true,
124124
}
125+
case provider.IsDelete(method):
126+
return &ClientCall{
127+
Method: method.Name,
128+
NameField: "Name",
129+
Package: goClient.Alias,
130+
RequestType: goClient.Alias + "pb." + method.InputType.Name,
131+
IsDelete: true,
132+
IsLRO: method.IsLRO,
133+
}
125134
default:
126135
return nil
127136
}

internal/sidekick/gcloud/client_test.go

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,40 @@ func TestBuildClientCall(t *testing.T) {
6666
IsList: true,
6767
},
6868
},
69+
{
70+
name: "Delete LRO method",
71+
method: &api.Method{
72+
Name: "DeleteInstance",
73+
InputType: &api.Message{Name: "DeleteInstanceRequest"},
74+
IsLRO: true,
75+
},
76+
goClient: goClient,
77+
hasPath: true,
78+
want: &ClientCall{
79+
Method: "DeleteInstance",
80+
NameField: "Name",
81+
Package: "parallelstore",
82+
RequestType: "parallelstorepb.DeleteInstanceRequest",
83+
IsDelete: true,
84+
IsLRO: true,
85+
},
86+
},
87+
{
88+
name: "Delete non-LRO method",
89+
method: &api.Method{
90+
Name: "DeleteOperation",
91+
InputType: &api.Message{Name: "DeleteOperationRequest"},
92+
},
93+
goClient: goClient,
94+
hasPath: true,
95+
want: &ClientCall{
96+
Method: "DeleteOperation",
97+
NameField: "Name",
98+
Package: "parallelstore",
99+
RequestType: "parallelstorepb.DeleteOperationRequest",
100+
IsDelete: true,
101+
},
102+
},
69103
{
70104
name: "nil goClient",
71105
method: &api.Method{
@@ -96,10 +130,10 @@ func TestBuildClientCall(t *testing.T) {
96130
want: nil,
97131
},
98132
{
99-
name: "not get or list",
133+
name: "not get list or delete",
100134
method: &api.Method{
101-
Name: "CreateInstance",
102-
InputType: &api.Message{Name: "CreateInstanceRequest"},
135+
Name: "ImportData",
136+
InputType: &api.Message{Name: "ImportDataRequest"},
103137
},
104138
goClient: goClient,
105139
hasPath: true,

internal/sidekick/gcloud/command.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,15 @@ type Command struct {
3333
// ClientCall describes a Go client method invocation that should replace the
3434
// default print-only action for a generated command.
3535
type ClientCall struct {
36+
// IsDelete reports whether the method is a standard Delete method.
37+
IsDelete bool
38+
3639
// IsList reports whether the method is a standard List method.
3740
IsList bool
3841

42+
// IsLRO reports whether the call returns a long-running operation.
43+
IsLRO bool
44+
3945
// Method is the unqualified client method to call on the constructed
4046
// client, for example "GetInstance". The template invokes it as
4147
// `client.<Method>(ctx, &<RequestType>{...})`.

internal/sidekick/gcloud/model_test.go

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,85 @@ func TestConstructSurfaceModel(t *testing.T) {
199199
},
200200
},
201201
},
202+
{
203+
name: "delete method",
204+
model: &api.API{
205+
Name: "parallelstore",
206+
Title: "Parallelstore",
207+
PackageName: "google.cloud.parallelstore.v1",
208+
Services: []*api.Service{{
209+
Name: "InstanceService",
210+
Methods: []*api.Method{{
211+
Name: "DeleteInstance",
212+
IsAIPStandardDelete: true,
213+
IsLRO: true,
214+
InputType: &api.Message{
215+
Name: "DeleteInstanceRequest",
216+
Fields: []*api.Field{
217+
{
218+
Name: "name",
219+
ResourceReference: &api.ResourceReference{Type: "parallelstore.googleapis.com/Instance"},
220+
},
221+
},
222+
},
223+
PathInfo: &api.PathInfo{
224+
Bindings: []*api.PathBinding{{
225+
Verb: "DELETE",
226+
PathTemplate: (&api.PathTemplate{}).
227+
WithLiteral("v1").
228+
WithLiteral("projects").WithVariable(api.NewPathVariable("project")).
229+
WithLiteral("locations").WithVariable(api.NewPathVariable("location")).
230+
WithLiteral("instances").WithVariable(api.NewPathVariable("instance")),
231+
}},
232+
},
233+
}},
234+
}},
235+
ResourceDefinitions: []*api.Resource{{
236+
Type: "parallelstore.googleapis.com/Instance",
237+
Patterns: []api.ResourcePattern{
238+
(&api.PathTemplate{}).
239+
WithLiteral("projects").WithVariable(api.NewPathVariable("project")).
240+
WithLiteral("locations").WithVariable(api.NewPathVariable("location")).
241+
WithLiteral("instances").WithVariable(api.NewPathVariable("instance")).
242+
Segments,
243+
},
244+
}},
245+
},
246+
want: SurfaceModel{
247+
PackageName: "parallelstore",
248+
Imports: []Import{
249+
{Alias: "parallelstore", Path: "cloud.google.com/go/parallelstore/apiv1"},
250+
{Path: "cloud.google.com/go/parallelstore/apiv1/parallelstorepb"},
251+
},
252+
Group: Group{
253+
Name: "parallelstore",
254+
Usage: "manage Parallelstore resources",
255+
Subgroups: []Subgroup{{
256+
Name: "instances",
257+
Usage: "manage instances resources",
258+
Commands: []Command{{
259+
Name: "delete",
260+
Usage: "delete instances",
261+
PathFormat: "projects/%s/locations/%s/instances/%s",
262+
Args: []string{"project", "location", "instance"},
263+
PathLabel: "name",
264+
Flags: []Flag{
265+
{Name: "location", Kind: "String", Required: true, Usage: "The location."},
266+
{Name: "instance", Kind: "String", Required: true, Usage: "The instance."},
267+
},
268+
ClientCall: &ClientCall{
269+
Method: "DeleteInstance",
270+
NameField: "Name",
271+
Package: "parallelstore",
272+
RequestType: "parallelstorepb.DeleteInstanceRequest",
273+
IsDelete: true,
274+
IsLRO: true,
275+
},
276+
}},
277+
}},
278+
},
279+
},
280+
},
202281
} {
203282
t.Run(test.name, func(t *testing.T) {
204283
got := constructSurfaceModel(test.model, "")

internal/sidekick/gcloud/templates/package/surface_commands.go.tmpl

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,22 @@ func Command() *cli.Command {
8989
fmt.Println(string(out))
9090
}
9191
return nil
92+
{{- else if .ClientCall.IsDelete}}
93+
{{- if .ClientCall.IsLRO}}
94+
op, err := client.{{.ClientCall.Method}}(ctx, &{{.ClientCall.RequestType}}{ {{.ClientCall.NameField}}: {{.PathLabel}} })
95+
if err != nil {
96+
return err
97+
}
98+
if err := op.Wait(ctx); err != nil {
99+
return err
100+
}
101+
{{- else}}
102+
if err := client.{{.ClientCall.Method}}(ctx, &{{.ClientCall.RequestType}}{ {{.ClientCall.NameField}}: {{.PathLabel}} }); err != nil {
103+
return err
104+
}
105+
{{- end}}
106+
fmt.Printf("Deleted %s\n", {{.PathLabel}})
107+
return nil
92108
{{- else}}
93109
resp, err := client.{{.ClientCall.Method}}(ctx, &{{.ClientCall.RequestType}}{ {{.ClientCall.NameField}}: {{.PathLabel}} })
94110
if err != nil {

internal/sidekick/gcloud/testdata/internal/generated/parallelstore/commands.go.golden

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,19 @@ func Command() *cli.Command {
127127
return fmt.Errorf("--project is required")
128128
}
129129
name := fmt.Sprintf("projects/%s/locations/%s/instances/%s", cmd.String("project"), cmd.String("location"), cmd.String("instance"))
130-
fmt.Printf("Executing delete on %s\n", name)
130+
client, err := parallelstore.NewClient(ctx)
131+
if err != nil {
132+
return err
133+
}
134+
defer client.Close()
135+
op, err := client.DeleteInstance(ctx, &parallelstorepb.DeleteInstanceRequest{Name: name})
136+
if err != nil {
137+
return err
138+
}
139+
if err := op.Wait(ctx); err != nil {
140+
return err
141+
}
142+
fmt.Printf("Deleted %s\n", name)
131143
return nil
132144
},
133145
},
@@ -266,7 +278,15 @@ func Command() *cli.Command {
266278
return fmt.Errorf("--project is required")
267279
}
268280
name := fmt.Sprintf("projects/%s/locations/%s/operations/%s", cmd.String("project"), cmd.String("location"), cmd.String("operation"))
269-
fmt.Printf("Executing delete on %s\n", name)
281+
client, err := parallelstore.NewClient(ctx)
282+
if err != nil {
283+
return err
284+
}
285+
defer client.Close()
286+
if err := client.DeleteOperation(ctx, &parallelstorepb.DeleteOperationRequest{Name: name}); err != nil {
287+
return err
288+
}
289+
fmt.Printf("Deleted %s\n", name)
270290
return nil
271291
},
272292
},

0 commit comments

Comments
 (0)