-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: hardcoded resource cmds (#203)
* add barebones cmds for resources and operations * wip: add flags * add more flag types * remove cmd * remove comments * add (bad) tests, fix output * fix teams short/long description * change back rootCmd name * pr feedback
- Loading branch information
1 parent
96474cd
commit b8dc52a
Showing
4 changed files
with
232 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
// this file WILL be generated (sc-241153) | ||
|
||
package cmd | ||
|
||
import ( | ||
"net/http" | ||
|
||
"github.com/spf13/cobra" | ||
|
||
"ldcli/cmd/resources" | ||
) | ||
|
||
func addAllResourceCmds(rootCmd *cobra.Command, client *http.Client) { | ||
// Resource commands | ||
gen_TeamsResourceCmd := resources.NewResourceCmd( | ||
rootCmd, | ||
"teams", | ||
"A team is a group of members in your LaunchDarkly account.", | ||
"A team can have maintainers who are able to add and remove team members. It also can have custom roles assigned to it that allows shared access to those roles for all team members. To learn more, read [Teams](https://docs.launchdarkly.com/home/teams).\n\nThe Teams API allows you to create, read, update, and delete a team.\n\nSeveral of the endpoints in the Teams API require one or more member IDs. The member ID is returned as part of the [List account members](/tag/Account-members#operation/getMembers) response. It is the `_id` field of each element in the `items` array.", | ||
) | ||
|
||
// Operation commands | ||
resources.NewOperationCmd(gen_TeamsResourceCmd, client, resources.OperationData{ | ||
Short: "Create team", | ||
Long: "Create a team. To learn more, read [Creating a team](https://docs.launchdarkly.com/home/teams/creating).\n\n### Expanding the teams response\nLaunchDarkly supports four fields for expanding the \"Create team\" response. By default, these fields are **not** included in the response.\n\nTo expand the response, append the `expand` query parameter and add a comma-separated list with any of the following fields:\n\n* `members` includes the total count of members that belong to the team.\n* `roles` includes a paginated list of the custom roles that you have assigned to the team.\n* `projects` includes a paginated list of the projects that the team has any write access to.\n* `maintainers` includes a paginated list of the maintainers that you have assigned to the team.\n\nFor example, `expand=members,roles` includes the `members` and `roles` fields in the response.\n", | ||
Use: "create", | ||
Params: []resources.Param{ | ||
{ | ||
Name: "expand", | ||
In: "query", | ||
Description: "A comma-separated list of properties that can reveal additional information in the response. Supported fields are explained above.", | ||
Type: "string", | ||
}, | ||
}, | ||
HTTPMethod: "post", | ||
RequiresBody: true, | ||
Path: "/api/v2/teams", | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
package cmd_test | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
"github.com/stretchr/testify/require" | ||
|
||
"ldcli/cmd" | ||
"ldcli/internal/analytics" | ||
) | ||
|
||
func TestCreateTeam(t *testing.T) { | ||
t.Run("help shows postTeam description", func(t *testing.T) { | ||
args := []string{ | ||
"teams", | ||
"create", | ||
"--help", | ||
} | ||
|
||
output, err := cmd.CallCmd(t, cmd.APIClients{}, &analytics.NoopClient{}, args) | ||
|
||
require.NoError(t, err) | ||
assert.Contains(t, string(output), "Create a team.") | ||
}) | ||
t.Run("with valid flags calls makeRequest function", func(t *testing.T) { | ||
args := []string{ | ||
"teams", | ||
"create", | ||
"--access-token", | ||
"abcd1234", | ||
"--data", | ||
`{"key": "team-key", "name": "Team Name"}`, | ||
} | ||
|
||
output, err := cmd.CallCmd(t, cmd.APIClients{}, &analytics.NoopClient{}, args) | ||
|
||
require.NoError(t, err) | ||
s := string(output) | ||
assert.Contains(t, s, "would be making a request to /api/v2/teams here, with args: map[data:map[key:team-key name:Team Name] expand:]\n") | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
package resources | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
"net/http" | ||
|
||
"github.com/spf13/cobra" | ||
"github.com/spf13/viper" | ||
|
||
"ldcli/cmd/cliflags" | ||
"ldcli/cmd/validators" | ||
) | ||
|
||
func NewResourceCmd(parentCmd *cobra.Command, resourceName, shortDescription, longDescription string) *cobra.Command { | ||
cmd := &cobra.Command{ | ||
Use: resourceName, | ||
Short: shortDescription, | ||
Long: longDescription, | ||
//TODO: add tracking here | ||
} | ||
|
||
parentCmd.AddCommand(cmd) | ||
|
||
return cmd | ||
} | ||
|
||
type OperationData struct { | ||
Short string | ||
Long string | ||
Use string | ||
Params []Param | ||
HTTPMethod string | ||
RequiresBody bool | ||
Path string | ||
} | ||
|
||
type Param struct { | ||
Name string | ||
In string | ||
Description string | ||
Type string | ||
} | ||
|
||
type OperationCmd struct { | ||
OperationData | ||
client *http.Client | ||
cmd *cobra.Command | ||
} | ||
|
||
func (op *OperationCmd) initFlags() error { | ||
if op.RequiresBody { | ||
op.cmd.Flags().StringP(cliflags.DataFlag, "d", "", "Input data in JSON") | ||
err := op.cmd.MarkFlagRequired(cliflags.DataFlag) | ||
if err != nil { | ||
return err | ||
} | ||
err = viper.BindPFlag(cliflags.DataFlag, op.cmd.Flags().Lookup(cliflags.DataFlag)) | ||
if err != nil { | ||
return err | ||
} | ||
} | ||
|
||
for _, p := range op.Params { | ||
shorthand := fmt.Sprintf(p.Name[0:1]) // todo: how do we handle potential dupes | ||
switch p.Type { | ||
case "string": | ||
op.cmd.Flags().StringP(p.Name, shorthand, "", p.Description) | ||
case "int": | ||
op.cmd.Flags().IntP(p.Name, shorthand, 0, p.Description) | ||
case "boolean": | ||
op.cmd.Flags().BoolP(p.Name, shorthand, false, p.Description) | ||
} | ||
|
||
if p.In == "path" { | ||
err := op.cmd.MarkFlagRequired(p.Name) | ||
if err != nil { | ||
return err | ||
} | ||
} | ||
|
||
err := viper.BindPFlag(p.Name, op.cmd.Flags().Lookup(p.Name)) | ||
if err != nil { | ||
return err | ||
} | ||
} | ||
return nil | ||
} | ||
|
||
func (op *OperationCmd) makeRequest(cmd *cobra.Command, args []string) error { | ||
paramVals := map[string]interface{}{} | ||
|
||
if op.RequiresBody { | ||
var data interface{} | ||
// TODO: why does viper.GetString(cliflags.DataFlag) not work? | ||
err := json.Unmarshal([]byte(cmd.Flags().Lookup(cliflags.DataFlag).Value.String()), &data) | ||
if err != nil { | ||
return err | ||
} | ||
paramVals[cliflags.DataFlag] = data | ||
} | ||
|
||
for _, p := range op.Params { | ||
var val interface{} | ||
switch p.Type { | ||
case "string": | ||
val = viper.GetString(p.Name) | ||
case "boolean": | ||
val = viper.GetBool(p.Name) | ||
case "int": | ||
val = viper.GetInt(p.Name) | ||
} | ||
|
||
if val != nil { | ||
paramVals[p.Name] = val | ||
} | ||
} | ||
|
||
fmt.Fprintf(cmd.OutOrStdout(), "would be making a request to %s here, with args: %s\n", op.Path, paramVals) | ||
|
||
return nil | ||
} | ||
|
||
func NewOperationCmd(parentCmd *cobra.Command, client *http.Client, op OperationData) *cobra.Command { | ||
opCmd := OperationCmd{ | ||
OperationData: op, | ||
client: client, | ||
} | ||
|
||
cmd := &cobra.Command{ | ||
Args: validators.Validate(), | ||
Long: op.Long, | ||
RunE: opCmd.makeRequest, | ||
Short: op.Short, | ||
Use: op.Use, | ||
//TODO: add tracking here | ||
} | ||
|
||
opCmd.cmd = cmd | ||
opCmd.initFlags() | ||
|
||
parentCmd.AddCommand(cmd) | ||
|
||
return cmd | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters