Skip to content

Commit 0a90843

Browse files
authored
fix(description): use descriptions from schema (#26)
Using descriptions from the oas schema if available, which are generally more descriptive.
1 parent 2a9f8c6 commit 0a90843

4 files changed

Lines changed: 84 additions & 13 deletions

File tree

go.mod

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,6 @@ require (
1717
golang.org/x/text v0.19.0 // indirect
1818
gopkg.in/yaml.v3 v3.0.1 // indirect
1919
)
20+
21+
// uncomment for local development.
22+
// replace github.com/aep-dev/aep-lib-go => ../aep-lib-go

internal/service/resource_definition.go

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -202,41 +202,45 @@ func ExecuteResourceCommand(r *api.Resource, args []string) (*http.Request, stri
202202

203203
func addSchemaFlags(c *cobra.Command, schema openapi.Schema, args map[string]interface{}) error {
204204
for name, prop := range schema.Properties {
205+
description := prop.Description
206+
if description == "" {
207+
description = fmt.Sprintf("The %v of the resource", name)
208+
}
205209
if prop.ReadOnly {
206210
continue
207211
}
208212
switch prop.Type {
209213
case "string":
210214
var value string
211215
args[name] = &value
212-
c.Flags().StringVar(&value, name, "", fmt.Sprintf("The %v of the resource", name))
216+
c.Flags().StringVar(&value, name, "", description)
213217
case "integer":
214218
var value int
215219
args[name] = &value
216-
c.Flags().IntVar(&value, name, 0, fmt.Sprintf("The %v of the resource", name))
220+
c.Flags().IntVar(&value, name, 0, description)
217221
case "number":
218222
var value float64
219223
args[name] = &value
220-
c.Flags().Float64Var(&value, name, 0, fmt.Sprintf("The %v of the resource", name))
224+
c.Flags().Float64Var(&value, name, 0, description)
221225
case "boolean":
222226
var value bool
223227
args[name] = &value
224-
c.Flags().BoolVar(&value, name, false, fmt.Sprintf("The %v of the resource", name))
228+
c.Flags().BoolVar(&value, name, false, description)
225229
case "array":
226230
if prop.Items == nil {
227231
return fmt.Errorf("items is required for array type, not found for field %v", name)
228232
}
229233
var value []interface{}
230234
args[name] = &value
231-
c.Flags().Var(&ArrayFlag{&value, prop.Items.Type}, name, fmt.Sprintf("The %v of the resource", name))
235+
c.Flags().Var(&ArrayFlag{&value, prop.Items.Type}, name, description)
232236
case "object":
233237
var parsedValue map[string]interface{}
234238
args[name] = &parsedValue
235-
c.Flags().Var(&JSONFlag{&parsedValue}, name, fmt.Sprintf("The %v of the resource", name))
239+
c.Flags().Var(&JSONFlag{&parsedValue}, name, description)
236240
default:
237241
var parsedValue map[string]interface{}
238242
args[name] = &parsedValue
239-
c.Flags().Var(&JSONFlag{&parsedValue}, name, fmt.Sprintf("The %v of the resource", name))
243+
c.Flags().Var(&JSONFlag{&parsedValue}, name, description)
240244
}
241245
}
242246
for _, f := range schema.Required {

internal/service/resource_definition_test.go

Lines changed: 68 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"io"
66
"os"
77
"path/filepath"
8+
"strings"
89
"testing"
910

1011
"github.com/aep-dev/aep-lib-go/pkg/api"
@@ -19,7 +20,8 @@ func getTestAPI() *api.API {
1920
Schema: &openapi.Schema{
2021
Properties: map[string]openapi.Schema{
2122
"name": {
22-
Type: "string",
23+
Type: "string",
24+
Description: "The name of the project",
2325
},
2426
"description": {
2527
Type: "string",
@@ -118,12 +120,49 @@ func getTestAPI() *api.API {
118120
Parents: []string{},
119121
Schema: &openapi.Schema{},
120122
},
123+
"shelf": {
124+
Singular: "shelf",
125+
Plural: "shelves",
126+
Parents: []string{"project"},
127+
Schema: &openapi.Schema{},
128+
},
129+
"book": {
130+
Singular: "book",
131+
Plural: "books",
132+
Parents: []string{"shelf"},
133+
Schema: &openapi.Schema{
134+
Properties: map[string]openapi.Schema{
135+
"title": {
136+
Type: "string",
137+
},
138+
"author": {
139+
Type: "string",
140+
},
141+
"path": {
142+
Type: "string",
143+
ReadOnly: true,
144+
},
145+
},
146+
},
147+
Methods: api.Methods{
148+
Create: &api.CreateMethod{
149+
SupportsUserSettableCreate: true,
150+
},
151+
},
152+
},
121153
},
122154
}
123155
err := api.AddImplicitFieldsAndValidate(a)
124156
if err != nil {
125157
panic(err)
126158
}
159+
// Restore ReadOnly for book path, as AddImplicitFieldsAndValidate overwrites it
160+
if book, ok := a.Resources["book"]; ok {
161+
if pathProp, ok := book.Schema.Properties["path"]; ok {
162+
pathProp.ReadOnly = true
163+
book.Schema.Properties["path"] = pathProp
164+
}
165+
}
127166
return a
128167
}
129168

@@ -135,8 +174,10 @@ func TestExecuteCommand(t *testing.T) {
135174
expectedQuery string
136175
expectedPath string
137176
expectedMethod string
177+
138178
wantErr bool
139179
body string
180+
expectedOutput string
140181
}{
141182
{
142183
name: "simple resource no parents",
@@ -240,20 +281,43 @@ func TestExecuteCommand(t *testing.T) {
240281
wantErr: false,
241282
body: `{"description":"Manual dataset","name":"manual-dataset"}`,
242283
},
284+
{
285+
name: "create book with read-only path flag",
286+
resource: "book",
287+
args: []string{"--project=myproject", "--shelf=myshelf", "create", "mybook", "--path=some/path"},
288+
expectedPath: "",
289+
expectedMethod: "",
290+
wantErr: true,
291+
body: "",
292+
},
293+
{
294+
name: "help with description",
295+
resource: "project",
296+
args: []string{"create", "--help"},
297+
expectedPath: "",
298+
expectedMethod: "",
299+
wantErr: false,
300+
expectedOutput: "The name of the project",
301+
},
243302
}
244303

245304
for _, tt := range tests {
246305
t.Run(tt.name, func(t *testing.T) {
247306
a := getTestAPI()
248-
req, _, err := ExecuteResourceCommand(a.Resources[tt.resource], tt.args)
307+
req, output, err := ExecuteResourceCommand(a.Resources[tt.resource], tt.args)
249308
if (err != nil) != tt.wantErr {
250309
t.Errorf("ExecuteCommand() error = %v, wantErr %v", err, tt.wantErr)
251310
return
252311
}
253-
if !tt.wantErr && req == nil {
312+
if !tt.wantErr && req == nil && tt.expectedOutput == "" {
254313
t.Error("ExecuteCommand() returned nil request when no error expected")
255314
}
256-
if !tt.wantErr {
315+
if tt.expectedOutput != "" {
316+
if !strings.Contains(output, tt.expectedOutput) {
317+
t.Errorf("ExecuteCommand() output = %q, want to contain %q", output, tt.expectedOutput)
318+
}
319+
}
320+
if !tt.wantErr && req != nil {
257321
// Verify the request path matches expected pattern
258322
if req.URL.Path != tt.expectedPath {
259323
t.Errorf("ExecuteCommand() request path = %v, want %v", req.URL.Path, tt.expectedPath)

internal/service/service_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,12 @@ func TestService_ExecuteCommand_ListResources(t *testing.T) {
2222
{
2323
name: "no arguments",
2424
args: []string{},
25-
expected: "Available resources:\n - comment\n - dataset\n - project\n - user\n",
25+
expected: "Available resources:\n - book\n - comment\n - dataset\n - project\n - shelf\n - user\n",
2626
},
2727
{
2828
name: "help flag",
2929
args: []string{"--help"},
30-
expected: "Available resources:\n - comment\n - dataset\n - project\n - user\n",
30+
expected: "Available resources:\n - book\n - comment\n - dataset\n - project\n - shelf\n - user\n",
3131
},
3232
{
3333
name: "unknown resource",

0 commit comments

Comments
 (0)