Skip to content

Commit

Permalink
add confirmation to deployment after preview
Browse files Browse the repository at this point in the history
  • Loading branch information
HomelessDinosaur committed Jan 29, 2025
1 parent 0f51a9b commit 925aea5
Show file tree
Hide file tree
Showing 4 changed files with 147 additions and 87 deletions.
145 changes: 68 additions & 77 deletions cmd/stack.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import (
stack_new "github.com/nitrictech/cli/pkg/view/tui/commands/stack/new"
stack_preview "github.com/nitrictech/cli/pkg/view/tui/commands/stack/preview"
stack_select "github.com/nitrictech/cli/pkg/view/tui/commands/stack/select"
stack_up "github.com/nitrictech/cli/pkg/view/tui/commands/stack/up"
"github.com/nitrictech/cli/pkg/view/tui/components/list"
"github.com/nitrictech/cli/pkg/view/tui/components/listprompt"
"github.com/nitrictech/cli/pkg/view/tui/components/view"
Expand Down Expand Up @@ -371,9 +372,7 @@ var stackUpdateCmd = &cobra.Command{
}
}

// Check if the thing is active

confirmModel := listprompt.NewListPrompt(listprompt.ListPromptArgs{
confirmModel := stack_preview.NewConfirmDeployment(listprompt.ListPromptArgs{
Items: list.StringsToListItems([]string{"confirm deployment", "cancel"}),
Tag: "deploy",
Prompt: "Finished preview. Would you like to perform the deployment?",
Expand All @@ -382,84 +381,76 @@ var stackUpdateCmd = &cobra.Command{
selection, err := teax.NewProgram(confirmModel).Run()
tui.CheckErr(err)

v := view.New()
v.Break()
fmt.Println("")

stackSelection = selection.(listprompt.ListPrompt).Choice()
stackSelection = selection.(stack_preview.ConfirmDeploymentModel).Choice()
if stackSelection == "cancel" {
v.Addln("Cancelling deployment")
fmt.Println(v.Render())
fmt.Println("Cancelled")
return
}

v.Addln("Deployed")
fmt.Println(v.Render())
eventChan, errorChan := deploymentClient.Up(&deploymentspb.DeploymentUpRequest{
Spec: spec,
Attributes: attributesStruct,
Interactive: true,
})

// Step 5d. Communicate with server to share progress of update
if isNonInteractive() {
providerErrorDetected := false

fmt.Printf("Deploying %s stack with provider %s\n", stackConfig.Name, stackConfig.Provider)
go func() {
for update := range errorChan {
fmt.Printf("Error: %s\n", update)
providerErrorDetected = true
}
}()

go func() {
for outMessage := range providerStdout {
fmt.Printf("%s: %s\n", stackConfig.Provider, outMessage)
}
}()

// non-interactive environment
for update := range eventChan {
switch content := update.Content.(type) {
case *deploymentspb.DeploymentUpEvent_Message:
fmt.Printf("%s\n", content.Message)
case *deploymentspb.DeploymentUpEvent_Update:
updateResType := ""
updateResName := ""
if content.Update.Id != nil {
updateResType = content.Update.Id.Type.String()
updateResName = content.Update.Id.Name
}

if updateResType == "" {
updateResType = "Stack"
}
if updateResName == "" {
updateResName = stackConfig.Name
}
if content.Update.SubResource != "" {
updateResName = fmt.Sprintf("%s:%s", updateResName, content.Update.SubResource)
}

fmt.Printf("%s:%s [%s]:%s %s\n", updateResType, updateResName, content.Update.Action, content.Update.Status, content.Update.Message)
case *deploymentspb.DeploymentUpEvent_Result:
fmt.Printf("\nResult: %s\n", content.Result.GetText())
}
}

// eventChan, errorChan := deploymentClient.Up(&deploymentspb.DeploymentUpRequest{
// Spec: spec,
// Attributes: attributesStruct,
// Interactive: true,
// })

// // Step 5d. Communicate with server to share progress of update
// if isNonInteractive() {
// providerErrorDetected := false

// fmt.Printf("Deploying %s stack with provider %s\n", stackConfig.Name, stackConfig.Provider)
// go func() {
// for update := range errorChan {
// fmt.Printf("Error: %s\n", update)
// providerErrorDetected = true
// }
// }()

// go func() {
// for outMessage := range providerStdout {
// fmt.Printf("%s: %s\n", stackConfig.Provider, outMessage)
// }
// }()

// // non-interactive environment
// for update := range eventChan {
// switch content := update.Content.(type) {
// case *deploymentspb.DeploymentUpEvent_Message:
// fmt.Printf("%s\n", content.Message)
// case *deploymentspb.DeploymentUpEvent_Update:
// updateResType := ""
// updateResName := ""
// if content.Update.Id != nil {
// updateResType = content.Update.Id.Type.String()
// updateResName = content.Update.Id.Name
// }

// if updateResType == "" {
// updateResType = "Stack"
// }
// if updateResName == "" {
// updateResName = stackConfig.Name
// }
// if content.Update.SubResource != "" {
// updateResName = fmt.Sprintf("%s:%s", updateResName, content.Update.SubResource)
// }

// fmt.Printf("%s:%s [%s]:%s %s\n", updateResType, updateResName, content.Update.Action, content.Update.Status, content.Update.Message)
// case *deploymentspb.DeploymentUpEvent_Result:
// fmt.Printf("\nResult: %s\n", content.Result.GetText())
// }
// }

// // ensure the process exits with a non-zero status code after all messages are processed
// if providerErrorDetected {
// os.Exit(1)
// }
// } else {
// // interactive environment
// // Step 5e. Start the stack up view
// stackUp := stack_up.New(stackConfig.Provider, stackConfig.Name, eventChan, providerStdout, errorChan)
// _, err = teax.NewProgram(stackUp).Run()
// tui.CheckErr(err)
// }
// ensure the process exits with a non-zero status code after all messages are processed
if providerErrorDetected {
os.Exit(1)
}
} else {
// interactive environment
// Step 5e. Start the stack up view
stackUp := stack_up.New(stackConfig.Provider, stackConfig.Name, eventChan, providerStdout, errorChan)
_, err = teax.NewProgram(stackUp).Run()
tui.CheckErr(err)
}
},
Args: cobra.MinimumNArgs(0),
Aliases: []string{"up"},
Expand Down Expand Up @@ -990,7 +981,7 @@ func init() {
stackUpdateCmd.Flags().BoolVarP(&noBuilder, "no-builder", "", false, "don't create a buildx container")
stackUpdateCmd.Flags().StringVarP(&envFile, "env-file", "e", "", "--env-file config/.my-env")
stackUpdateCmd.Flags().BoolVarP(&forceStack, "force", "f", false, "force override previous deployment")
stackUpdateCmd.Flags().BoolVarP(&skipPreview, "skip-preview", "", false, "ignore preview")
stackUpdateCmd.Flags().BoolVarP(&skipPreview, "skip-preview", "", false, "skips the preview step of the deployment")
tui.CheckErr(AddOptions(stackUpdateCmd, false))

// Delete Stack (Down)
Expand Down
69 changes: 69 additions & 0 deletions pkg/view/tui/commands/stack/preview/confirm_deployment.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package stack_preview

import (
"github.com/charmbracelet/bubbles/key"
tea "github.com/charmbracelet/bubbletea"
tui "github.com/nitrictech/cli/pkg/view/tui"
"github.com/nitrictech/cli/pkg/view/tui/components/listprompt"
"github.com/nitrictech/cli/pkg/view/tui/teax"
)

type ConfirmDeploymentModel struct {
windowSize tea.WindowSizeMsg

confirmPrompt listprompt.ListPrompt
}

// Init initializes the model, used by Bubbletea
func (m ConfirmDeploymentModel) Init() tea.Cmd {
return nil
}

// Update the model based on a message
func (m ConfirmDeploymentModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
var cmd tea.Cmd

switch msg := msg.(type) {
case tea.WindowSizeMsg:
m.windowSize = msg

if m.windowSize.Height < 7 {
m.confirmPrompt.SetMinimized(true)
m.confirmPrompt.SetMaxDisplayedItems(m.windowSize.Height - 1)
} else {
m.confirmPrompt.SetMinimized(false)
maxItems := ((m.windowSize.Height - 1) / 3) // make room for the exit message
m.confirmPrompt.SetMaxDisplayedItems(maxItems)
}

return m, nil
case tea.KeyMsg:
switch {
case key.Matches(msg, tui.KeyMap.Quit):
return m, teax.Quit
}
}

m.confirmPrompt, cmd = m.confirmPrompt.UpdateListPrompt(msg)
if m.confirmPrompt.IsComplete() {
return m, teax.Quit
}

return m, cmd
}

func (m ConfirmDeploymentModel) View() string {
return m.confirmPrompt.View()
}

func (m ConfirmDeploymentModel) Choice() string {
return m.confirmPrompt.Choice()
}

func NewConfirmDeployment(args listprompt.ListPromptArgs) *ConfirmDeploymentModel {
confirmPrompt := listprompt.NewListPrompt(args)

return &ConfirmDeploymentModel{
confirmPrompt: confirmPrompt,
}
}
16 changes: 9 additions & 7 deletions pkg/view/tui/commands/stack/preview/stack_preview.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

package stack_up
package stack_preview

import (
"fmt"
Expand Down Expand Up @@ -207,17 +207,19 @@ func (m Model) View() string {
currentNode := statusTree.AddNode(child.Name, "")

for _, grandchild := range child.Children {
resourceTime := lo.Ternary(grandchild.FinishTime.IsZero(), time.Since(grandchild.StartTime).Round(time.Second), grandchild.FinishTime.Sub(grandchild.StartTime))

statusColor := tui.Colors.Blue
if grandchild.Status == deploymentspb.ResourceDeploymentStatus_FAILED {
if grandchild.Action == deploymentspb.ResourceDeploymentAction_DELETE {
statusColor = tui.Colors.Red
} else if grandchild.Status == deploymentspb.ResourceDeploymentStatus_SUCCESS || grandchild.Action == deploymentspb.ResourceDeploymentAction_SAME {
} else if grandchild.Action == deploymentspb.ResourceDeploymentAction_CREATE {
statusColor = tui.Colors.Green
} else if grandchild.Action == deploymentspb.ResourceDeploymentAction_SAME {
statusColor = tui.Colors.Gray
}

statusText := fmt.Sprintf("%s (%s)", stack.VerbMap[grandchild.Action][grandchild.Status], resourceTime.Round(time.Second))
currentNode.AddNode(grandchild.Name, lipgloss.NewStyle().Foreground(statusColor).Render(statusText))
// Always uses the pending verbage to show it will happen, not that it has happened
statusVerbage := stack.VerbMap[grandchild.Action][deploymentspb.ResourceDeploymentStatus_PENDING]

currentNode.AddNode(grandchild.Name, lipgloss.NewStyle().Foreground(statusColor).Render(statusVerbage))
}
}

Expand Down
4 changes: 1 addition & 3 deletions pkg/view/tui/components/listprompt/listprompt.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@
package listprompt

import (
"strings"

"github.com/charmbracelet/bubbles/key"
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss"
Expand Down Expand Up @@ -105,7 +103,7 @@ func (m ListPrompt) View() string {
listView.Addln(m.Choice()).WithStyle(historyTextStyle)
}

return strings.TrimSuffix(listView.Render(), "\n")
return listView.Render()
}

type ListPromptArgs struct {
Expand Down

0 comments on commit 925aea5

Please sign in to comment.