Skip to content

Commit 327dfc1

Browse files
committed
feat: support profile flag for development
1 parent 16fa45c commit 327dfc1

File tree

5 files changed

+99
-41
lines changed

5 files changed

+99
-41
lines changed

cmd/root.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,13 +92,16 @@ var (
9292
return errors.New("must set the --experimental flag to run this command")
9393
}
9494
cmd.SilenceUsage = true
95-
// Change workdir
95+
// Load profile before changing workdir
96+
ctx := cmd.Context()
9697
fsys := afero.NewOsFs()
98+
if err := utils.LoadProfile(ctx, fsys); err != nil {
99+
return err
100+
}
97101
if err := utils.ChangeWorkDir(fsys); err != nil {
98102
return err
99103
}
100104
// Add common flags
101-
ctx := cmd.Context()
102105
if IsManagementAPI(cmd) {
103106
if err := promptLogin(fsys); err != nil {
104107
return err
@@ -236,6 +239,7 @@ func init() {
236239
flags.String("workdir", "", "path to a Supabase project directory")
237240
flags.Bool("experimental", false, "enable experimental features")
238241
flags.String("network-id", "", "use the specified docker network instead of a generated one")
242+
flags.String("profile", "supabase", "use a specific profile for connecting to Supabase API")
239243
flags.VarP(&utils.OutputFormat, "output", "o", "output format of status variables")
240244
flags.Var(&utils.DNSResolver, "dns-resolver", "lookup domain names using the specified resolver")
241245
flags.BoolVar(&createTicket, "create-ticket", false, "create a support ticket for any CLI error")

go.mod

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ require (
2020
github.com/getsentry/sentry-go v0.35.1
2121
github.com/go-errors/errors v1.5.1
2222
github.com/go-git/go-git/v5 v5.16.2
23+
github.com/go-playground/validator/v10 v10.27.0
24+
github.com/go-viper/mapstructure/v2 v2.4.0
2325
github.com/go-xmlfmt/xmlfmt v1.1.3
2426
github.com/google/go-github/v62 v62.0.0
2527
github.com/google/go-querystring v1.1.0
@@ -131,6 +133,7 @@ require (
131133
github.com/firefart/nonamedreturns v1.0.6 // indirect
132134
github.com/fvbommel/sortorder v1.1.0 // indirect
133135
github.com/fzipp/gocyclo v0.6.0 // indirect
136+
github.com/gabriel-vasile/mimetype v1.4.8 // indirect
134137
github.com/getkin/kin-openapi v0.131.0 // indirect
135138
github.com/ghostiam/protogetter v0.3.15 // indirect
136139
github.com/go-critic/go-critic v0.13.0 // indirect
@@ -140,14 +143,15 @@ require (
140143
github.com/go-logr/stdr v1.2.2 // indirect
141144
github.com/go-openapi/jsonpointer v0.21.0 // indirect
142145
github.com/go-openapi/swag v0.23.1 // indirect
146+
github.com/go-playground/locales v0.14.1 // indirect
147+
github.com/go-playground/universal-translator v0.18.1 // indirect
143148
github.com/go-toolsmith/astcast v1.1.0 // indirect
144149
github.com/go-toolsmith/astcopy v1.1.0 // indirect
145150
github.com/go-toolsmith/astequal v1.2.0 // indirect
146151
github.com/go-toolsmith/astfmt v1.1.0 // indirect
147152
github.com/go-toolsmith/astp v1.1.0 // indirect
148153
github.com/go-toolsmith/strparse v1.1.0 // indirect
149154
github.com/go-toolsmith/typep v1.1.0 // indirect
150-
github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
151155
github.com/gobwas/glob v0.2.3 // indirect
152156
github.com/godbus/dbus/v5 v5.1.0 // indirect
153157
github.com/gofrs/flock v0.12.1 // indirect
@@ -206,6 +210,7 @@ require (
206210
github.com/ldez/grignotin v0.9.0 // indirect
207211
github.com/ldez/tagliatelle v0.7.1 // indirect
208212
github.com/ldez/usetesting v0.4.3 // indirect
213+
github.com/leodido/go-urn v1.4.0 // indirect
209214
github.com/leonklingele/grouper v1.1.2 // indirect
210215
github.com/lib/pq v1.10.9 // indirect
211216
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect

go.sum

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,8 @@ github.com/fvbommel/sortorder v1.1.0 h1:fUmoe+HLsBTctBDoaBwpQo5N+nrCp8g/BjKb/6ZQ
296296
github.com/fvbommel/sortorder v1.1.0/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0=
297297
github.com/fzipp/gocyclo v0.6.0 h1:lsblElZG7d3ALtGMx9fmxeTKZaLLpU8mET09yN4BBLo=
298298
github.com/fzipp/gocyclo v0.6.0/go.mod h1:rXPyn8fnlpa0R2csP/31uerbiVBugk5whMdlyaLkLoA=
299+
github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM=
300+
github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8=
299301
github.com/getkin/kin-openapi v0.131.0 h1:NO2UeHnFKRYhZ8wg6Nyh5Cq7dHk4suQQr72a4pMrDxE=
300302
github.com/getkin/kin-openapi v0.131.0/go.mod h1:3OlG51PCYNsPByuiMB0t4fjnNlIDnaEDsjiKUV8nL58=
301303
github.com/getsentry/sentry-go v0.35.1 h1:iopow6UVLE2aXu46xKVIs8Z9D/YZkJrHkgozrxa+tOQ=
@@ -334,6 +336,14 @@ github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1
334336
github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY=
335337
github.com/go-openapi/swag v0.23.1 h1:lpsStH0n2ittzTnbaSloVZLuB5+fvSY/+hnagBjSNZU=
336338
github.com/go-openapi/swag v0.23.1/go.mod h1:STZs8TbRvEQQKUA+JZNAm3EWlgaOBGpyFDqQnDHMef0=
339+
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
340+
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
341+
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
342+
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
343+
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
344+
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
345+
github.com/go-playground/validator/v10 v10.27.0 h1:w8+XrWVMhGkxOaaowyKH35gFydVHOvC0/uWoy2Fzwn4=
346+
github.com/go-playground/validator/v10 v10.27.0/go.mod h1:I5QpIEbmr8On7W0TktmJAumgzX4CA1XNl4ZmDuVHKKo=
337347
github.com/go-quicktest/qt v1.101.0 h1:O1K29Txy5P2OK0dGo59b7b0LR6wKfIhttaAhHUyn7eI=
338348
github.com/go-quicktest/qt v1.101.0/go.mod h1:14Bz/f7NwaXPtdYEgzsx46kqSxVwTbzVZsDC26tQJow=
339349
github.com/go-sql-driver/mysql v1.3.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
@@ -641,6 +651,8 @@ github.com/ldez/tagliatelle v0.7.1 h1:bTgKjjc2sQcsgPiT902+aadvMjCeMHrY7ly2XKFORI
641651
github.com/ldez/tagliatelle v0.7.1/go.mod h1:3zjxUpsNB2aEZScWiZTHrAXOl1x25t3cRmzfK1mlo2I=
642652
github.com/ldez/usetesting v0.4.3 h1:pJpN0x3fMupdTf/IapYjnkhiY1nSTN+pox1/GyBRw3k=
643653
github.com/ldez/usetesting v0.4.3/go.mod h1:eEs46T3PpQ+9RgN9VjpY6qWdiw2/QmfiDeWmdZdrjIQ=
654+
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
655+
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
644656
github.com/leonklingele/grouper v1.1.2 h1:o1ARBDLOmmasUaNDesWqWCIFH3u7hoFlM84YrjT3mIY=
645657
github.com/leonklingele/grouper v1.1.2/go.mod h1:6D0M/HVkhs2yRKRFZUoGjeDy7EZTfFBE9gl4kjmIGkA=
646658
github.com/lib/pq v0.0.0-20150723085316-0dad96c0b94f/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=

internal/utils/api.go

Lines changed: 7 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import (
1111

1212
"github.com/go-errors/errors"
1313
"github.com/spf13/afero"
14-
"github.com/spf13/viper"
1514
"github.com/supabase/cli/internal/utils/cloudflare"
1615
supabase "github.com/supabase/cli/pkg/api"
1716
"github.com/supabase/cli/pkg/cast"
@@ -139,11 +138,7 @@ func GetSupabase() *supabase.ClientWithResponses {
139138
return apiClient
140139
}
141140

142-
const (
143-
DefaultApiHost = "https://api.supabase.com"
144-
// DEPRECATED
145-
DeprecatedApiHost = "https://api.supabase.io"
146-
)
141+
const DefaultApiHost = "https://api.supabase.com"
147142

148143
var RegionMap = map[string]string{
149144
"ap-northeast-1": "Northeast Asia (Tokyo)",
@@ -163,43 +158,17 @@ var RegionMap = map[string]string{
163158
}
164159

165160
func GetSupabaseAPIHost() string {
166-
apiHost := viper.GetString("INTERNAL_API_HOST")
167-
if apiHost == "" {
168-
apiHost = DefaultApiHost
169-
}
170-
return apiHost
161+
return CurrentProfile.APIURL
171162
}
172163

173164
func GetSupabaseDashboardURL() string {
174-
switch GetSupabaseAPIHost() {
175-
case DefaultApiHost, DeprecatedApiHost:
176-
return "https://supabase.com/dashboard"
177-
case "https://api.supabase.green":
178-
return "https://supabase.green/dashboard"
179-
default:
180-
return "http://127.0.0.1:8082"
181-
}
165+
return CurrentProfile.DashboardURL
182166
}
183167

184-
func GetSupabaseDbHost(projectRef string) string {
185-
// TODO: query projects api for db_host
186-
switch GetSupabaseAPIHost() {
187-
case DefaultApiHost, DeprecatedApiHost:
188-
return fmt.Sprintf("db.%s.supabase.co", projectRef)
189-
case "https://api.supabase.green":
190-
return fmt.Sprintf("db.%s.supabase.red", projectRef)
191-
default:
192-
return fmt.Sprintf("db.%s.supabase.red", projectRef)
193-
}
168+
func GetSupabaseHost(projectRef string) string {
169+
return fmt.Sprintf("%s.%s", projectRef, CurrentProfile.ProjectHost)
194170
}
195171

196-
func GetSupabaseHost(projectRef string) string {
197-
switch GetSupabaseAPIHost() {
198-
case DefaultApiHost, DeprecatedApiHost:
199-
return fmt.Sprintf("%s.supabase.co", projectRef)
200-
case "https://api.supabase.green":
201-
return fmt.Sprintf("%s.supabase.red", projectRef)
202-
default:
203-
return fmt.Sprintf("%s.supabase.red", projectRef)
204-
}
172+
func GetSupabaseDbHost(projectRef string) string {
173+
return "db." + GetSupabaseHost(projectRef)
205174
}

internal/utils/profile.go

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package utils
2+
3+
import (
4+
"context"
5+
"strings"
6+
7+
"github.com/go-errors/errors"
8+
"github.com/go-playground/validator/v10"
9+
"github.com/go-viper/mapstructure/v2"
10+
"github.com/spf13/afero"
11+
"github.com/spf13/viper"
12+
)
13+
14+
type Profile struct {
15+
Name string `mapstructure:"name" validate:"required"`
16+
APIURL string `mapstructure:"api_url" validate:"required,http_url"`
17+
DashboardURL string `mapstructure:"dashboard_url" validate:"required,http_url"`
18+
ProjectHost string `mapstructure:"project_host" validate:"required,hostname_rfc1123"`
19+
DocsURL string `mapstructure:"docs_url" validate:"omitempty,http_url"`
20+
StudioImage string `mapstructure:"studio_image"`
21+
}
22+
23+
var allProfile = []Profile{{
24+
Name: "supabase",
25+
APIURL: "https://api.supabase.com",
26+
DashboardURL: "https://supabase.com/dashboard",
27+
DocsURL: "https://supabase.com/docs",
28+
ProjectHost: "supabase.co",
29+
}, {
30+
Name: "supabase-staging",
31+
APIURL: "https://api.supabase.green",
32+
DashboardURL: "https://supabase.green/dashboard",
33+
DocsURL: "https://supabase.com/docs",
34+
ProjectHost: "supabase.red",
35+
}}
36+
37+
var CurrentProfile Profile
38+
39+
func LoadProfile(ctx context.Context, fsys afero.Fs) error {
40+
prof := viper.GetString("PROFILE")
41+
for _, p := range allProfile {
42+
if strings.EqualFold(p.Name, prof) {
43+
CurrentProfile = p
44+
return nil
45+
}
46+
}
47+
// Instantiate to prevent accidentally leaking viper state to pkg internal calls
48+
v := viper.New()
49+
v.SetFs(fsys)
50+
v.SetConfigFile(prof)
51+
if err := v.ReadInConfig(); err != nil {
52+
return errors.Errorf("failed to read profile: %w", err)
53+
}
54+
// Load envs into viper, rejecting keys not defined by config
55+
if err := v.UnmarshalExact(&CurrentProfile, viper.DecodeHook(mapstructure.ComposeDecodeHookFunc(
56+
mapstructure.StringToTimeDurationHookFunc(),
57+
mapstructure.StringToIPHookFunc(),
58+
mapstructure.StringToSliceHookFunc(","),
59+
mapstructure.TextUnmarshallerHookFunc(),
60+
))); err != nil {
61+
return errors.Errorf("failed to parse profile: %w", err)
62+
}
63+
validate := validator.New(validator.WithRequiredStructEnabled())
64+
if err := validate.StructCtx(ctx, &CurrentProfile); err != nil {
65+
return errors.Errorf("invalid profile: %w", err)
66+
}
67+
return nil
68+
}

0 commit comments

Comments
 (0)