@@ -11,12 +11,15 @@ import (
11
11
"strings"
12
12
"time"
13
13
14
+ "github.com/charmbracelet/bubbles/spinner"
15
+ tea "github.com/charmbracelet/bubbletea"
14
16
"github.com/hashicorp/go-getter"
15
17
"github.com/pkg/errors"
16
18
"github.com/spf13/cobra"
17
19
18
20
cfg "github.com/cloudposse/atmos/pkg/config"
19
21
"github.com/cloudposse/atmos/pkg/schema"
22
+ "github.com/cloudposse/atmos/pkg/ui/theme"
20
23
u "github.com/cloudposse/atmos/pkg/utils"
21
24
)
22
25
@@ -27,28 +30,71 @@ const atmosManifestDefaultFileName = "schemas/atmos/atmos-manifest/1.0/atmos-man
27
30
28
31
// ExecuteValidateStacksCmd executes `validate stacks` command
29
32
func ExecuteValidateStacksCmd (cmd * cobra.Command , args []string ) error {
33
+ // Initialize spinner
34
+ message := "Validating Atmos Stacks..."
35
+ s := spinner .New ()
36
+ s .Style = theme .Styles .Link
37
+
38
+ var opts []tea.ProgramOption
39
+ if ! CheckTTYSupport () {
40
+ // Workaround for non-TTY environments
41
+ opts = []tea.ProgramOption {tea .WithoutRenderer (), tea .WithInput (nil )}
42
+ u .LogTrace ("No TTY detected. Falling back to basic output. This can happen when no terminal is attached or when commands are pipelined." )
43
+ fmt .Println (message )
44
+ }
45
+
46
+ p := tea .NewProgram (modelSpinner {
47
+ spinner : s ,
48
+ message : message ,
49
+ }, opts ... )
50
+
51
+ // Use error channel to capture spinner errors
52
+ spinnerDone := make (chan error , 1 )
53
+
54
+ go func () {
55
+ _ , err := p .Run ()
56
+ if err != nil {
57
+ fmt .Println (message )
58
+ u .LogError (fmt .Errorf ("failed to run spinner: %w" , err ))
59
+ }
60
+ spinnerDone <- err
61
+ close (spinnerDone )
62
+ }()
63
+
64
+ // Process CLI arguments
30
65
info , err := ProcessCommandLineArgs ("" , cmd , args , nil )
31
66
if err != nil {
67
+ p .Quit ()
68
+ <- spinnerDone
32
69
return err
33
70
}
34
71
35
72
atmosConfig , err := cfg .InitCliConfig (info , true )
36
73
if err != nil {
74
+ p .Quit ()
75
+ <- spinnerDone
37
76
return err
38
77
}
39
78
40
79
flags := cmd .Flags ()
41
-
42
80
schemasAtmosManifestFlag , err := flags .GetString ("schemas-atmos-manifest" )
43
81
if err != nil {
82
+ p .Quit ()
83
+ <- spinnerDone
44
84
return err
45
85
}
46
86
47
87
if schemasAtmosManifestFlag != "" {
48
88
atmosConfig .Schemas .Atmos .Manifest = schemasAtmosManifestFlag
49
89
}
50
90
51
- return ValidateStacks (atmosConfig )
91
+ err = ValidateStacks (atmosConfig )
92
+
93
+ // Ensure spinner is stopped before returning
94
+ p .Quit ()
95
+ <- spinnerDone
96
+
97
+ return err
52
98
}
53
99
54
100
// ValidateStacks validates Atmos stack configuration
0 commit comments