Skip to content

Commit

Permalink
Add support for output flag to projects commands
Browse files Browse the repository at this point in the history
  • Loading branch information
djhi committed Sep 11, 2024
1 parent 62e2a9f commit 52ccf82
Show file tree
Hide file tree
Showing 8 changed files with 74 additions and 47 deletions.
6 changes: 3 additions & 3 deletions cmd/projects.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ var (
if cmd.Flags().Changed("size") {
body.DesiredInstanceSize = (*api.DesiredInstanceSize)(&size.Value)
}
return create.Run(cmd.Context(), body, afero.NewOsFs())
return create.Run(cmd.Context(), body, viper.GetString("output"), afero.NewOsFs())
},
}

Expand All @@ -87,15 +87,15 @@ var (
Short: "List all Supabase projects",
Long: "List all Supabase projects the logged-in user can access.",
RunE: func(cmd *cobra.Command, args []string) error {
return list.Run(cmd.Context(), afero.NewOsFs())
return list.Run(cmd.Context(), viper.GetString("output"), afero.NewOsFs())
},
}

projectsApiKeysCmd = &cobra.Command{
Use: "api-keys",
Short: "List all API keys for a Supabase project",
RunE: func(cmd *cobra.Command, args []string) error {
return apiKeys.Run(cmd.Context(), flags.ProjectRef, afero.NewOsFs())
return apiKeys.Run(cmd.Context(), flags.ProjectRef, viper.GetString("output"), afero.NewOsFs())
},
}

Expand Down
2 changes: 1 addition & 1 deletion internal/bootstrap/bootstrap.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ func Run(ctx context.Context, starter StarterTemplate, fsys afero.Fs, options ..
Name: filepath.Base(workdir),
TemplateUrl: &starter.Url,
}
if err := create.Run(ctx, params, fsys); err != nil {
if err := create.Run(ctx, params, utils.OutputPretty, fsys); err != nil {
return err
}
// 3. Get api keys
Expand Down
15 changes: 10 additions & 5 deletions internal/projects/apiKeys/api_keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package apiKeys
import (
"context"
"fmt"
"os"
"strings"

"github.com/go-errors/errors"
Expand All @@ -12,20 +13,24 @@ import (
"github.com/supabase/cli/pkg/api"
)

func Run(ctx context.Context, projectRef string, fsys afero.Fs) error {
func Run(ctx context.Context, projectRef string, format string, fsys afero.Fs) error {
keys, err := RunGetApiKeys(ctx, projectRef)
if err != nil {
return err
}

table := `|NAME|KEY VALUE|
if format == utils.OutputPretty {
table := `|NAME|KEY VALUE|
|-|-|
`
for _, entry := range keys {
table += fmt.Sprintf("|`%s`|`%s`|\n", strings.ReplaceAll(entry.Name, "|", "\\|"), entry.ApiKey)
for _, entry := range keys {
table += fmt.Sprintf("|`%s`|`%s`|\n", strings.ReplaceAll(entry.Name, "|", "\\|"), entry.ApiKey)
}

return list.RenderTable(table)
}

return list.RenderTable(table)
return utils.EncodeOutput(format, os.Stdout, keys)
}

func RunGetApiKeys(ctx context.Context, projectRef string) ([]api.ApiKeyResponse, error) {
Expand Down
6 changes: 3 additions & 3 deletions internal/projects/apiKeys/api_keys_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func TestProjectApiKeysCommand(t *testing.T) {
ApiKey: "dummy-api-key-value",
}})
// Run test
err := Run(context.Background(), project, fsys)
err := Run(context.Background(), project, utils.OutputPretty, fsys)
// Check error
assert.NoError(t, err)
assert.Empty(t, apitest.ListUnmatchedRequests())
Expand All @@ -42,7 +42,7 @@ func TestProjectApiKeysCommand(t *testing.T) {
// Setup in-memory fs
fsys := afero.NewMemMapFs()
// Run test
err := Run(context.Background(), "", fsys)
err := Run(context.Background(), "", utils.OutputPretty, fsys)
// Check error
assert.ErrorContains(t, err, "Unexpected error retrieving project api-keys")
})
Expand All @@ -61,7 +61,7 @@ func TestProjectApiKeysCommand(t *testing.T) {
Get("/v1/projects/" + project + "/api-keys").
ReplyError(errors.New("network error"))
// Run test
err := Run(context.Background(), project, fsys)
err := Run(context.Background(), project, utils.OutputPretty, fsys)
// Check error
assert.ErrorContains(t, err, "network error")
assert.Empty(t, apitest.ListUnmatchedRequests())
Expand Down
11 changes: 8 additions & 3 deletions internal/projects/create/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import (
"github.com/supabase/cli/pkg/api"
)

func Run(ctx context.Context, params api.V1CreateProjectBody, fsys afero.Fs) error {
func Run(ctx context.Context, params api.V1CreateProjectBody, format string, fsys afero.Fs) error {
if err := promptMissingParams(ctx, &params); err != nil {
return err
}
Expand All @@ -35,8 +35,13 @@ func Run(ctx context.Context, params api.V1CreateProjectBody, fsys afero.Fs) err
}

projectUrl := fmt.Sprintf("%s/project/%s", utils.GetSupabaseDashboardURL(), resp.JSON201.Id)
fmt.Printf("Created a new project %s at %s\n", utils.Aqua(resp.JSON201.Name), utils.Bold(projectUrl))
return nil

if format == utils.OutputPretty {
fmt.Printf("Created a new project %s at %s\n", utils.Aqua(resp.JSON201.Name), utils.Bold(projectUrl))
return nil
}

return utils.EncodeOutput(format, os.Stdout, resp.JSON201)
}

func printKeyValue(key, value string) string {
Expand Down
10 changes: 5 additions & 5 deletions internal/projects/create/create_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,13 @@ func TestProjectCreateCommand(t *testing.T) {
CreatedAt: "2022-04-25T02:14:55.906498Z",
})
// Run test
assert.NoError(t, Run(context.Background(), params, fsys))
assert.NoError(t, Run(context.Background(), params, utils.OutputPretty, fsys))
// Validate api
assert.Empty(t, apitest.ListUnmatchedRequests())
})

t.Run("throws error on failure to load token", func(t *testing.T) {
assert.Error(t, Run(context.Background(), params, afero.NewMemMapFs()))
assert.Error(t, Run(context.Background(), params, utils.OutputPretty, afero.NewMemMapFs()))
})

t.Run("throws error on network error", func(t *testing.T) {
Expand All @@ -65,7 +65,7 @@ func TestProjectCreateCommand(t *testing.T) {
JSON(params).
ReplyError(errors.New("network error"))
// Run test
assert.Error(t, Run(context.Background(), params, fsys))
assert.Error(t, Run(context.Background(), params, utils.OutputPretty, fsys))
// Validate api
assert.Empty(t, apitest.ListUnmatchedRequests())
})
Expand All @@ -85,7 +85,7 @@ func TestProjectCreateCommand(t *testing.T) {
Reply(500).
JSON(map[string]string{"message": "unavailable"})
// Run test
assert.Error(t, Run(context.Background(), params, fsys))
assert.Error(t, Run(context.Background(), params, utils.OutputPretty, fsys))
// Validate api
assert.Empty(t, apitest.ListUnmatchedRequests())
})
Expand All @@ -105,7 +105,7 @@ func TestProjectCreateCommand(t *testing.T) {
Reply(200).
JSON([]string{})
// Run test
assert.Error(t, Run(context.Background(), params, fsys))
assert.Error(t, Run(context.Background(), params, utils.OutputPretty, fsys))
// Validate api
assert.Empty(t, apitest.ListUnmatchedRequests())
})
Expand Down
61 changes: 39 additions & 22 deletions internal/projects/list/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@ import (
"github.com/supabase/cli/internal/migration/list"
"github.com/supabase/cli/internal/utils"
"github.com/supabase/cli/internal/utils/flags"
"github.com/supabase/cli/pkg/api"
)

func Run(ctx context.Context, fsys afero.Fs) error {
func Run(ctx context.Context, format string, fsys afero.Fs) error {
resp, err := utils.GetSupabase().V1ListAllProjectsWithResponse(ctx)
if err != nil {
return errors.Errorf("failed to list projects: %w", err)
Expand All @@ -29,30 +30,46 @@ func Run(ctx context.Context, fsys afero.Fs) error {
fmt.Fprintln(os.Stderr, err)
}

table := `LINKED|ORG ID|REFERENCE ID|NAME|REGION|CREATED AT (UTC)
if format == utils.OutputPretty {
table := `LINKED|ORG ID|REFERENCE ID|NAME|REGION|CREATED AT (UTC)
|-|-|-|-|-|-|
`
for _, project := range *resp.JSON200 {
if t, err := time.Parse(time.RFC3339, project.CreatedAt); err == nil {
project.CreatedAt = t.UTC().Format("2006-01-02 15:04:05")
}
if region, ok := utils.RegionMap[project.Region]; ok {
project.Region = region
for _, project := range *resp.JSON200 {
if t, err := time.Parse(time.RFC3339, project.CreatedAt); err == nil {
project.CreatedAt = t.UTC().Format("2006-01-02 15:04:05")
}
if region, ok := utils.RegionMap[project.Region]; ok {
project.Region = region
}
linked := " "
if project.Id == projectRef {
linked = " ●"
}
table += fmt.Sprintf(
"|`%s`|`%s`|`%s`|`%s`|`%s`|`%s`|\n",
linked,
project.OrganizationId,
project.Id,
strings.ReplaceAll(project.Name, "|", "\\|"),
project.Region,
utils.FormatTimestamp(project.CreatedAt),
)
}
linked := " "
if project.Id == projectRef {
linked = " ●"
}
table += fmt.Sprintf(
"|`%s`|`%s`|`%s`|`%s`|`%s`|`%s`|\n",
linked,
project.OrganizationId,
project.Id,
strings.ReplaceAll(project.Name, "|", "\\|"),
project.Region,
utils.FormatTimestamp(project.CreatedAt),
)

return list.RenderTable(table)
}

return list.RenderTable(table)
var projects []Project
for _, project := range *resp.JSON200 {
projects = append(projects, Project{
V1ProjectResponse: project,
Linked: project.Id == projectRef,
})
}
return utils.EncodeOutput(format, os.Stdout, projects)
}

type Project struct {
api.V1ProjectResponse
Linked bool `json:"linked"`
}
10 changes: 5 additions & 5 deletions internal/projects/list/list_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,13 @@ func TestProjectListCommand(t *testing.T) {
},
})
// Run test
assert.NoError(t, Run(context.Background(), fsys))
assert.NoError(t, Run(context.Background(), utils.OutputPretty, fsys))
// Validate api
assert.Empty(t, apitest.ListUnmatchedRequests())
})

t.Run("throws error on failure to load token", func(t *testing.T) {
assert.Error(t, Run(context.Background(), afero.NewMemMapFs()))
assert.Error(t, Run(context.Background(), utils.OutputPretty, afero.NewMemMapFs()))
})

t.Run("throws error on network error", func(t *testing.T) {
Expand All @@ -56,7 +56,7 @@ func TestProjectListCommand(t *testing.T) {
Get("/v1/projects").
ReplyError(errors.New("network error"))
// Run test
assert.Error(t, Run(context.Background(), fsys))
assert.Error(t, Run(context.Background(), utils.OutputPretty, fsys))
// Validate api
assert.Empty(t, apitest.ListUnmatchedRequests())
})
Expand All @@ -74,7 +74,7 @@ func TestProjectListCommand(t *testing.T) {
Reply(500).
JSON(map[string]string{"message": "unavailable"})
// Run test
assert.Error(t, Run(context.Background(), fsys))
assert.Error(t, Run(context.Background(), utils.OutputPretty, fsys))
// Validate api
assert.Empty(t, apitest.ListUnmatchedRequests())
})
Expand All @@ -92,7 +92,7 @@ func TestProjectListCommand(t *testing.T) {
Reply(200).
JSON(map[string]string{})
// Run test
assert.Error(t, Run(context.Background(), fsys))
assert.Error(t, Run(context.Background(), utils.OutputPretty, fsys))
// Validate api
assert.Empty(t, apitest.ListUnmatchedRequests())
})
Expand Down

0 comments on commit 52ccf82

Please sign in to comment.