// Copyright 2016-2018, Pulumi Corporation. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package cmd import ( "github.com/pkg/errors" "github.com/spf13/cobra" "github.com/pulumi/pulumi/pkg/backend/display" "github.com/pulumi/pulumi/pkg/backend/state" "github.com/pulumi/pulumi/sdk/go/common/util/cmdutil" "github.com/pulumi/pulumi/sdk/go/common/util/contract" ) // newStackSelectCmd handles both the "local" and "cloud" scenarios in its implementation. func newStackSelectCmd() *cobra.Command { var stack string var secretsProvider string var create bool cmd := &cobra.Command{ Use: "select []", Short: "Switch the current workspace to the given stack", Long: "Switch the current workspace to the given stack.\n" + "\n" + "Selecting a stack allows you to use commands like `config`, `preview`, and `update`\n" + "without needing to type the stack name each time.\n" + "\n" + "If no argument is supplied, you will be prompted to select one interactively.\n" + "If provided stack name is not found you may pass the --create flag to create and select it", Args: cmdutil.MaximumNArgs(1), Run: cmdutil.RunFunc(func(cmd *cobra.Command, args []string) error { opts := display.Options{ Color: cmdutil.GetGlobalColorization(), } b, err := currentBackend(opts) if err != nil { return err } if len(args) > 0 { if stack != "" { return errors.New("only one of --stack or argument stack name may be specified, not both") } stack = args[0] } if stack != "" { // A stack was given, ask the backend about it. stackRef, stackErr := b.ParseStackReference(stack) if stackErr != nil { return stackErr } s, stackErr := b.GetStack(commandContext(), stackRef) if stackErr != nil { return stackErr } else if s != nil { return state.SetCurrentStack(stackRef.String()) } // If create flag was passed and stack was not found, create it and select it. if create && stack != "" { s, err := stackInit(b, stack, false, secretsProvider) if err != nil { return err } return state.SetCurrentStack(s.Ref().String()) } return errors.Errorf("no stack named '%s' found", stackRef) } // If no stack was given, prompt the user to select a name from the available ones. stack, err := chooseStack(b, true, opts, true /*setCurrent*/) if err != nil { return err } contract.Assert(stack != nil) return state.SetCurrentStack(stack.Ref().String()) }), } cmd.PersistentFlags().StringVarP( &stack, "stack", "s", "", "The name of the stack to select") cmd.PersistentFlags().BoolVarP( &create, "create", "c", false, "If selected stack does not exist, create it") cmd.PersistentFlags().StringVar( &secretsProvider, "secrets-provider", "default", "Use with --create flag, "+possibleSecretsProviderChoices) return cmd }