detached 7d8603d

Refactor NewClientApp and Configuration Logic

- Add error handling in NewClientApp
- Simplify configuration loading and saving
- Remove redundant config handler in CLI
commit
7d8603d1c9f06a1e343eca6005a393d14b157071
author
bnema · · 2023-10-24 10:09 UTC
parent
befdbe3
signature
unsigned
4 files · +303 -95
A changes.tx +232 -0
@@ -0,0 +1,232 @@
1+diff --git a/cmd/cli/main.go b/cmd/cli/main.go
2+index 8cf8d6c..8ba374c 100644
3+--- a/cmd/cli/main.go
4++++ b/cmd/cli/main.go
5+@@ -1,11 +1,16 @@
6+ package main
7+
8+ import (
9++ "fmt"
10++
11+ "github.com/bnema/gordon/internal/app"
12+ "github.com/bnema/gordon/internal/cli"
13+ )
14+
15+ func main() {
16+- a := app.NewClientApp()
17++ a, err := app.NewClientApp()
18++ if err != nil {
19++ fmt.Println("Error initializing app:", err)
20++ }
21+ cli.Execute(a)
22+ }
23+diff --git a/internal/app/newclient.go b/internal/app/newclient.go
24+index ec6bb4b..c51c1bf 100644
25+--- a/internal/app/newclient.go
26++++ b/internal/app/newclient.go
27+@@ -11,118 +11,105 @@ import (
28+ "gopkg.in/yaml.v3"
29+ )
30+
31+-func NewClientApp() *App {
32+- // Initialize AppConfig
33++// NewClientApp initializes a new App with configuration.
34++func NewClientApp() (*App, error) {
35+ config := &Config{}
36+ config, err := config.LoadClientConfig()
37+ if err != nil {
38+- log.Fatalf("Failed to load configuration: %v", err)
39++ return nil, fmt.Errorf("failed to load configuration: %w", err)
40+ }
41+-
42+- // Initialize App
43+- a := &App{
44+- Config: *config,
45+- }
46+- return a
47++ return &App{Config: *config}, nil
48+ }
49+
50+-func (config *Config) LoadClientConfig() (*Config, error) {
51+- configFileName := "config.yml"
52++// getConfigDir returns the configuration directory based on the operating system.
53++func getConfigDir() (string, error) {
54+ usr, err := user.Current()
55+ if err != nil {
56+- return nil, fmt.Errorf("error getting user's home directory: %w", err)
57++ return "", fmt.Errorf("error getting user's home directory: %w", err)
58+ }
59+
60+ var configDir string
61+-
62+ if runtime.GOOS == "windows" {
63+ configDir = filepath.Join(usr.HomeDir, "AppData", "Roaming", "Gordon")
64+ } else {
65+ configDir = filepath.Join(usr.HomeDir, ".config", "Gordon")
66+ }
67++ return configDir, nil
68++}
69+
70+- if err := os.MkdirAll(configDir, 0755); err != nil {
71+- return nil, fmt.Errorf("error creating configuration directory: %w", err)
72++// configPath returns the path of the configuration directory and file.
73++func configPath() (string, string) {
74++ configDir, err := getConfigDir()
75++ if err != nil {
76++ log.Fatalf("error getting configuration directory: %v", err)
77+ }
78++ configFilePath := filepath.Join(configDir, "config.yml")
79++ return configDir, configFilePath
80++}
81+
82+- configFilePath := filepath.Join(configDir, configFileName)
83+-
84+- if _, err := os.Stat(configFilePath); os.IsNotExist(err) {
85+- fmt.Printf("Config file not found, creating it at %s\n", configFilePath)
86+- defaultConfig := []byte("some: default\ndata: here\n")
87+- if err := os.WriteFile(configFilePath, defaultConfig, 0666); err != nil {
88+- return nil, fmt.Errorf("error writing default configuration: %w", err)
89+- }
90+- } else if err != nil {
91+- return nil, fmt.Errorf("error checking configuration file: %w", err)
92++// SaveConfig saves the current configuration to a file.
93++func (config *Config) SaveConfig() error {
94++ configDir, err := getConfigDir()
95++ if err != nil {
96++ return err
97+ }
98+-
99+- // Read and unmarshal the config file
100+- configData, err := os.ReadFile(configFilePath)
101++ configFilePath := filepath.Join(configDir, "config.yml")
102++ data, err := yaml.Marshal(config)
103+ if err != nil {
104+- return nil, fmt.Errorf("error reading configuration file: %w", err)
105++ return fmt.Errorf("failed to marshal config: %v", err)
106++ }
107++ if err := os.WriteFile(configFilePath, data, 0644); err != nil {
108++ return fmt.Errorf("failed to write to config file: %v", err)
109+ }
110++ return nil
111++}
112+
113+- err = yaml.Unmarshal(configData, &config)
114++// readAndUnmarshalConfig reads the config file and unmarshals it into the given config.
115++func readAndUnmarshalConfig(filePath string, config *Config) error {
116++ configData, err := os.ReadFile(filePath)
117+ if err != nil {
118+- return nil, fmt.Errorf("error unmarshalling configuration file: %w", err)
119++ return fmt.Errorf("error reading configuration file: %w", err)
120+ }
121++ return yaml.Unmarshal(configData, config)
122++}
123+
124+- // New logic for backend URL and token
125+- needsSave := false
126++// LoadClientConfig loads the client configuration.
127++func (config *Config) LoadClientConfig() (*Config, error) {
128++ configDir, configFilePath := configPath()
129+
130+- if config.Http.BackendURL == "" {
131+- fmt.Println("Please enter the backend URL:")
132+- var backendURL string
133+- fmt.Scanln(&backendURL)
134+- config.Http.BackendURL = backendURL
135+- needsSave = true
136++ if err := os.MkdirAll(configDir, 0755); err != nil {
137++ return nil, fmt.Errorf("error creating configuration directory: %w", err)
138+ }
139+
140+- if config.General.GordonToken == "" {
141+- fmt.Println("Please enter the token:")
142+- var token string
143+- fmt.Scanln(&token)
144+- config.General.GordonToken = token
145+- needsSave = true
146+- }
147++ // Check if the file exists
148++ if _, err := os.Stat(configFilePath); os.IsNotExist(err) {
149++ fmt.Printf("Config file not found, creating it at %s\n", configFilePath)
150+
151+- if needsSave {
152+- err := config.SaveConfig() // Assuming SaveConfig is a method that saves the config to file
153+- if err != nil {
154+- return nil, fmt.Errorf("error saving configuration file: %w", err)
155++ // Prompt user for initial settings
156++ config.Http.BackendURL = readUserInput("Enter the backend URL:")
157++ config.General.GordonToken = readUserInput("Enter the Gordon token:")
158++
159++ // Save the new configuration
160++ if err := config.SaveConfig(); err != nil {
161++ return nil, fmt.Errorf("error saving new configuration: %w", err)
162++ }
163++ } else if err != nil {
164++ // Some other error occurred while checking the file
165++ return nil, fmt.Errorf("error checking configuration file: %w", err)
166++ } else {
167++ // File exists, read and unmarshal it
168++ if err := readAndUnmarshalConfig(configFilePath, config); err != nil {
169++ return nil, err
170+ }
171+ }
172+
173+ return config, nil
174+ }
175+
176+-func (config *Config) SaveConfig() error {
177+- usr, err := user.Current()
178+- if err != nil {
179+- return fmt.Errorf("error getting user's home directory: %w", err)
180+- }
181+-
182+- var configDir string
183+- if runtime.GOOS == "windows" {
184+- configDir = filepath.Join(usr.HomeDir, "AppData", "Roaming", "Gordon")
185+- } else {
186+- configDir = filepath.Join(usr.HomeDir, ".config", "Gordon")
187+- }
188+-
189+- configFilePath := filepath.Join(configDir, "config.yml")
190+-
191+- // Marshal the config struct into YAML
192+- data, err := yaml.Marshal(config)
193+- if err != nil {
194+- return fmt.Errorf("failed to marshal config: %v", err)
195+- }
196+-
197+- // Write the data to the config file
198+- err = os.WriteFile(configFilePath, data, 0644)
199+- if err != nil {
200+- return fmt.Errorf("failed to write to config file: %v", err)
201+- }
202+-
203+- return nil
204++// readUserInput reads a string input from the user with a prompt.
205++func readUserInput(prompt string) string {
206++ fmt.Println(prompt)
207++ var input string
208++ fmt.Scanln(&input)
209++ return input
210+ }
211+diff --git a/internal/cli/handler/configfile.go b/internal/cli/handler/configfile.go
212+deleted file mode 100644
213+index e1a3f6b..0000000
214+--- a/internal/cli/handler/configfile.go
215++++ /dev/null
216+@@ -1,16 +0,0 @@
217+-package handler
218+-
219+-import "github.com/bnema/gordon/internal/app"
220+-
221+-// I need to handle the case of the backend URL not being present in the config file
222+-func IsBackendURLPresent(a *app.App) bool {
223+- // since config.yml is loaded from newclient.go, I can access the backend URL from the app struct
224+-
225+- if a.Config.Http.BackendURL == "" {
226+- return false
227+- }
228+-
229+- return true
230+-}
231+-
232+-// I Need to handle the case the token is not present in the config file
@@ -0,0 +1,232 @@
1+diff --git a/cmd/cli/main.go b/cmd/cli/main.go
2+index 8cf8d6c..8ba374c 100644
3+--- a/cmd/cli/main.go
4++++ b/cmd/cli/main.go
5+@@ -1,11 +1,16 @@
6+ package main
7+
8+ import (
9++ "fmt"
10++
11+ "github.com/bnema/gordon/internal/app"
12+ "github.com/bnema/gordon/internal/cli"
13+ )
14+
15+ func main() {
16+- a := app.NewClientApp()
17++ a, err := app.NewClientApp()
18++ if err != nil {
19++ fmt.Println("Error initializing app:", err)
20++ }
21+ cli.Execute(a)
22+ }
23+diff --git a/internal/app/newclient.go b/internal/app/newclient.go
24+index ec6bb4b..c51c1bf 100644
25+--- a/internal/app/newclient.go
26++++ b/internal/app/newclient.go
27+@@ -11,118 +11,105 @@ import (
28+ "gopkg.in/yaml.v3"
29+ )
30+
31+-func NewClientApp() *App {
32+- // Initialize AppConfig
33++// NewClientApp initializes a new App with configuration.
34++func NewClientApp() (*App, error) {
35+ config := &Config{}
36+ config, err := config.LoadClientConfig()
37+ if err != nil {
38+- log.Fatalf("Failed to load configuration: %v", err)
39++ return nil, fmt.Errorf("failed to load configuration: %w", err)
40+ }
41+-
42+- // Initialize App
43+- a := &App{
44+- Config: *config,
45+- }
46+- return a
47++ return &App{Config: *config}, nil
48+ }
49+
50+-func (config *Config) LoadClientConfig() (*Config, error) {
51+- configFileName := "config.yml"
52++// getConfigDir returns the configuration directory based on the operating system.
53++func getConfigDir() (string, error) {
54+ usr, err := user.Current()
55+ if err != nil {
56+- return nil, fmt.Errorf("error getting user's home directory: %w", err)
57++ return "", fmt.Errorf("error getting user's home directory: %w", err)
58+ }
59+
60+ var configDir string
61+-
62+ if runtime.GOOS == "windows" {
63+ configDir = filepath.Join(usr.HomeDir, "AppData", "Roaming", "Gordon")
64+ } else {
65+ configDir = filepath.Join(usr.HomeDir, ".config", "Gordon")
66+ }
67++ return configDir, nil
68++}
69+
70+- if err := os.MkdirAll(configDir, 0755); err != nil {
71+- return nil, fmt.Errorf("error creating configuration directory: %w", err)
72++// configPath returns the path of the configuration directory and file.
73++func configPath() (string, string) {
74++ configDir, err := getConfigDir()
75++ if err != nil {
76++ log.Fatalf("error getting configuration directory: %v", err)
77+ }
78++ configFilePath := filepath.Join(configDir, "config.yml")
79++ return configDir, configFilePath
80++}
81+
82+- configFilePath := filepath.Join(configDir, configFileName)
83+-
84+- if _, err := os.Stat(configFilePath); os.IsNotExist(err) {
85+- fmt.Printf("Config file not found, creating it at %s\n", configFilePath)
86+- defaultConfig := []byte("some: default\ndata: here\n")
87+- if err := os.WriteFile(configFilePath, defaultConfig, 0666); err != nil {
88+- return nil, fmt.Errorf("error writing default configuration: %w", err)
89+- }
90+- } else if err != nil {
91+- return nil, fmt.Errorf("error checking configuration file: %w", err)
92++// SaveConfig saves the current configuration to a file.
93++func (config *Config) SaveConfig() error {
94++ configDir, err := getConfigDir()
95++ if err != nil {
96++ return err
97+ }
98+-
99+- // Read and unmarshal the config file
100+- configData, err := os.ReadFile(configFilePath)
101++ configFilePath := filepath.Join(configDir, "config.yml")
102++ data, err := yaml.Marshal(config)
103+ if err != nil {
104+- return nil, fmt.Errorf("error reading configuration file: %w", err)
105++ return fmt.Errorf("failed to marshal config: %v", err)
106++ }
107++ if err := os.WriteFile(configFilePath, data, 0644); err != nil {
108++ return fmt.Errorf("failed to write to config file: %v", err)
109+ }
110++ return nil
111++}
112+
113+- err = yaml.Unmarshal(configData, &config)
114++// readAndUnmarshalConfig reads the config file and unmarshals it into the given config.
115++func readAndUnmarshalConfig(filePath string, config *Config) error {
116++ configData, err := os.ReadFile(filePath)
117+ if err != nil {
118+- return nil, fmt.Errorf("error unmarshalling configuration file: %w", err)
119++ return fmt.Errorf("error reading configuration file: %w", err)
120+ }
121++ return yaml.Unmarshal(configData, config)
122++}
123+
124+- // New logic for backend URL and token
125+- needsSave := false
126++// LoadClientConfig loads the client configuration.
127++func (config *Config) LoadClientConfig() (*Config, error) {
128++ configDir, configFilePath := configPath()
129+
130+- if config.Http.BackendURL == "" {
131+- fmt.Println("Please enter the backend URL:")
132+- var backendURL string
133+- fmt.Scanln(&backendURL)
134+- config.Http.BackendURL = backendURL
135+- needsSave = true
136++ if err := os.MkdirAll(configDir, 0755); err != nil {
137++ return nil, fmt.Errorf("error creating configuration directory: %w", err)
138+ }
139+
140+- if config.General.GordonToken == "" {
141+- fmt.Println("Please enter the token:")
142+- var token string
143+- fmt.Scanln(&token)
144+- config.General.GordonToken = token
145+- needsSave = true
146+- }
147++ // Check if the file exists
148++ if _, err := os.Stat(configFilePath); os.IsNotExist(err) {
149++ fmt.Printf("Config file not found, creating it at %s\n", configFilePath)
150+
151+- if needsSave {
152+- err := config.SaveConfig() // Assuming SaveConfig is a method that saves the config to file
153+- if err != nil {
154+- return nil, fmt.Errorf("error saving configuration file: %w", err)
155++ // Prompt user for initial settings
156++ config.Http.BackendURL = readUserInput("Enter the backend URL:")
157++ config.General.GordonToken = readUserInput("Enter the Gordon token:")
158++
159++ // Save the new configuration
160++ if err := config.SaveConfig(); err != nil {
161++ return nil, fmt.Errorf("error saving new configuration: %w", err)
162++ }
163++ } else if err != nil {
164++ // Some other error occurred while checking the file
165++ return nil, fmt.Errorf("error checking configuration file: %w", err)
166++ } else {
167++ // File exists, read and unmarshal it
168++ if err := readAndUnmarshalConfig(configFilePath, config); err != nil {
169++ return nil, err
170+ }
171+ }
172+
173+ return config, nil
174+ }
175+
176+-func (config *Config) SaveConfig() error {
177+- usr, err := user.Current()
178+- if err != nil {
179+- return fmt.Errorf("error getting user's home directory: %w", err)
180+- }
181+-
182+- var configDir string
183+- if runtime.GOOS == "windows" {
184+- configDir = filepath.Join(usr.HomeDir, "AppData", "Roaming", "Gordon")
185+- } else {
186+- configDir = filepath.Join(usr.HomeDir, ".config", "Gordon")
187+- }
188+-
189+- configFilePath := filepath.Join(configDir, "config.yml")
190+-
191+- // Marshal the config struct into YAML
192+- data, err := yaml.Marshal(config)
193+- if err != nil {
194+- return fmt.Errorf("failed to marshal config: %v", err)
195+- }
196+-
197+- // Write the data to the config file
198+- err = os.WriteFile(configFilePath, data, 0644)
199+- if err != nil {
200+- return fmt.Errorf("failed to write to config file: %v", err)
201+- }
202+-
203+- return nil
204++// readUserInput reads a string input from the user with a prompt.
205++func readUserInput(prompt string) string {
206++ fmt.Println(prompt)
207++ var input string
208++ fmt.Scanln(&input)
209++ return input
210+ }
211+diff --git a/internal/cli/handler/configfile.go b/internal/cli/handler/configfile.go
212+deleted file mode 100644
213+index e1a3f6b..0000000
214+--- a/internal/cli/handler/configfile.go
215++++ /dev/null
216+@@ -1,16 +0,0 @@
217+-package handler
218+-
219+-import "github.com/bnema/gordon/internal/app"
220+-
221+-// I need to handle the case of the backend URL not being present in the config file
222+-func IsBackendURLPresent(a *app.App) bool {
223+- // since config.yml is loaded from newclient.go, I can access the backend URL from the app struct
224+-
225+- if a.Config.Http.BackendURL == "" {
226+- return false
227+- }
228+-
229+- return true
230+-}
231+-
232+-// I Need to handle the case the token is not present in the config file
M cmd/cli/main.go +6 -1
@@ -1,11 +1,16 @@
11 package main
22
33 import (
4+ "fmt"
5+
46 "github.com/bnema/gordon/internal/app"
57 "github.com/bnema/gordon/internal/cli"
68 )
79
810 func main() {
9- a := app.NewClientApp()
11+ a, err := app.NewClientApp()
12+ if err != nil {
13+ fmt.Println("Error initializing app:", err)
14+ }
1015 cli.Execute(a)
1116 }
@@ -1,11 +1,16 @@
1 package main1 package main
2 2
3 import (3 import (
4+ "fmt"
5+
4 "github.com/bnema/gordon/internal/app"6 "github.com/bnema/gordon/internal/app"
5 "github.com/bnema/gordon/internal/cli"7 "github.com/bnema/gordon/internal/cli"
6 )8 )
7 9
8 func main() {10 func main() {
9- a := app.NewClientApp()11+ a, err := app.NewClientApp()
12+ if err != nil {
13+ fmt.Println("Error initializing app:", err)
14+ }
10 cli.Execute(a)15 cli.Execute(a)
11 }16 }
M internal/app/newclient.go +65 -78
@@ -11,118 +11,105 @@ import (
1111 "gopkg.in/yaml.v3"
1212 )
1313
14-func NewClientApp() *App {
15- // Initialize AppConfig
14+// NewClientApp initializes a new App with configuration.
15+func NewClientApp() (*App, error) {
1616 config := &Config{}
1717 config, err := config.LoadClientConfig()
1818 if err != nil {
19- log.Fatalf("Failed to load configuration: %v", err)
19+ return nil, fmt.Errorf("failed to load configuration: %w", err)
2020 }
21-
22- // Initialize App
23- a := &App{
24- Config: *config,
25- }
26- return a
21+ return &App{Config: *config}, nil
2722 }
2823
29-func (config *Config) LoadClientConfig() (*Config, error) {
30- configFileName := "config.yml"
24+// getConfigDir returns the configuration directory based on the operating system.
25+func getConfigDir() (string, error) {
3126 usr, err := user.Current()
3227 if err != nil {
33- return nil, fmt.Errorf("error getting user's home directory: %w", err)
28+ return "", fmt.Errorf("error getting user's home directory: %w", err)
3429 }
3530
3631 var configDir string
37-
3832 if runtime.GOOS == "windows" {
3933 configDir = filepath.Join(usr.HomeDir, "AppData", "Roaming", "Gordon")
4034 } else {
4135 configDir = filepath.Join(usr.HomeDir, ".config", "Gordon")
4236 }
37+ return configDir, nil
38+}
4339
44- if err := os.MkdirAll(configDir, 0755); err != nil {
45- return nil, fmt.Errorf("error creating configuration directory: %w", err)
40+// configPath returns the path of the configuration directory and file.
41+func configPath() (string, string) {
42+ configDir, err := getConfigDir()
43+ if err != nil {
44+ log.Fatalf("error getting configuration directory: %v", err)
4645 }
46+ configFilePath := filepath.Join(configDir, "config.yml")
47+ return configDir, configFilePath
48+}
4749
48- configFilePath := filepath.Join(configDir, configFileName)
49-
50- if _, err := os.Stat(configFilePath); os.IsNotExist(err) {
51- fmt.Printf("Config file not found, creating it at %s\n", configFilePath)
52- defaultConfig := []byte("some: default\ndata: here\n")
53- if err := os.WriteFile(configFilePath, defaultConfig, 0666); err != nil {
54- return nil, fmt.Errorf("error writing default configuration: %w", err)
55- }
56- } else if err != nil {
57- return nil, fmt.Errorf("error checking configuration file: %w", err)
50+// SaveConfig saves the current configuration to a file.
51+func (config *Config) SaveConfig() error {
52+ configDir, err := getConfigDir()
53+ if err != nil {
54+ return err
5855 }
59-
60- // Read and unmarshal the config file
61- configData, err := os.ReadFile(configFilePath)
56+ configFilePath := filepath.Join(configDir, "config.yml")
57+ data, err := yaml.Marshal(config)
6258 if err != nil {
63- return nil, fmt.Errorf("error reading configuration file: %w", err)
59+ return fmt.Errorf("failed to marshal config: %v", err)
60+ }
61+ if err := os.WriteFile(configFilePath, data, 0644); err != nil {
62+ return fmt.Errorf("failed to write to config file: %v", err)
6463 }
64+ return nil
65+}
6566
66- err = yaml.Unmarshal(configData, &config)
67+// readAndUnmarshalConfig reads the config file and unmarshals it into the given config.
68+func readAndUnmarshalConfig(filePath string, config *Config) error {
69+ configData, err := os.ReadFile(filePath)
6770 if err != nil {
68- return nil, fmt.Errorf("error unmarshalling configuration file: %w", err)
71+ return fmt.Errorf("error reading configuration file: %w", err)
6972 }
73+ return yaml.Unmarshal(configData, config)
74+}
7075
71- // New logic for backend URL and token
72- needsSave := false
76+// LoadClientConfig loads the client configuration.
77+func (config *Config) LoadClientConfig() (*Config, error) {
78+ configDir, configFilePath := configPath()
7379
74- if config.Http.BackendURL == "" {
75- fmt.Println("Please enter the backend URL:")
76- var backendURL string
77- fmt.Scanln(&backendURL)
78- config.Http.BackendURL = backendURL
79- needsSave = true
80+ if err := os.MkdirAll(configDir, 0755); err != nil {
81+ return nil, fmt.Errorf("error creating configuration directory: %w", err)
8082 }
8183
82- if config.General.GordonToken == "" {
83- fmt.Println("Please enter the token:")
84- var token string
85- fmt.Scanln(&token)
86- config.General.GordonToken = token
87- needsSave = true
88- }
84+ // Check if the file exists
85+ if _, err := os.Stat(configFilePath); os.IsNotExist(err) {
86+ fmt.Printf("Config file not found, creating it at %s\n", configFilePath)
8987
90- if needsSave {
91- err := config.SaveConfig() // Assuming SaveConfig is a method that saves the config to file
92- if err != nil {
93- return nil, fmt.Errorf("error saving configuration file: %w", err)
88+ // Prompt user for initial settings
89+ config.Http.BackendURL = readUserInput("Enter the backend URL:")
90+ config.General.GordonToken = readUserInput("Enter the Gordon token:")
91+
92+ // Save the new configuration
93+ if err := config.SaveConfig(); err != nil {
94+ return nil, fmt.Errorf("error saving new configuration: %w", err)
95+ }
96+ } else if err != nil {
97+ // Some other error occurred while checking the file
98+ return nil, fmt.Errorf("error checking configuration file: %w", err)
99+ } else {
100+ // File exists, read and unmarshal it
101+ if err := readAndUnmarshalConfig(configFilePath, config); err != nil {
102+ return nil, err
94103 }
95104 }
96105
97106 return config, nil
98107 }
99108
100-func (config *Config) SaveConfig() error {
101- usr, err := user.Current()
102- if err != nil {
103- return fmt.Errorf("error getting user's home directory: %w", err)
104- }
105-
106- var configDir string
107- if runtime.GOOS == "windows" {
108- configDir = filepath.Join(usr.HomeDir, "AppData", "Roaming", "Gordon")
109- } else {
110- configDir = filepath.Join(usr.HomeDir, ".config", "Gordon")
111- }
112-
113- configFilePath := filepath.Join(configDir, "config.yml")
114-
115- // Marshal the config struct into YAML
116- data, err := yaml.Marshal(config)
117- if err != nil {
118- return fmt.Errorf("failed to marshal config: %v", err)
119- }
120-
121- // Write the data to the config file
122- err = os.WriteFile(configFilePath, data, 0644)
123- if err != nil {
124- return fmt.Errorf("failed to write to config file: %v", err)
125- }
126-
127- return nil
109+// readUserInput reads a string input from the user with a prompt.
110+func readUserInput(prompt string) string {
111+ fmt.Println(prompt)
112+ var input string
113+ fmt.Scanln(&input)
114+ return input
128115 }
@@ -11,118 +11,105 @@ import (
11 "gopkg.in/yaml.v3"11 "gopkg.in/yaml.v3"
12 )12 )
13 13
14-func NewClientApp() *App {14+// NewClientApp initializes a new App with configuration.
15- // Initialize AppConfig15+func NewClientApp() (*App, error) {
16 config := &Config{}16 config := &Config{}
17 config, err := config.LoadClientConfig()17 config, err := config.LoadClientConfig()
18 if err != nil {18 if err != nil {
19- log.Fatalf("Failed to load configuration: %v", err)19+ return nil, fmt.Errorf("failed to load configuration: %w", err)
20 }20 }
21-21+ return &App{Config: *config}, nil
22- // Initialize App
23- a := &App{
24- Config: *config,
25- }
26- return a
27 }22 }
28 23
29-func (config *Config) LoadClientConfig() (*Config, error) {24+// getConfigDir returns the configuration directory based on the operating system.
30- configFileName := "config.yml"25+func getConfigDir() (string, error) {
31 usr, err := user.Current()26 usr, err := user.Current()
32 if err != nil {27 if err != nil {
33- return nil, fmt.Errorf("error getting user's home directory: %w", err)28+ return "", fmt.Errorf("error getting user's home directory: %w", err)
34 }29 }
35 30
36 var configDir string31 var configDir string
37-
38 if runtime.GOOS == "windows" {32 if runtime.GOOS == "windows" {
39 configDir = filepath.Join(usr.HomeDir, "AppData", "Roaming", "Gordon")33 configDir = filepath.Join(usr.HomeDir, "AppData", "Roaming", "Gordon")
40 } else {34 } else {
41 configDir = filepath.Join(usr.HomeDir, ".config", "Gordon")35 configDir = filepath.Join(usr.HomeDir, ".config", "Gordon")
42 }36 }
37+ return configDir, nil
38+}
43 39
44- if err := os.MkdirAll(configDir, 0755); err != nil {40+// configPath returns the path of the configuration directory and file.
45- return nil, fmt.Errorf("error creating configuration directory: %w", err)41+func configPath() (string, string) {
42+ configDir, err := getConfigDir()
43+ if err != nil {
44+ log.Fatalf("error getting configuration directory: %v", err)
46 }45 }
46+ configFilePath := filepath.Join(configDir, "config.yml")
47+ return configDir, configFilePath
48+}
47 49
48- configFilePath := filepath.Join(configDir, configFileName)50+// SaveConfig saves the current configuration to a file.
49-51+func (config *Config) SaveConfig() error {
50- if _, err := os.Stat(configFilePath); os.IsNotExist(err) {52+ configDir, err := getConfigDir()
51- fmt.Printf("Config file not found, creating it at %s\n", configFilePath)53+ if err != nil {
52- defaultConfig := []byte("some: default\ndata: here\n")54+ return err
53- if err := os.WriteFile(configFilePath, defaultConfig, 0666); err != nil {
54- return nil, fmt.Errorf("error writing default configuration: %w", err)
55- }
56- } else if err != nil {
57- return nil, fmt.Errorf("error checking configuration file: %w", err)
58 }55 }
59-56+ configFilePath := filepath.Join(configDir, "config.yml")
60- // Read and unmarshal the config file57+ data, err := yaml.Marshal(config)
61- configData, err := os.ReadFile(configFilePath)
62 if err != nil {58 if err != nil {
63- return nil, fmt.Errorf("error reading configuration file: %w", err)59+ return fmt.Errorf("failed to marshal config: %v", err)
60+ }
61+ if err := os.WriteFile(configFilePath, data, 0644); err != nil {
62+ return fmt.Errorf("failed to write to config file: %v", err)
64 }63 }
64+ return nil
65+}
65 66
66- err = yaml.Unmarshal(configData, &config)67+// readAndUnmarshalConfig reads the config file and unmarshals it into the given config.
68+func readAndUnmarshalConfig(filePath string, config *Config) error {
69+ configData, err := os.ReadFile(filePath)
67 if err != nil {70 if err != nil {
68- return nil, fmt.Errorf("error unmarshalling configuration file: %w", err)71+ return fmt.Errorf("error reading configuration file: %w", err)
69 }72 }
73+ return yaml.Unmarshal(configData, config)
74+}
70 75
71- // New logic for backend URL and token76+// LoadClientConfig loads the client configuration.
72- needsSave := false77+func (config *Config) LoadClientConfig() (*Config, error) {
78+ configDir, configFilePath := configPath()
73 79
74- if config.Http.BackendURL == "" {80+ if err := os.MkdirAll(configDir, 0755); err != nil {
75- fmt.Println("Please enter the backend URL:")81+ return nil, fmt.Errorf("error creating configuration directory: %w", err)
76- var backendURL string
77- fmt.Scanln(&backendURL)
78- config.Http.BackendURL = backendURL
79- needsSave = true
80 }82 }
81 83
82- if config.General.GordonToken == "" {84+ // Check if the file exists
83- fmt.Println("Please enter the token:")85+ if _, err := os.Stat(configFilePath); os.IsNotExist(err) {
84- var token string86+ fmt.Printf("Config file not found, creating it at %s\n", configFilePath)
85- fmt.Scanln(&token)
86- config.General.GordonToken = token
87- needsSave = true
88- }
89 87
90- if needsSave {88+ // Prompt user for initial settings
91- err := config.SaveConfig() // Assuming SaveConfig is a method that saves the config to file89+ config.Http.BackendURL = readUserInput("Enter the backend URL:")
92- if err != nil {90+ config.General.GordonToken = readUserInput("Enter the Gordon token:")
93- return nil, fmt.Errorf("error saving configuration file: %w", err)91+
92+ // Save the new configuration
93+ if err := config.SaveConfig(); err != nil {
94+ return nil, fmt.Errorf("error saving new configuration: %w", err)
95+ }
96+ } else if err != nil {
97+ // Some other error occurred while checking the file
98+ return nil, fmt.Errorf("error checking configuration file: %w", err)
99+ } else {
100+ // File exists, read and unmarshal it
101+ if err := readAndUnmarshalConfig(configFilePath, config); err != nil {
102+ return nil, err
94 }103 }
95 }104 }
96 105
97 return config, nil106 return config, nil
98 }107 }
99 108
100-func (config *Config) SaveConfig() error {109+// readUserInput reads a string input from the user with a prompt.
101- usr, err := user.Current()110+func readUserInput(prompt string) string {
102- if err != nil {111+ fmt.Println(prompt)
103- return fmt.Errorf("error getting user's home directory: %w", err)112+ var input string
104- }113+ fmt.Scanln(&input)
105-114+ return input
106- var configDir string
107- if runtime.GOOS == "windows" {
108- configDir = filepath.Join(usr.HomeDir, "AppData", "Roaming", "Gordon")
109- } else {
110- configDir = filepath.Join(usr.HomeDir, ".config", "Gordon")
111- }
112-
113- configFilePath := filepath.Join(configDir, "config.yml")
114-
115- // Marshal the config struct into YAML
116- data, err := yaml.Marshal(config)
117- if err != nil {
118- return fmt.Errorf("failed to marshal config: %v", err)
119- }
120-
121- // Write the data to the config file
122- err = os.WriteFile(configFilePath, data, 0644)
123- if err != nil {
124- return fmt.Errorf("failed to write to config file: %v", err)
125- }
126-
127- return nil
128 }115 }
D internal/cli/handler/configfile.go +0 -16
@@ -1,16 +0,0 @@
1-package handler
2-
3-import "github.com/bnema/gordon/internal/app"
4-
5-// I need to handle the case of the backend URL not being present in the config file
6-func IsBackendURLPresent(a *app.App) bool {
7- // since config.yml is loaded from newclient.go, I can access the backend URL from the app struct
8-
9- if a.Config.Http.BackendURL == "" {
10- return false
11- }
12-
13- return true
14-}
15-
16-// I Need to handle the case the token is not present in the config file
@@ -1,16 +0,0 @@
1-package handler
2-
3-import "github.com/bnema/gordon/internal/app"
4-
5-// I need to handle the case of the backend URL not being present in the config file
6-func IsBackendURLPresent(a *app.App) bool {
7- // since config.yml is loaded from newclient.go, I can access the backend URL from the app struct
8-
9- if a.Config.Http.BackendURL == "" {
10- return false
11- }
12-
13- return true
14-}
15-
16-// I Need to handle the case the token is not present in the config file

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 7

Tags 106

↑↓ moveenter openesc close