From dc45095c74f73c0b156468933a4c2a967d971b09 Mon Sep 17 00:00:00 2001 From: Qiao Han Date: Fri, 10 Jan 2025 16:31:50 +0800 Subject: [PATCH] fix: restore project id from base config --- internal/config/push/push.go | 6 +++++- internal/db/push/push.go | 1 + pkg/config/config.go | 30 ++++++++++++++++++++---------- 3 files changed, 26 insertions(+), 11 deletions(-) diff --git a/internal/config/push/push.go b/internal/config/push/push.go index 8374caeba..d2dadddc3 100644 --- a/internal/config/push/push.go +++ b/internal/config/push/push.go @@ -16,7 +16,11 @@ func Run(ctx context.Context, ref string, fsys afero.Fs) error { return err } client := config.NewConfigUpdater(*utils.GetSupabase()) - remote, _ := utils.Config.GetRemoteByProjectRef(ref) + remote, err := utils.Config.GetRemoteByProjectRef(ref) + if err != nil { + // Use base config when no remote is declared + remote.ProjectId = ref + } fmt.Fprintln(os.Stderr, "Pushing config to project:", remote.ProjectId) console := utils.NewConsole() keep := func(name string) bool { diff --git a/internal/db/push/push.go b/internal/db/push/push.go index 99a42932a..7e5241558 100644 --- a/internal/db/push/push.go +++ b/internal/db/push/push.go @@ -31,6 +31,7 @@ func Run(ctx context.Context, dryRun, ignoreVersionMismatch bool, includeRoles, } var seeds []migration.SeedFile if includeSeed { + // TODO: flag should override config but we don't resolve glob paths when seed is disabled. if !utils.Config.Db.Seed.Enabled { fmt.Fprintln(os.Stderr, "Skipping seed because it is disabled in config.toml for project:", flags.ProjectRef) } else if seeds, err = migration.GetPendingSeeds(ctx, utils.Config.Db.Seed.SqlPaths, conn, afero.NewIOFS(fsys)); err != nil { diff --git a/pkg/config/config.go b/pkg/config/config.go index 24d96c285..93cc252c9 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -407,16 +407,21 @@ func (c *config) loadFromReader(v *viper.Viper, r io.Reader) error { return errors.Errorf("failed to merge config: %w", err) } // Find [remotes.*] block to override base config + baseId := v.GetString("project_id") + idToName := map[string]string{baseId: "base"} for name, remote := range v.GetStringMap("remotes") { - if m, ok := remote.(map[string]any); ok && m["project_id"] == c.ProjectId { - fmt.Fprintln(os.Stderr, "Loading remote override:", name) - // On remotes branches set seed as disabled by default - v.Set("db.seed.enabled", false) - // TODO: warn duplicate project_id in remotes - delete(m, "project_id") - if err := v.MergeConfigMap(m); err != nil { + projectId := v.GetString(fmt.Sprintf("remotes.%s.project_id", name)) + // Track remote project_id to check for duplication + if other, exists := idToName[projectId]; exists { + return errors.Errorf("duplicate project_id for [remotes.%s] and %s", name, other) + } + idToName[projectId] = fmt.Sprintf("[remotes.%s]", name) + if projectId == c.ProjectId { + fmt.Fprintln(os.Stderr, "Loading config override:", idToName[projectId]) + if err := v.MergeConfigMap(remote.(map[string]any)); err != nil { return err } + v.Set("project_id", baseId) } } // Manually parse [functions.*] to empty struct for backwards compatibility @@ -1308,11 +1313,16 @@ func (c *baseConfig) GetServiceImages() []string { } // Retrieve the final base config to use taking into account the remotes override +// Pre: config must be loaded after setting config.ProjectID = "ref" func (c *config) GetRemoteByProjectRef(projectRef string) (baseConfig, error) { - // Config must be loaded after setting config.ProjectID = "ref" base := c.baseConfig.Clone() - base.ProjectId = projectRef - return base, nil + for _, remote := range c.Remotes { + if remote.ProjectId == projectRef { + base.ProjectId = projectRef + return base, nil + } + } + return base, errors.Errorf("no remote found for project_id: %s", projectRef) } func ToTomlBytes(config any) ([]byte, error) {