Skip to content

Commit df8ea53

Browse files
Fix races by not relying on viper.WatchConfig
1 parent 4235fb1 commit df8ea53

File tree

1 file changed

+17
-12
lines changed

1 file changed

+17
-12
lines changed

internal/tiger/config/config.go

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package config
22

33
import (
4+
"errors"
45
"fmt"
6+
"io/fs"
57
"os"
68
"path/filepath"
79
"strconv"
@@ -63,26 +65,29 @@ func SetupViper(configDir string) error {
6365
viper.SetDefault("password_storage", DefaultPasswordStorage)
6466
viper.SetDefault("debug", DefaultDebug)
6567

66-
// Try to read config file if it exists
67-
if _, err := os.Stat(configFile); err == nil {
68-
// File exists, try to read it
69-
if err := viper.ReadInConfig(); err != nil {
70-
return fmt.Errorf("error reading config file: %w", err)
71-
}
68+
return readInConfig()
69+
}
7270

73-
// Configure viper to watch for file changes and update its in-memory
74-
// representation of the config. Note that this won't automatically
75-
// update [Config] structs already returned from [Load].
76-
viper.WatchConfig()
77-
}
71+
func readInConfig() error {
72+
// Try to read config file if it exists
7873
// If file doesn't exist, that's okay - we'll use defaults and env vars
79-
74+
if err := viper.ReadInConfig(); err != nil &&
75+
!errors.As(err, &viper.ConfigFileNotFoundError{}) &&
76+
!errors.Is(err, fs.ErrNotExist) {
77+
return err
78+
}
8079
return nil
8180
}
8281

8382
// Load creates a new Config instance from the current viper state
8483
// This function should be called after SetupViper has been called to initialize viper
8584
func Load() (*Config, error) {
85+
// Try to read config file into viper to ensure we're unmarshaling the most
86+
// up-to-date values into the config struct.
87+
if err := readInConfig(); err != nil {
88+
return nil, err
89+
}
90+
8691
cfg := &Config{
8792
ConfigDir: GetConfigDir(),
8893
}

0 commit comments

Comments
 (0)