Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ go 1.22.3

require (
github.com/BurntSushi/toml v1.4.0
github.com/aep-dev/aep-lib-go v0.0.0-20250226051706-6eab5b746243
github.com/aep-dev/aep-lib-go v0.0.0-20250506053130-6fd1d4e67239
github.com/spf13/cobra v1.8.1
github.com/stretchr/testify v1.9.0
)
Expand All @@ -14,5 +14,6 @@ require (
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
golang.org/x/text v0.19.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
12 changes: 10 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0=
github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
github.com/aep-dev/aep-lib-go v0.0.0-20250226051706-6eab5b746243 h1:R0zh8mlKsE04B5MWcvs22xaeGzQrXWtRxqHemCh4jBY=
github.com/aep-dev/aep-lib-go v0.0.0-20250226051706-6eab5b746243/go.mod h1:M+h1D6T2uIUPelmaEsJbjR6JhqKsTlPX3lxp25zQQsk=
github.com/aep-dev/aep-lib-go v0.0.0-20250506053130-6fd1d4e67239 h1:X9ylZ4HkzEpBny2vAE9zLDtTXpoe1BHeqhnIpsZZfaA=
github.com/aep-dev/aep-lib-go v0.0.0-20250506053130-6fd1d4e67239/go.mod h1:YWfg3gjAGpvwFJnEQl1JjBGd0evGBKobt5wU/QxV6pA=
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/jarcoal/httpmock v1.3.1 h1:iUx3whfZWVf3jT01hQTO/Eo5sAYtB2/rqaUuOtpInww=
github.com/jarcoal/httpmock v1.3.1/go.mod h1:3yb8rc4BI7TCBhFY8ng0gjuLKJNquuDNiPaZjnENuYg=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
Expand All @@ -16,7 +20,11 @@ github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM=
golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
2 changes: 1 addition & 1 deletion internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ type API struct {
func ReadConfigFromFile(file string) (*Config, error) {
// Check if file exists first
if _, err := os.Stat(file); os.IsNotExist(err) {
slog.Warn("Config file does not exist, using default configuration", "file", file)
slog.Debug("Config file does not exist, using default configuration", "file", file)
return &Config{APIs: make(map[string]API)}, nil
}

Expand Down
23 changes: 12 additions & 11 deletions internal/service/resource_definition.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@ func ExecuteResourceCommand(r *api.Resource, args []string) (*http.Request, stri
var parents []*string

i := 1
for i < len(r.PatternElems)-1 {
p := r.PatternElems[i]
patternElems := r.PatternElems()
for i < len(patternElems)-1 {
p := patternElems[i]
flagName := p[1 : len(p)-1]
var flagValue string
parents = append(parents, &flagValue)
Expand All @@ -31,9 +32,9 @@ func ExecuteResourceCommand(r *api.Resource, args []string) (*http.Request, stri

withPrefix := func(path string) string {
pElems := []string{}
for i, p := range r.PatternElems {
for i, p := range patternElems {
// last element, we assume this was handled by the caller.
if i == len(r.PatternElems)-1 {
if i == len(patternElems)-1 {
continue
}
if i%2 == 0 {
Expand All @@ -46,10 +47,10 @@ func ExecuteResourceCommand(r *api.Resource, args []string) (*http.Request, stri
return fmt.Sprintf("%s%s", prefix, path)
}

if r.CreateMethod != nil {
if r.Methods.Create != nil {
use := "create [id]"
args := cobra.ExactArgs(1)
if !r.CreateMethod.SupportsUserSettableCreate {
if !r.Methods.Create.SupportsUserSettableCreate {
use = "create"
args = cobra.ExactArgs(0)
}
Expand All @@ -60,7 +61,7 @@ func ExecuteResourceCommand(r *api.Resource, args []string) (*http.Request, stri
Args: args,
Run: func(cmd *cobra.Command, args []string) {
p := withPrefix("")
if r.CreateMethod.SupportsUserSettableCreate {
if r.Methods.Create.SupportsUserSettableCreate {
id := args[0]
p = withPrefix(fmt.Sprintf("?id=%s", id))
}
Expand All @@ -78,7 +79,7 @@ func ExecuteResourceCommand(r *api.Resource, args []string) (*http.Request, stri
c.AddCommand(createCmd)
}

if r.GetMethod != nil {
if r.Methods.Get != nil {
getCmd := &cobra.Command{
Use: "get [id]",
Short: fmt.Sprintf("Get a %v", strings.ToLower(r.Singular)),
Expand All @@ -92,7 +93,7 @@ func ExecuteResourceCommand(r *api.Resource, args []string) (*http.Request, stri
c.AddCommand(getCmd)
}

if r.UpdateMethod != nil {
if r.Methods.Update != nil {

updateArgs := map[string]interface{}{}
updateCmd := &cobra.Command{
Expand All @@ -116,7 +117,7 @@ func ExecuteResourceCommand(r *api.Resource, args []string) (*http.Request, stri
c.AddCommand(updateCmd)
}

if r.DeleteMethod != nil {
if r.Methods.Delete != nil {

deleteCmd := &cobra.Command{
Use: "delete [id]",
Expand All @@ -131,7 +132,7 @@ func ExecuteResourceCommand(r *api.Resource, args []string) (*http.Request, stri
c.AddCommand(deleteCmd)
}

if r.ListMethod != nil {
if r.Methods.List != nil {

listCmd := &cobra.Command{
Use: "list",
Expand Down
129 changes: 80 additions & 49 deletions internal/service/resource_definition_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,50 +8,91 @@ import (
"github.com/aep-dev/aep-lib-go/pkg/openapi"
)

var projectResource = api.Resource{
Singular: "project",
Plural: "projects",
PatternElems: []string{"projects", "{project}"},
Parents: []*api.Resource{},
Schema: &openapi.Schema{
Properties: map[string]openapi.Schema{
"name": {
Type: "string",
},
"description": {
Type: "string",
func getTestAPI() *api.API {
projectResource := api.Resource{
Singular: "project",
Plural: "projects",
Parents: []string{},
Schema: &openapi.Schema{
Properties: map[string]openapi.Schema{
"name": {
Type: "string",
},
"description": {
Type: "string",
},
"active": {
Type: "boolean",
},
"tags": {
Type: "array",
Items: &openapi.Schema{
Type: "string",
},
},
"metadata": {
Type: "object",
},
"priority": {
Type: "integer",
},
},
"active": {
Type: "boolean",
Required: []string{"name"},
},
Methods: api.Methods{
Get: &api.GetMethod{},
List: &api.ListMethod{},
Create: &api.CreateMethod{
SupportsUserSettableCreate: true,
},
"tags": {
Type: "array",
Items: &openapi.Schema{
Type: "string",
Update: &api.UpdateMethod{},
Delete: &api.DeleteMethod{},
},
}

a := &api.API{
Name: "test",
ServerURL: "https://api.example.com",
Resources: map[string]*api.Resource{
"project": &projectResource,
"dataset": &api.Resource{
Singular: "dataset",
Plural: "datasets",
Parents: []string{"project"},
Schema: &openapi.Schema{},
Methods: api.Methods{
Get: &api.GetMethod{},
List: &api.ListMethod{},
Create: &api.CreateMethod{},
Update: &api.UpdateMethod{},
Delete: &api.DeleteMethod{},
},
},
"metadata": {
Type: "object",
"user": &api.Resource{
Singular: "user",
Plural: "users",
Parents: []string{},
Schema: &openapi.Schema{},
},
"priority": {
Type: "integer",
"comment": &api.Resource{
Singular: "comment",
Plural: "comments",
Parents: []string{},
Schema: &openapi.Schema{},
},
},
Required: []string{"name"},
},
GetMethod: &api.GetMethod{},
ListMethod: &api.ListMethod{},
CreateMethod: &api.CreateMethod{
SupportsUserSettableCreate: true,
},
UpdateMethod: &api.UpdateMethod{},
DeleteMethod: &api.DeleteMethod{},
}
err := api.AddImplicitFieldsAndValidate(a)
if err != nil {
panic(err)
}
return a
}

func TestExecuteCommand(t *testing.T) {
tests := []struct {
name string
resource api.Resource
resource string
args []string
expectedQuery string
expectedPath string
Expand All @@ -61,7 +102,7 @@ func TestExecuteCommand(t *testing.T) {
}{
{
name: "simple resource no parents",
resource: projectResource,
resource: "project",
args: []string{"list"},
expectedPath: "projects",
expectedMethod: "GET",
Expand All @@ -70,7 +111,7 @@ func TestExecuteCommand(t *testing.T) {
},
{
name: "create with tags",
resource: projectResource,
resource: "project",
args: []string{"create", "myproject", "--name=test-project", "--tags=tag1,tag2,tag3"},
expectedPath: "projects",
expectedMethod: "POST",
Expand All @@ -80,7 +121,7 @@ func TestExecuteCommand(t *testing.T) {
},
{
name: "create with tags quoted",
resource: projectResource,
resource: "project",
args: []string{"create", "myproject", "--name=test-project", "--tags=\"tag1,\",tag2,tag3"},
expectedPath: "projects",
expectedMethod: "POST",
Expand All @@ -89,19 +130,8 @@ func TestExecuteCommand(t *testing.T) {
body: `{"name":"test-project","tags":["tag1,","tag2","tag3"]}`,
},
{
name: "resource with parent",
resource: api.Resource{
Singular: "dataset",
Plural: "datasets",
PatternElems: []string{"projects", "{project}", "datasets", "{dataset}"},
Parents: []*api.Resource{&projectResource},
Schema: &openapi.Schema{},
GetMethod: &api.GetMethod{},
ListMethod: &api.ListMethod{},
CreateMethod: &api.CreateMethod{},
UpdateMethod: &api.UpdateMethod{},
DeleteMethod: &api.DeleteMethod{},
},
name: "resource with parent",
resource: "dataset",
args: []string{"--project=foo", "get", "abc"},
expectedPath: "projects/foo/datasets/abc",
expectedMethod: "GET",
Expand All @@ -112,7 +142,8 @@ func TestExecuteCommand(t *testing.T) {

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
req, _, err := ExecuteResourceCommand(&tt.resource, tt.args)
a := getTestAPI()
req, _, err := ExecuteResourceCommand(a.Resources[tt.resource], tt.args)
if (err != nil) != tt.wantErr {
t.Errorf("ExecuteCommand() error = %v, wantErr %v", err, tt.wantErr)
return
Expand Down
14 changes: 12 additions & 2 deletions internal/service/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,21 @@ func (s *ServiceCommand) Execute(args []string) (string, error) {
if err != nil {
return "", fmt.Errorf("unable to execute request: %v", err)
}
return strings.Join([]string{output, reqOutput}, "\n"), nil
outputs := []string{}
for _, o := range []string{output, reqOutput} {
if o != "" {
outputs = append(outputs, o)
}
}
return strings.Join(outputs, "\n"), nil
}

func (s *ServiceCommand) doRequest(r *http.Request) (string, error) {
r.Header.Set("Content-Type", "application/json")
contentType := "application/json"
if r.Method == http.MethodPatch {
contentType = "application/merge-patch+json"
}
r.Header.Set("Content-Type", contentType)
for k, v := range s.Headers {
r.Header.Set(k, v)
}
Expand Down
16 changes: 3 additions & 13 deletions internal/service/service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,11 @@ package service
import (
"strings"
"testing"

"github.com/aep-dev/aep-lib-go/pkg/api"
)

func TestService_ExecuteCommand_ListResources(t *testing.T) {
// Test setup
svc := NewServiceCommand(&api.API{
ServerURL: "http://test.com",
Resources: map[string]*api.Resource{
"project": &projectResource,
"user": {},
"post": {},
"comment": {},
},
}, nil, false, false)
svc := NewServiceCommand(getTestAPI(), nil, false, false)

tests := []struct {
name string
Expand All @@ -28,12 +18,12 @@ func TestService_ExecuteCommand_ListResources(t *testing.T) {
{
name: "no arguments",
args: []string{},
expected: "Available resources:\n - comment\n - post\n - project\n - user\n",
expected: "Available resources:\n - comment\n - dataset\n - project\n - user\n",
},
{
name: "help flag",
args: []string{"--help"},
expected: "Available resources:\n - comment\n - post\n - project\n - user\n",
expected: "Available resources:\n - comment\n - dataset\n - project\n - user\n",
},
{
name: "unknown resource",
Expand Down
Loading