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
38 changes: 38 additions & 0 deletions cmd/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package cmd

import (
"os"
"os/signal"

"github.com/spf13/afero"
"github.com/spf13/cobra"
"github.com/supabase/cli/internal/config/push"
"github.com/supabase/cli/internal/utils/flags"
)

var (
configCmd = &cobra.Command{
GroupID: groupManagementAPI,
Use: "config",
Short: "Manage Supabase project configurations",
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
ctx, _ := signal.NotifyContext(cmd.Context(), os.Interrupt)
cmd.SetContext(ctx)
return cmd.Root().PersistentPreRunE(cmd, args)
},
}

configPushCmd = &cobra.Command{
Use: "push",
Short: "Pushes local config.toml to the linked project",
RunE: func(cmd *cobra.Command, args []string) error {
return push.Run(cmd.Context(), flags.ProjectRef, afero.NewOsFs())
},
}
)

func init() {
configCmd.PersistentFlags().StringVar(&flags.ProjectRef, "project-ref", "", "Project ref of the Supabase project.")
configCmd.AddCommand(configPushCmd)
rootCmd.AddCommand(configCmd)
}
30 changes: 30 additions & 0 deletions internal/config/push/push.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package push

import (
"context"
"fmt"
"os"

"github.com/spf13/afero"
"github.com/supabase/cli/internal/utils"
"github.com/supabase/cli/pkg/config"
)

func Run(ctx context.Context, ref string, fsys afero.Fs) error {
if err := utils.LoadConfigFS(fsys); err != nil {
return err
}
client := config.NewConfigUpdater(*utils.GetSupabase())
fmt.Fprintln(os.Stderr, "Pushing config to project:", ref)
remote, _ := utils.Config.GetRemoteByProjectRef(ref)
console := utils.NewConsole()
keep := func(name string) bool {
title := fmt.Sprintf("Do you want to push %s config to remote?", name)
shouldPush, err := console.PromptYesNo(ctx, title, true)
if err != nil {
fmt.Fprintln(os.Stderr, err)
}
return shouldPush
}
return client.UpdateRemoteConfig(ctx, remote, keep)
}
55 changes: 38 additions & 17 deletions pkg/config/updater.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,26 +17,26 @@ func NewConfigUpdater(client v1API.ClientWithResponses) ConfigUpdater {
return ConfigUpdater{client: client}
}

func (u *ConfigUpdater) UpdateRemoteConfig(ctx context.Context, remote baseConfig) error {
if err := u.UpdateApiConfig(ctx, remote.ProjectId, remote.Api); err != nil {
func (u *ConfigUpdater) UpdateRemoteConfig(ctx context.Context, remote baseConfig, filter ...func(string) bool) error {
if err := u.UpdateApiConfig(ctx, remote.ProjectId, remote.Api, filter...); err != nil {
return err
}
if err := u.UpdateDbConfig(ctx, remote.ProjectId, remote.Db); err != nil {
if err := u.UpdateDbConfig(ctx, remote.ProjectId, remote.Db, filter...); err != nil {
return err
}
if err := u.UpdateAuthConfig(ctx, remote.ProjectId, remote.Auth); err != nil {
if err := u.UpdateAuthConfig(ctx, remote.ProjectId, remote.Auth, filter...); err != nil {
return err
}
if err := u.UpdateStorageConfig(ctx, remote.ProjectId, remote.Storage); err != nil {
if err := u.UpdateStorageConfig(ctx, remote.ProjectId, remote.Storage, filter...); err != nil {
return err
}
if err := u.UpdateExperimentalConfig(ctx, remote.ProjectId, remote.Experimental); err != nil {
if err := u.UpdateExperimentalConfig(ctx, remote.ProjectId, remote.Experimental, filter...); err != nil {
return err
}
return nil
}

func (u *ConfigUpdater) UpdateApiConfig(ctx context.Context, projectRef string, c api) error {
func (u *ConfigUpdater) UpdateApiConfig(ctx context.Context, projectRef string, c api, filter ...func(string) bool) error {
apiConfig, err := u.client.V1GetPostgrestServiceConfigWithResponse(ctx, projectRef)
if err != nil {
return errors.Errorf("failed to read API config: %w", err)
Expand All @@ -51,7 +51,11 @@ func (u *ConfigUpdater) UpdateApiConfig(ctx context.Context, projectRef string,
return nil
}
fmt.Fprintln(os.Stderr, "Updating API service with config:", string(apiDiff))

for _, keep := range filter {
if !keep("api") {
return nil
}
}
if resp, err := u.client.V1UpdatePostgrestServiceConfigWithResponse(ctx, projectRef, c.ToUpdatePostgrestConfigBody()); err != nil {
return errors.Errorf("failed to update API config: %w", err)
} else if resp.JSON200 == nil {
Expand All @@ -60,7 +64,7 @@ func (u *ConfigUpdater) UpdateApiConfig(ctx context.Context, projectRef string,
return nil
}

func (u *ConfigUpdater) UpdateDbSettingsConfig(ctx context.Context, projectRef string, s settings) error {
func (u *ConfigUpdater) UpdateDbSettingsConfig(ctx context.Context, projectRef string, s settings, filter ...func(string) bool) error {
dbConfig, err := u.client.V1GetPostgresConfigWithResponse(ctx, projectRef)
if err != nil {
return errors.Errorf("failed to read DB config: %w", err)
Expand All @@ -75,6 +79,11 @@ func (u *ConfigUpdater) UpdateDbSettingsConfig(ctx context.Context, projectRef s
return nil
}
fmt.Fprintln(os.Stderr, "Updating DB service with config:", string(dbDiff))
for _, keep := range filter {
if !keep("db") {
return nil
}
}
updateBody := s.ToUpdatePostgresConfigBody()
if resp, err := u.client.V1UpdatePostgresConfigWithResponse(ctx, projectRef, updateBody); err != nil {
return errors.Errorf("failed to update DB config: %w", err)
Expand All @@ -84,14 +93,14 @@ func (u *ConfigUpdater) UpdateDbSettingsConfig(ctx context.Context, projectRef s
return nil
}

func (u *ConfigUpdater) UpdateDbConfig(ctx context.Context, projectRef string, c db) error {
if err := u.UpdateDbSettingsConfig(ctx, projectRef, c.Settings); err != nil {
func (u *ConfigUpdater) UpdateDbConfig(ctx context.Context, projectRef string, c db, filter ...func(string) bool) error {
if err := u.UpdateDbSettingsConfig(ctx, projectRef, c.Settings, filter...); err != nil {
return err
}
return nil
}

func (u *ConfigUpdater) UpdateAuthConfig(ctx context.Context, projectRef string, c auth) error {
func (u *ConfigUpdater) UpdateAuthConfig(ctx context.Context, projectRef string, c auth, filter ...func(string) bool) error {
if !c.Enabled {
return nil
}
Expand All @@ -109,7 +118,11 @@ func (u *ConfigUpdater) UpdateAuthConfig(ctx context.Context, projectRef string,
return nil
}
fmt.Fprintln(os.Stderr, "Updating Auth service with config:", string(authDiff))

for _, keep := range filter {
if !keep("auth") {
return nil
}
}
if resp, err := u.client.V1UpdateAuthServiceConfigWithResponse(ctx, projectRef, c.ToUpdateAuthConfigBody()); err != nil {
return errors.Errorf("failed to update Auth config: %w", err)
} else if status := resp.StatusCode(); status < 200 || status >= 300 {
Expand All @@ -118,7 +131,7 @@ func (u *ConfigUpdater) UpdateAuthConfig(ctx context.Context, projectRef string,
return nil
}

func (u *ConfigUpdater) UpdateStorageConfig(ctx context.Context, projectRef string, c storage) error {
func (u *ConfigUpdater) UpdateStorageConfig(ctx context.Context, projectRef string, c storage, filter ...func(string) bool) error {
if !c.Enabled {
return nil
}
Expand All @@ -136,7 +149,11 @@ func (u *ConfigUpdater) UpdateStorageConfig(ctx context.Context, projectRef stri
return nil
}
fmt.Fprintln(os.Stderr, "Updating Storage service with config:", string(storageDiff))

for _, keep := range filter {
if !keep("storage") {
return nil
}
}
if resp, err := u.client.V1UpdateStorageConfigWithResponse(ctx, projectRef, c.ToUpdateStorageConfigBody()); err != nil {
return errors.Errorf("failed to update Storage config: %w", err)
} else if status := resp.StatusCode(); status < 200 || status >= 300 {
Expand All @@ -145,10 +162,14 @@ func (u *ConfigUpdater) UpdateStorageConfig(ctx context.Context, projectRef stri
return nil
}

func (u *ConfigUpdater) UpdateExperimentalConfig(ctx context.Context, projectRef string, exp experimental) error {
func (u *ConfigUpdater) UpdateExperimentalConfig(ctx context.Context, projectRef string, exp experimental, filter ...func(string) bool) error {
if exp.Webhooks != nil && exp.Webhooks.Enabled {
fmt.Fprintln(os.Stderr, "Enabling webhooks for project:", projectRef)

for _, keep := range filter {
if !keep("webhooks") {
return nil
}
}
if resp, err := u.client.V1EnableDatabaseWebhookWithResponse(ctx, projectRef); err != nil {
return errors.Errorf("failed to enable webhooks: %w", err)
} else if status := resp.StatusCode(); status < 200 || status >= 300 {
Expand Down