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
2 changes: 1 addition & 1 deletion src/cmd/cli/command/color.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func (c *ColorMode) Set(value string) error {
return nil
}
}
return fmt.Errorf("color mode not one of %v", allColorModes)
return fmt.Errorf("invalid color: %q, not one of %v", value, allColorModes)
}

func (c ColorMode) Type() string {
Expand Down
5 changes: 1 addition & 4 deletions src/cmd/cli/command/session.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,7 @@ func newCommandSessionWithOpts(cmd *cobra.Command, opts commandSessionOpts) (*se
}

func newSessionLoaderOptionsForCommand(cmd *cobra.Command) session.SessionLoaderOptions {
stack, _ := cmd.Flags().GetString("stack")
configPaths, _ := cmd.Flags().GetStringArray("file")
provider, _ := cmd.Flag("provider").Value.(*client.ProviderID)
projectName, _ := cmd.Flags().GetString("project-name")

// Avoid common mistakes
Expand All @@ -77,9 +75,8 @@ func newSessionLoaderOptionsForCommand(cmd *cobra.Command) session.SessionLoader
ComposeFilePaths: configPaths,
ProjectName: projectName,
GetStackOpts: stacks.GetStackOpts{
ProviderID: *provider,
Interactive: !global.NonInteractive,
Stack: stack,
Default: global.Stack,
},
}
}
Expand Down
7 changes: 0 additions & 7 deletions src/pkg/session/session.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,13 +68,6 @@ func (sl *SessionLoader) LoadSession(ctx context.Context) (*Session, error) {
}

func (sl *SessionLoader) loadStack(ctx context.Context) (*stacks.Parameters, string, error) {
if sl.sm == nil {
return &stacks.Parameters{
Name: stacks.DefaultBeta,
Provider: sl.opts.ProviderID,
}, "no stack manager available", nil
}

stack, whence, err := sl.sm.GetStack(ctx, sl.opts.GetStackOpts)
if err != nil {
return nil, whence, err
Expand Down
27 changes: 7 additions & 20 deletions src/pkg/session/session_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,9 @@ func TestLoadSession(t *testing.T) {
name: "specified stack",
options: SessionLoaderOptions{
GetStackOpts: stacks.GetStackOpts{
Stack: "existingstack",
Default: stacks.Parameters{
Name: "existingstack",
},
},
},
existingStack: &stacks.Parameters{
Expand Down Expand Up @@ -122,9 +124,9 @@ func TestLoadSession(t *testing.T) {
sm := &mockStacksManager{}

if tt.existingStack == nil {
if tt.options.GetStackOpts.Stack != "" {
if tt.options.Default.Name != "" {
// For specified non-existing stack, return ErrNotExist
sm.On("GetStack", ctx, mock.Anything).Maybe().Return(nil, "", &stacks.ErrNotExist{StackName: tt.options.GetStackOpts.Stack})
sm.On("GetStack", ctx, mock.Anything).Maybe().Return(nil, "", &stacks.ErrNotExist{StackName: tt.options.Default.Name})
} else if tt.getStackError != nil {
sm.On("GetStack", ctx, mock.Anything).Maybe().Return(nil, "", tt.getStackError)
}
Expand All @@ -149,11 +151,11 @@ func TestLoadSession(t *testing.T) {
assert.NotNil(t, session.Loader)

assert.NotNil(t, session.Provider)
if tt.options.ProviderID == client.ProviderAWS {
if tt.options.Default.Provider == client.ProviderAWS {
_, ok := session.Provider.(*aws.ByocAws)
assert.True(t, ok)
}
if tt.options.ProviderID == client.ProviderGCP {
if tt.options.Default.Provider == client.ProviderGCP {
_, ok := session.Provider.(*gcp.ByocGcp)
assert.True(t, ok)
}
Expand All @@ -175,18 +177,3 @@ func TestLoadSession(t *testing.T) {
})
}
}

func TestLoadSession_NoStackManager(t *testing.T) {
ctx := t.Context()

options := SessionLoaderOptions{
GetStackOpts: stacks.GetStackOpts{
ProviderID: client.ProviderDefang,
},
}

loader := NewSessionLoader(client.MockFabricClient{}, nil, options)
session, err := loader.LoadSession(ctx)
require.NoError(t, err)
assert.NotNil(t, session)
}
49 changes: 22 additions & 27 deletions src/pkg/stacks/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -201,47 +201,43 @@ func (sm *manager) Create(params Parameters) (string, error) {
}

type GetStackOpts struct {
ProviderID client.ProviderID
Stack string
Interactive bool
AllowStackCreation bool
Default Parameters
Interactive bool
SelectStackOptions
}

func (sl *manager) GetStack(ctx context.Context, opts GetStackOpts) (*Parameters, string, error) {
func (sm *manager) GetStack(ctx context.Context, opts GetStackOpts) (*Parameters, string, error) {
// use --stack if available
if opts.Stack != "" {
return sl.getSpecifiedStack(ctx, opts.Stack)
if opts.Default.Name != "" {
return sm.getSpecifiedStack(ctx, opts.Default.Name) // TODO: merge with opts.Default?
}
// use --provider if available
if opts.ProviderID != client.ProviderAuto && opts.ProviderID != "" {
if opts.Default.Provider != client.ProviderAuto && opts.Default.Provider != "" {
whence := "DEFANG_PROVIDER"
envProvider := os.Getenv("DEFANG_PROVIDER")
if envProvider != opts.ProviderID.String() {
var fromEnv client.ProviderID
if err := fromEnv.Set(os.Getenv("DEFANG_PROVIDER")); err == nil && fromEnv != opts.Default.Provider {
whence = "--provider flag"
}
return &Parameters{
Name: DefaultBeta,
Provider: opts.ProviderID,
}, whence, nil
fallback := opts.Default
fallback.Name = DefaultBeta
return &fallback, whence, nil
}
// fallback to interactive
if opts.Interactive {
return sl.getStackInteractively(ctx, opts)
return sm.getStackInteractively(ctx, opts) // TODO: merge with opts.Default?
}
// fallback to default stack
stack, whence, err := sl.getDefaultStack(ctx)
// fallback to default stack for project
stack, whence, err := sm.getDefaultStack(ctx)
if err != nil {
if !errors.Is(err, ErrDefaultStackNotSet) {
return nil, "", err
}
whence := "fallback stack"

// fallback to fallback
stack = &Parameters{
Name: DefaultBeta,
Provider: client.ProviderDefang,
}
return stack, whence, nil
// no default stack for project; use fallback
whence := "fallback stack"
fallback := opts.Default
fallback.Name = DefaultBeta
return &fallback, whence, nil
}

return stack, whence, nil
Expand Down Expand Up @@ -289,9 +285,8 @@ func (sm *manager) getSpecifiedStack(ctx context.Context, name string) (*Paramet

func (sm *manager) getStackInteractively(ctx context.Context, opts GetStackOpts) (*Parameters, string, error) {
stackSelector := NewSelector(sm.ec, sm)
stack, err := stackSelector.SelectStack(ctx, SelectStackOptions{
AllowStackCreation: opts.AllowStackCreation,
})
// TODO: pass fallback stack to selector wizard for pre-filling
stack, err := stackSelector.SelectStack(ctx, opts.SelectStackOptions)
if err != nil {
return nil, "", fmt.Errorf("failed to select stack: %w", err)
}
Expand Down
27 changes: 17 additions & 10 deletions src/pkg/stacks/manager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -664,7 +664,7 @@ func TestGetStack(t *testing.T) {
name: "stack specified but not found",
projectName: "foo",
options: GetStackOpts{
Stack: "missingstack",
Default: Parameters{Name: "missingstack"},
},
expectedError: "stack \"missingstack\" does not exist",
expectedEnv: map[string]string{},
Expand All @@ -673,7 +673,7 @@ func TestGetStack(t *testing.T) {
name: "local stack specified",
projectName: "foo",
options: GetStackOpts{
Stack: "localstack",
Default: Parameters{Name: "localstack"},
},
localStack: &Parameters{
Name: "localstack",
Expand All @@ -698,7 +698,7 @@ func TestGetStack(t *testing.T) {
name: "remote stack specified",
projectName: "foo",
options: GetStackOpts{
Stack: "remotestack",
Default: Parameters{Name: "remotestack"},
},
remoteStack: &Parameters{
Name: "remotestack",
Expand All @@ -725,7 +725,7 @@ func TestGetStack(t *testing.T) {
name: "local and remote stack",
projectName: "foo",
options: GetStackOpts{
Stack: "bothstack",
Default: Parameters{Name: "bothstack"},
},
localStack: &Parameters{
Name: "bothstack",
Expand Down Expand Up @@ -767,8 +767,10 @@ func TestGetStack(t *testing.T) {
name: "interactive selection",
projectName: "foo",
options: GetStackOpts{
Interactive: true,
AllowStackCreation: true,
Interactive: true,
SelectStackOptions: SelectStackOptions{
AllowStackCreation: true,
},
},
remoteStack: &Parameters{
Name: "existingstack",
Expand All @@ -784,9 +786,14 @@ func TestGetStack(t *testing.T) {
"stack": "existingstack",
},
expectedStack: &Parameters{
Name: "existingstack",
Provider: client.ProviderGCP,
Variables: map[string]string{},
Name: "existingstack",
Provider: client.ProviderGCP,
Region: "us-central1",
Variables: map[string]string{
"DEFANG_PROVIDER": "gcp",
"GCP_PROJECT": "existing-gcp-project",
"FOO": "existing-bar",
},
},
expectedEnv: map[string]string{
"DEFANG_PROVIDER": "gcp",
Expand All @@ -798,7 +805,7 @@ func TestGetStack(t *testing.T) {
name: "stack with compose vars updates loader",
projectName: "foo",
options: GetStackOpts{
Stack: "composestack",
Default: Parameters{Name: "composestack"},
},
localStack: &Parameters{
Name: "composestack",
Expand Down
Loading