• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

supabase / cli / 18835102741

27 Oct 2025 08:50AM UTC coverage: 54.703% (-0.03%) from 54.728%
18835102741

Pull #4345

github

web-flow
Merge 76edda1d2 into 64465dd82
Pull Request #4345: chore: sync API types from infrastructure

0 of 2 new or added lines in 2 files covered. (0.0%)

11 existing lines in 3 files now uncovered.

6386 of 11674 relevant lines covered (54.7%)

6.13 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

81.82
/internal/utils/profile.go
1
package utils
2

3
import (
4
        "context"
5
        "fmt"
6
        "strings"
7

8
        "github.com/go-errors/errors"
9
        "github.com/go-playground/validator/v10"
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
        PoolerHost   string `mapstructure:"pooler_host" validate:"omitempty,hostname_rfc1123"`
20
        DocsURL      string `mapstructure:"docs_url" validate:"omitempty,http_url"`
21
        StudioImage  string `mapstructure:"studio_image"`
22
}
23

24
var allProfiles = []Profile{{
25
        Name:         "supabase",
26
        APIURL:       "https://api.supabase.com",
27
        DashboardURL: "https://supabase.com/dashboard",
28
        DocsURL:      "https://supabase.com/docs",
29
        ProjectHost:  "supabase.co",
30
        PoolerHost:   "supabase.com",
31
}, {
32
        Name:         "supabase-staging",
33
        APIURL:       "https://api.supabase.green",
34
        DashboardURL: "https://supabase.green/dashboard",
35
        DocsURL:      "https://supabase.com/docs",
36
        ProjectHost:  "supabase.red",
37
        PoolerHost:   "supabase.green",
38
}, {
39
        Name:         "supabase-local",
40
        APIURL:       "http://localhost:8080",
41
        DashboardURL: "http://localhost:8082",
42
        DocsURL:      "https://supabase.com/docs",
43
        ProjectHost:  "supabase.red",
44
}, {
45
        Name:         "snap",
46
        APIURL:       "https://cloudapi.snap.com",
47
        DashboardURL: "https://cloud.snap.com/dashboard",
48
        DocsURL:      "https://cloud.snap.com/docs",
49
        ProjectHost:  "snapcloud.dev",
50
        PoolerHost:   "snapcloud.co",
51
}}
52

53
var CurrentProfile Profile
54

55
func LoadProfile(ctx context.Context, fsys afero.Fs) error {
8✔
56
        prof := getProfileName(fsys)
8✔
57
        for _, p := range allProfiles {
34✔
58
                if strings.EqualFold(p.Name, prof) {
30✔
59
                        CurrentProfile = p
4✔
60
                        return nil
4✔
61
                }
4✔
62
        }
63
        // Instantiate to avoid leaking profile into global viper state
64
        v := viper.New()
4✔
65
        v.SetFs(fsys)
4✔
66
        v.SetConfigFile(prof)
4✔
67
        if err := v.ReadInConfig(); err != nil {
5✔
68
                return errors.Errorf("failed to read profile: %w", err)
1✔
69
        }
1✔
70
        // Load profile into viper, rejecting keys not defined by config
71
        if err := v.UnmarshalExact(&CurrentProfile); err != nil {
4✔
72
                return errors.Errorf("failed to parse profile: %w", err)
1✔
73
        }
1✔
74
        validate := validator.New(validator.WithRequiredStructEnabled())
2✔
75
        if err := validate.StructCtx(ctx, &CurrentProfile); err != nil {
3✔
76
                return errors.Errorf("invalid profile: %w", err)
1✔
77
        }
1✔
78
        return nil
1✔
79
}
80

81
func getProfileName(fsys afero.Fs) string {
8✔
82
        debuglogger := GetDebugLogger()
8✔
83
        if prof := viper.GetString("PROFILE"); viper.IsSet("PROFILE") {
16✔
84
                fmt.Fprintln(debuglogger, "Loading profile from flag:", prof)
8✔
85
                return prof
8✔
86
        } else if content, err := afero.ReadFile(fsys, ProfilePath); err == nil {
8✔
87
                fmt.Fprintln(debuglogger, "Loading profile from file:", ProfilePath)
×
88
                return string(content)
×
UNCOV
89
        } else {
×
UNCOV
90
                fmt.Fprintln(debuglogger, err)
×
UNCOV
91
                return prof
×
UNCOV
92
        }
×
93
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc