Skip to content

Commit

Permalink
feat: Add flags create command (#56)
Browse files Browse the repository at this point in the history
Add flags create command
  • Loading branch information
dbolson authored Mar 22, 2024
1 parent 6b48414 commit 19add8d
Show file tree
Hide file tree
Showing 9 changed files with 172 additions and 19 deletions.
91 changes: 91 additions & 0 deletions cmd/flags/create.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package flags

import (
"context"
"encoding/json"
"fmt"
"net/url"

"github.com/spf13/cobra"
"github.com/spf13/viper"

"ld-cli/internal/errors"
"ld-cli/internal/flags"
)

func NewCreateCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "create",
Short: "Create a new flag",
Long: "Create a new flag",
PreRunE: validate,
RunE: runCreate,
}

cmd.Flags().StringP("data", "d", "", "Input data in JSON")
err := cmd.MarkFlagRequired("data")
if err != nil {
panic(err)
}
err = viper.BindPFlag("data", cmd.Flags().Lookup("data"))
if err != nil {
panic(err)
}

cmd.Flags().String("projKey", "", "Project key")
err = cmd.MarkFlagRequired("projKey")
if err != nil {
panic(err)
}
err = viper.BindPFlag("projKey", cmd.Flags().Lookup("projKey"))
if err != nil {
panic(err)
}

return cmd
}

type inputData struct {
Name string `json:"name"`
Key string `json:"key"`
}

func runCreate(cmd *cobra.Command, args []string) error {
client := flags.NewClient(
viper.GetString("accessToken"),
viper.GetString("baseUri"),
)

var data inputData
err := json.Unmarshal([]byte(cmd.Flags().Lookup("data").Value.String()), &data)
// err := json.Unmarshal([]byte(viper.GetString("data")), &data)
if err != nil {
return err
}
projKey := viper.GetString("projKey")

response, err := client.Create(
context.Background(),
data.Name,
data.Key,
projKey,
)
if err != nil {
return err
}

fmt.Fprintf(cmd.OutOrStdout(), string(response)+"\n")

return nil
}

// validate ensures the flags are valid before using them.
// TODO: refactor with projects validate().
func validate(cmd *cobra.Command, args []string) error {
_, err := url.ParseRequestURI(viper.GetString("baseUri"))
if err != nil {
return errors.ErrInvalidBaseURI
}

return nil
}
15 changes: 15 additions & 0 deletions cmd/flags/flags.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package flags

import "github.com/spf13/cobra"

func NewFlagsCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "flags",
Short: "Make requests (list, create, etc.) on flags",
Long: "Make requests (list, create, etc.) on flags",
}

cmd.AddCommand(NewCreateCmd())

return cmd
}
14 changes: 3 additions & 11 deletions cmd/projects/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"encoding/json"
"fmt"

"github.com/spf13/cobra"
"github.com/spf13/viper"

Expand All @@ -19,14 +20,7 @@ func NewCreateCmd() *cobra.Command {
RunE: runCreate,
}

var data string
cmd.Flags().StringVarP(
&data,
"data",
"d",
"",
"Input data in JSON",
)
cmd.Flags().StringP("data", "d", "", "Input data in JSON")
err := cmd.MarkFlagRequired("data")
if err != nil {
panic(err)
Expand All @@ -50,10 +44,8 @@ func runCreate(cmd *cobra.Command, args []string) error {
viper.GetString("baseUri"),
)

dataStr := viper.GetString("data")

var data inputData
err := json.Unmarshal([]byte(dataStr), &data)
err := json.Unmarshal([]byte(viper.GetString("data")), &data)
if err != nil {
return err
}
Expand Down
1 change: 1 addition & 0 deletions cmd/projects/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ func NewListCmd() *cobra.Command {
}

// validate ensures the flags are valid before using them.
// TODO: refactor with flags validate().
func validate(cmd *cobra.Command, args []string) error {
_, err := url.ParseRequestURI(viper.GetString("baseUri"))
if err != nil {
Expand Down
4 changes: 1 addition & 3 deletions cmd/projects/projects.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package projects

import (
"github.com/spf13/cobra"
)
import "github.com/spf13/cobra"

func NewProjectsCmd() *cobra.Command {
cmd := &cobra.Command{
Expand Down
5 changes: 3 additions & 2 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ import (
"fmt"
"os"

errs "ld-cli/internal/errors"

"github.com/spf13/cobra"
"github.com/spf13/viper"

"ld-cli/cmd/flags"
"ld-cli/cmd/projects"
errs "ld-cli/internal/errors"
)

func newRootCommand() *cobra.Command {
Expand Down Expand Up @@ -60,6 +60,7 @@ func newRootCommand() *cobra.Command {
panic(err)
}

cmd.AddCommand(flags.NewFlagsCmd())
cmd.AddCommand(projects.NewProjectsCmd())
cmd.AddCommand(setupCmd)

Expand Down
55 changes: 55 additions & 0 deletions internal/flags/flags.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package flags

import (
"context"
"encoding/json"

ldapi "github.com/launchdarkly/api-client-go/v14"

"ld-cli/internal/errors"
)

type Client interface {
Create(ctx context.Context, name string, key string, projectKey string) ([]byte, error)
}

type FlagsClient struct {
client *ldapi.APIClient
}

func NewClient(accessToken string, baseURI string) FlagsClient {
config := ldapi.NewConfiguration()
config.AddDefaultHeader("Authorization", accessToken)
config.Servers[0].URL = baseURI
client := ldapi.NewAPIClient(config)

return FlagsClient{
client: client,
}
}

func (c FlagsClient) Create(
ctx context.Context,
name string,
key string,
projectKey string,
) ([]byte, error) {
post := ldapi.NewFeatureFlagBody(name, key)
flag, _, err := c.client.FeatureFlagsApi.PostFeatureFlag(ctx, projectKey).FeatureFlagBody(*post).Execute()
if err != nil {
switch err.Error() {
case "401 Unauthorized":
return nil, errors.ErrUnauthorized
case "403 Forbidden":
return nil, errors.ErrForbidden
default:
return nil, err
}
}
responseJSON, err := json.Marshal(flag)
if err != nil {
return nil, err
}

return responseJSON, nil
}
2 changes: 1 addition & 1 deletion internal/setup/flag_toggle.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ func (m flagToggleModel) View() string {
return title + "\n\n" + toggleStyle.Render(toggle) + m.flagKey + furtherInstructions
}

func (m flagToggleModel) toggleFlag() error {
func (m flagToggleModel) toggleFlag() error { //nolint:unused
url := fmt.Sprintf("http://localhost/api/v2/flags/default/%s", m.flagKey)
c := &http.Client{
Timeout: 10 * time.Second,
Expand Down
4 changes: 2 additions & 2 deletions internal/setup/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,9 @@ func (m flagModel) View() string {
) + "\n"
}

const apiToken = ""
const apiToken = "" //nolint:unused

func (m flagModel) createFlag() error {
func (m flagModel) createFlag() error { //nolint:unused
url := "http://localhost/api/v2/flags/default"
c := &http.Client{
Timeout: 10 * time.Second,
Expand Down

0 comments on commit 19add8d

Please sign in to comment.