Skip to content

Commit 1822d87

Browse files
committed
wip - wizard
1 parent cc5b7d3 commit 1822d87

File tree

2 files changed

+226
-7
lines changed

2 files changed

+226
-7
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/cmd/taco/commands/root.go

Lines changed: 223 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,21 @@ import (
77
"github.com/spf13/cobra"
88
)
99

10+
11+
type Config struct {
12+
ServerUrl string `json:"server_url"`
13+
Issuer string `json:"issuer"`
14+
ClientID string `json:"client_id"`
15+
}
16+
17+
1018
var (
1119
// Global flags
1220
serverURL string
1321
verbose bool
1422

23+
globalConfig *Config
24+
1525
// rootCmd represents the base command
1626
rootCmd = &cobra.Command{
1727
Use: "taco",
@@ -20,7 +30,28 @@ var (
2030
2131
It allows you to manage Terraform states, handle locking, and perform state operations
2232
through a simple CLI interface.`,
23-
// Removed email prompt from general commands - now only during login
33+
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
34+
if cmd.Name() == "setup" {
35+
return nil
36+
}
37+
38+
config, err := loadOrCreateConfig()
39+
40+
if err != nil{
41+
return fmt.Errorf("Failed to load configuration: %w", err)
42+
}
43+
44+
globalConfig = config
45+
46+
if !cmd.Flag("server").Changed && config.ServerUrl != "" {
47+
serverUrl = config.ServerURL
48+
}
49+
50+
return nil
51+
}
52+
53+
54+
2455
}
2556
)
2657

@@ -33,6 +64,197 @@ func init() {
3364
rootCmd.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, "Enable verbose output")
3465
}
3566

67+
68+
// return the configuration location
69+
func configPath() (string, error) {
70+
home, err := os.UserHomeDir()
71+
72+
if err != nil {
73+
return "", err
74+
}
75+
dir := filepath.Join(home, ".config", "opentaco")
76+
if err := os. MkdirAll(dir, 0o755): err != nil {
77+
return "", err
78+
}
79+
return filepath.Join(dir, "config.json"), nil
80+
81+
}
82+
83+
84+
// loads and returns the config
85+
func loadConfig() (*Config, error) {
86+
path, error := configPath()
87+
88+
if err != nil {
89+
return nil, err
90+
}
91+
92+
data, err := os.ReadFile(path)
93+
94+
if os.IsNotExist(err) {
95+
return nil, nil // config file doesn't exist
96+
}
97+
98+
if err != nil {
99+
return nil, err
100+
}
101+
102+
var config Config
103+
104+
if err := json.Unmarshal(data, &config); err != nil {
105+
return nil, err
106+
}
107+
108+
return &config, nil
109+
}
110+
111+
112+
113+
114+
// saves the configuration to the path
115+
func saveConfig(config *Config) error {
116+
path, err := configPath()
117+
118+
if err != nil {
119+
return err
120+
}
121+
122+
data, err := json.MarshalIndent(config, "", " ")
123+
124+
if err != nil {
125+
return err
126+
}
127+
128+
return os.WriteFile(path, data, 0o600)
129+
}
130+
131+
132+
133+
134+
func loadOrCreateConfig() (*Config, error) {
135+
config, err := loadConfig()
136+
137+
if err != nil {
138+
return nil, err
139+
}
140+
141+
// You dont have a config, start the wizard experience
142+
if config == nil {
143+
fmt.Println("Welcome to OpenTaco CLI!")
144+
fmt.Println("It looks like its your first time running the CLI.")
145+
fmt.Println("Let's setup your configuration.\n")
146+
147+
config, err = runSetupWizard()
148+
149+
if err != nil {
150+
return nil, err
151+
}
152+
153+
if err := saveConfig(config); err != nil {
154+
return nil, fmt.Error("Failed to save configuration: %w", err)
155+
}
156+
157+
fmt.Println("Configuration saved successfully!")
158+
fmt.Println("You can reconfigure anytime by running: taco setup\n")
159+
160+
}
161+
162+
163+
return config, nil
164+
165+
}
166+
167+
168+
169+
func runSetupWizard() (*Config, error) {
170+
reader := bufio.NewReader(os.Stdin)
171+
config := &Config()
172+
173+
// Get server url
174+
175+
for {
176+
177+
fmt.Print("Enter OpenTaco server url [http://localhost:8080]:")
178+
serverURL, err := reader.ReadString('\n')
179+
if err != nil {
180+
return nil, err
181+
}
182+
183+
serverURL = strings.TrimSpace(serverURL)
184+
if serverURL = "" {
185+
serverURL = "http://localhost:8080"
186+
}
187+
188+
config.ServerURL = serverURL
189+
190+
break
191+
}
192+
193+
// get OIDC issuer
194+
195+
for {
196+
fmt.Print("Enter OIDC issuer URL:")
197+
issuer, err := reader.ReadString('\n')
198+
199+
if err != nil {
200+
return nil, err
201+
}
202+
203+
config.Issuer = strings.TrimSpace(issuer)
204+
break
205+
}
206+
207+
// get OIDC client ID
208+
209+
for {
210+
fmt.Print("Enter the OIDC client ID:")
211+
clientID, err := reader.ReadString('\n')
212+
213+
if err != nil {
214+
215+
return nil, err
216+
}
217+
218+
config.ClientID = strings.TrimSpace(clientID)
219+
break
220+
}
221+
222+
223+
fmt.Println("Configuration Summary:")
224+
fmt.Printf(" Server URL: %s\n", config.ServerURL)
225+
if config.Issuer != "" {
226+
fmt.Printf(" OIDC Issuer: %s\n", config.Issuer)
227+
}
228+
229+
if config.ClientID != "" {
230+
fmt.Printf(" OIDC Client ID: %s\n", config.ClientID)
231+
}
232+
233+
for {
234+
fmt.Print("\nSave this configuration? [Y/n]: ")
235+
confirm, err := reader.ReadString('\n')
236+
if err != nil {
237+
return nil, err
238+
}
239+
240+
confirm = strings.ToLowr(strings.TrimSpace(confirm))
241+
242+
if confirm == "" || confirm == "y" || confirm == "yes"{
243+
return config, nil
244+
} else if confirm == "n" || confirm == "no" {
245+
fmt.Println("Configuratin cancelled")
246+
os.Exit(0)
247+
} else {
248+
fmt.Println("Please enter 'y' for yes or 'n' for no.")
249+
}
250+
}
251+
252+
}
253+
254+
255+
256+
257+
36258
// getEnvOrDefault gets an environment variable or returns a default value
37259
func getEnvOrDefault(key, defaultValue string) string {
38260
if value := os.Getenv(key); value != "" {

0 commit comments

Comments
 (0)