diff --git a/CHANGELOG_PENDING.md b/CHANGELOG_PENDING.md index 7a1b63ab2567..d5f02f3362ba 100644 --- a/CHANGELOG_PENDING.md +++ b/CHANGELOG_PENDING.md @@ -1,5 +1,6 @@ ### Improvements +- [area/cli] - Implement `pulumi stack unselect` [#9179](https://github.com/pulumi/pulumi/pull/9179) - [language/dotnet] - Updated Pulumi dotnet packages to use grpc-dotnet instead of grpc. [#9149](https://github.com/pulumi/pulumi/pull/9149) diff --git a/pkg/cmd/pulumi/stack.go b/pkg/cmd/pulumi/stack.go index 90a1fe849dfc..93584cc5f256 100644 --- a/pkg/cmd/pulumi/stack.go +++ b/pkg/cmd/pulumi/stack.go @@ -185,6 +185,7 @@ func newStackCmd() *cobra.Command { cmd.AddCommand(newStackRenameCmd()) cmd.AddCommand(newStackChangeSecretsProviderCmd()) cmd.AddCommand(newStackHistoryCmd()) + cmd.AddCommand(newStackUnselectCmd()) return cmd } diff --git a/pkg/cmd/pulumi/stack_unselect.go b/pkg/cmd/pulumi/stack_unselect.go new file mode 100644 index 000000000000..eda3d729d671 --- /dev/null +++ b/pkg/cmd/pulumi/stack_unselect.go @@ -0,0 +1,61 @@ +// Copyright 2016-2022, 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 main + +import ( + "fmt" + + "github.com/pulumi/pulumi/sdk/v3/go/common/util/cmdutil" + "github.com/pulumi/pulumi/sdk/v3/go/common/workspace" + "github.com/spf13/cobra" +) + +// Resets the currently selected stack from the current workspace such that +// next time the users get prompted with a stack to select +func newStackUnselectCmd() *cobra.Command { + return &cobra.Command{ + Use: "unselect", + Short: "Resets stack selection from the current workspace", + Long: "Resets stack selection from the current workspace.\n" + + "\n" + + "This way, next time pulumi needs to execute an operation, the user is prompted with one of the stacks to select\n" + + "from.\n", + Args: cmdutil.NoArgs, + Run: cmdutil.RunFunc(func(cmd *cobra.Command, args []string) error { + currentWorkspace, err := workspace.New() + if err != nil { + return err + } + + settings := currentWorkspace.Settings() + if settings.Stack != "" { + // a stack is selected + // reset it + settings.Stack = "" + err = currentWorkspace.Save() + if err == nil { + // saving changes was successful + fmt.Println("Stack was unselected") + } else { + fmt.Printf("Could not unselect the current stack from the workspace: %s", err) + } + + return err + } + + return nil + }), + } +} diff --git a/tests/stack_test.go b/tests/stack_test.go index f2e3aac3287c..f539c8a03299 100644 --- a/tests/stack_test.go +++ b/tests/stack_test.go @@ -113,6 +113,35 @@ func TestStackCommands(t *testing.T) { e.RunCommand("pulumi", "stack", "rm", "--yes") }) + t.Run("StackUnselect", func(t *testing.T) { + t.Parallel() + + e := ptesting.NewEnvironment(t) + defer func() { + if !t.Failed() { + e.DeleteEnvironment() + } + }() + + integration.CreateBasicPulumiRepo(e) + e.SetBackend(e.LocalURL()) + e.RunCommand("pulumi", "stack", "init", "one") + e.RunCommand("pulumi", "stack", "init", "two") + + // Last one created is always selected. + stacks, current := integration.GetStacks(e) + if current == nil { + t.Fatalf("No stack was labeled as current among: %v", stacks) + } + assert.Equal(t, "two", *current) + + e.RunCommand("pulumi", "stack", "unselect") + _, updatedCurrentStack := integration.GetStacks(e) + if updatedCurrentStack != nil { + t.Fatal("No stack should be selected after unselect was executed") + } + }) + t.Run("StackRm", func(t *testing.T) { t.Parallel()