supabase-cli/internal/utils/flags/project_ref.go

73 lines
2.1 KiB
Go

package flags
import (
"bytes"
"context"
"fmt"
"os"
tea "github.com/charmbracelet/bubbletea"
"github.com/go-errors/errors"
"github.com/spf13/afero"
"github.com/spf13/viper"
"github.com/supabase/cli/internal/utils"
"golang.org/x/term"
)
var ProjectRef string
func ParseProjectRef(ctx context.Context, fsys afero.Fs) error {
if err := LoadProjectRef(fsys); !errors.Is(err, utils.ErrNotLinked) {
return err
}
// Prompt as the last resort
if term.IsTerminal(int(os.Stdin.Fd())) {
return PromptProjectRef(ctx, "Select a project:")
}
return errors.New(utils.ErrNotLinked)
}
func PromptProjectRef(ctx context.Context, title string, opts ...tea.ProgramOption) error {
resp, err := utils.GetSupabase().V1ListAllProjectsWithResponse(ctx)
if err != nil {
return errors.Errorf("failed to retrieve projects: %w", err)
}
if resp.JSON200 == nil {
return errors.New("Unexpected error retrieving projects: " + string(resp.Body))
}
items := make([]utils.PromptItem, len(*resp.JSON200))
for i, project := range *resp.JSON200 {
items[i] = utils.PromptItem{
Summary: project.Id,
Details: fmt.Sprintf("name: %s, org: %s, region: %s", project.Name, project.OrganizationId, project.Region),
}
}
choice, err := utils.PromptChoice(ctx, title, items, opts...)
if err != nil {
return err
}
ProjectRef = choice.Summary
fmt.Fprintln(os.Stderr, "Selected project:", ProjectRef)
return nil
}
func LoadProjectRef(fsys afero.Fs) error {
// Flag takes highest precedence
if len(ProjectRef) > 0 {
return utils.AssertProjectRefIsValid(ProjectRef)
}
// Env var takes precedence over ref file
if ProjectRef = viper.GetString("PROJECT_ID"); len(ProjectRef) > 0 {
return utils.AssertProjectRefIsValid(ProjectRef)
}
// Load from local file last
projectRefBytes, err := afero.ReadFile(fsys, utils.ProjectRefPath)
if errors.Is(err, os.ErrNotExist) {
return errors.New(utils.ErrNotLinked)
} else if err != nil {
return errors.Errorf("failed to load project ref: %w", err)
}
ProjectRef = string(bytes.TrimSpace(projectRefBytes))
return utils.AssertProjectRefIsValid(ProjectRef)
}