Skip to content

Commit 6c6c657

Browse files
authored
Merge pull request #2268 from diggerhq/feat/breardon2011/wizard
Add wizard for server URL, no env vars needed
2 parents 2ab144e + 3ae752f commit 6c6c657

File tree

5 files changed

+244
-11
lines changed

5 files changed

+244
-11
lines changed

.gitignore

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,6 @@ __azurite*
1717
*.out
1818
go.work.sum
1919

20-
# Taco specific binaries
21-
taco
22-
statesman
23-
terraform-provider-opentaco
24-
opentacosvc
25-
2620
# Build directories
2721
dist/
2822
build/
@@ -35,3 +29,6 @@ bin/
3529
*.swp
3630
*.swo
3731
*~
32+
33+
# data
34+
taco/data/

taco/.gitignore

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
1-
statesman
2-
terraform-provider-opentaco
1+
/taco
2+
/statesman
3+
/terraform-provider-opentaco

taco/cmd/taco/commands/login.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ var loginCmd = &cobra.Command{
6767
}
6868
}
6969
}
70-
if issuer == "" || clientID == "" { return fmt.Errorf("issuer/client-id missing; set flags or configure server /v1/auth/config") }
70+
if issuer == "" || clientID == "" { return fmt.Errorf("OpenTaco could not discover your issuer/client-id, are you sure the server is running?; set flags or configure server /v1/auth/config") }
7171

7272
// Discover endpoints or use overrides
7373
var authEp, tokenEp string

taco/cmd/taco/commands/root.go

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,22 @@ package commands
33
import (
44
"fmt"
55
"os"
6-
76
"github.com/spf13/cobra"
87
)
98

9+
10+
type Config struct {
11+
ServerUrl string `json:"server_url"`
12+
}
13+
14+
1015
var (
1116
// Global flags
1217
serverURL string
1318
verbose bool
1419

20+
globalConfig *Config
21+
1522
// rootCmd represents the base command
1623
rootCmd = &cobra.Command{
1724
Use: "taco",
@@ -20,7 +27,27 @@ var (
2027
2128
It allows you to manage Terraform states, handle locking, and perform state operations
2229
through a simple CLI interface.`,
23-
// Removed email prompt from general commands - now only during login
30+
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
31+
if cmd.Name() == "setup" {
32+
return nil
33+
}
34+
35+
config, err := loadOrCreateConfig()
36+
37+
if err != nil {
38+
return fmt.Errorf("Failed to load configuration: %w", err)
39+
}
40+
41+
globalConfig = config
42+
43+
// Prioritize environment variables over config file
44+
// env > flags > config
45+
if !cmd.Flag("server").Changed && config.ServerUrl != "" {
46+
serverURL = config.ServerUrl
47+
}
48+
49+
return nil
50+
},
2451
}
2552
)
2653

@@ -33,6 +60,9 @@ func init() {
3360
rootCmd.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, "Enable verbose output")
3461
}
3562

63+
64+
65+
3666
// getEnvOrDefault gets an environment variable or returns a default value
3767
func getEnvOrDefault(key, defaultValue string) string {
3868
if value := os.Getenv(key); value != "" {
@@ -49,3 +79,5 @@ func printVerbose(format string, args ...interface{}) {
4979
}
5080

5181

82+
83+

taco/cmd/taco/commands/setup.go

Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
package commands
2+
3+
import(
4+
5+
"fmt"
6+
"github.com/spf13/cobra"
7+
"os"
8+
"path/filepath"
9+
"strings"
10+
"encoding/json"
11+
"bufio"
12+
)
13+
14+
15+
var setupCmd = &cobra.Command{
16+
Use: "setup",
17+
Short: "Run the configuration setup wizard",
18+
Long: "Run the configuration setup wizard to configure your OpenTaco CLI settings.",
19+
RunE: runSetup,
20+
}
21+
22+
func init(){
23+
rootCmd.AddCommand(setupCmd)
24+
}
25+
26+
27+
func runSetup(cmd *cobra.Command, args []string) error {
28+
fmt.Println("OpenTaco CLI Configuration Setup")
29+
fmt.Println("This will update your configuration settings.\n")
30+
31+
config, err := runSetupWizard()
32+
33+
if err != nil {
34+
return err
35+
}
36+
37+
if err := saveConfig(config); err != nil {
38+
return fmt.Errorf("Failed to save configuration %w", err)
39+
}
40+
41+
fmt.Println("Configuration Updated Successfully")
42+
return nil
43+
}
44+
45+
46+
47+
48+
// return the configuration location
49+
func configPath() (string, error) {
50+
home, err := os.UserHomeDir()
51+
52+
if err != nil {
53+
return "", err
54+
}
55+
dir := filepath.Join(home, ".config", "opentaco")
56+
57+
if err := os.MkdirAll(dir, 0o755); err != nil {
58+
return "", err
59+
}
60+
return filepath.Join(dir, "config.json"), nil
61+
62+
}
63+
64+
65+
// loads and returns the config
66+
func loadConfig() (*Config, error) {
67+
path, err := configPath()
68+
69+
if err != nil {
70+
return nil, err
71+
}
72+
73+
data, err := os.ReadFile(path)
74+
75+
if os.IsNotExist(err) {
76+
return nil, nil // config file doesn't exist
77+
}
78+
79+
if err != nil {
80+
return nil, err
81+
}
82+
83+
var config Config
84+
85+
if err := json.Unmarshal(data, &config); err != nil {
86+
return nil, err
87+
}
88+
89+
return &config, nil
90+
}
91+
92+
93+
94+
95+
// saves the configuration to the path
96+
func saveConfig(config *Config) error {
97+
path, err := configPath()
98+
99+
if err != nil {
100+
return err
101+
}
102+
103+
data, err := json.MarshalIndent(config, "", " ")
104+
105+
if err != nil {
106+
return err
107+
}
108+
109+
return os.WriteFile(path, data, 0o600)
110+
}
111+
112+
113+
114+
115+
func loadOrCreateConfig() (*Config, error) {
116+
config, err := loadConfig()
117+
118+
if err != nil {
119+
return nil, err
120+
}
121+
122+
// You dont have a config, start the wizard experience
123+
if config == nil {
124+
fmt.Println("Welcome to OpenTaco CLI!")
125+
fmt.Println("It looks like its your first time running the CLI.")
126+
fmt.Println("Let's setup your configuration.\n")
127+
128+
config, err = runSetupWizard()
129+
130+
if err != nil {
131+
return nil, err
132+
}
133+
134+
if err := saveConfig(config); err != nil {
135+
return nil, fmt.Errorf("Failed to save configuration: %w", err)
136+
}
137+
138+
fmt.Println("Configuration saved successfully!")
139+
fmt.Println("You can reconfigure anytime by running: taco setup\n")
140+
141+
}
142+
143+
144+
return config, nil
145+
146+
}
147+
148+
149+
150+
func runSetupWizard() (*Config, error) {
151+
reader := bufio.NewReader(os.Stdin)
152+
config := &Config{}
153+
154+
// Get server url
155+
156+
for {
157+
158+
fmt.Print("Enter OpenTaco server url [http://localhost:8080]: ")
159+
serverURL, err := reader.ReadString('\n')
160+
if err != nil {
161+
return nil, err
162+
}
163+
164+
serverURL = strings.TrimSpace(serverURL)
165+
if serverURL == "" {
166+
serverURL = "http://localhost:8080"
167+
}
168+
169+
config.ServerUrl = serverURL
170+
171+
break
172+
}
173+
174+
175+
fmt.Println("Configuration Summary:")
176+
fmt.Printf(" Server URL: %s\n", config.ServerUrl)
177+
178+
for {
179+
fmt.Print("\nSave this configuration? [Y/n]: ")
180+
confirm, err := reader.ReadString('\n')
181+
if err != nil {
182+
return nil, err
183+
}
184+
185+
confirm = strings.ToLower(strings.TrimSpace(confirm))
186+
187+
if confirm == "" || confirm == "y" || confirm == "yes"{
188+
return config, nil
189+
} else if confirm == "n" || confirm == "no" {
190+
fmt.Println("Configuration cancelled")
191+
os.Exit(0)
192+
} else {
193+
fmt.Println("Please enter 'y' for yes or 'n' for no.")
194+
}
195+
}
196+
197+
}
198+
199+
200+
func GetGlobalConfig() *Config {
201+
return globalConfig
202+
}
203+

0 commit comments

Comments
 (0)