Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add spinner during atmos validate stacks operations #1005

Merged
merged 7 commits into from
Feb 4, 2025
50 changes: 48 additions & 2 deletions internal/exec/validate_stacks.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,15 @@ import (
"strings"
"time"

"github.com/charmbracelet/bubbles/spinner"
tea "github.com/charmbracelet/bubbletea"
"github.com/hashicorp/go-getter"
"github.com/pkg/errors"
"github.com/spf13/cobra"

cfg "github.com/cloudposse/atmos/pkg/config"
"github.com/cloudposse/atmos/pkg/schema"
"github.com/cloudposse/atmos/pkg/ui/theme"
u "github.com/cloudposse/atmos/pkg/utils"
)

Expand All @@ -27,28 +30,71 @@ const atmosManifestDefaultFileName = "schemas/atmos/atmos-manifest/1.0/atmos-man

// ExecuteValidateStacksCmd executes `validate stacks` command
func ExecuteValidateStacksCmd(cmd *cobra.Command, args []string) error {
// Initialize spinner
message := "Validating Atmos Stacks..."
s := spinner.New()
s.Style = theme.Styles.Link

var opts []tea.ProgramOption
if !CheckTTYSupport() {
// Workaround for non-TTY environments
opts = []tea.ProgramOption{tea.WithoutRenderer(), tea.WithInput(nil)}
u.LogTrace("No TTY detected. Falling back to basic output. This can happen when no terminal is attached or when commands are pipelined.")
fmt.Println(message)
}

p := tea.NewProgram(modelSpinner{
spinner: s,
message: message,
}, opts...)

// Use error channel to capture spinner errors
spinnerDone := make(chan error, 1)

go func() {
_, err := p.Run()
if err != nil {
fmt.Println(message)
u.LogError(fmt.Errorf("failed to run spinner: %w", err))
}
spinnerDone <- err
close(spinnerDone)
}()

// Process CLI arguments
info, err := ProcessCommandLineArgs("", cmd, args, nil)
if err != nil {
p.Quit()
<-spinnerDone
return err
}

atmosConfig, err := cfg.InitCliConfig(info, true)
if err != nil {
p.Quit()
<-spinnerDone
return err
}

flags := cmd.Flags()

schemasAtmosManifestFlag, err := flags.GetString("schemas-atmos-manifest")
if err != nil {
p.Quit()
<-spinnerDone
return err
}

if schemasAtmosManifestFlag != "" {
atmosConfig.Schemas.Atmos.Manifest = schemasAtmosManifestFlag
}

return ValidateStacks(atmosConfig)
err = ValidateStacks(atmosConfig)

// Ensure spinner is stopped before returning
p.Quit()
<-spinnerDone

return err
}

// ValidateStacks validates Atmos stack configuration
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.