| package config |
|
|
| import ( |
| "encoding/json" |
| "fmt" |
| "os" |
| "path/filepath" |
| "strings" |
| ) |
|
|
| func envWritebackEnabled() bool { |
| v := strings.ToLower(strings.TrimSpace(os.Getenv("DS2API_ENV_WRITEBACK"))) |
| return v == "1" || v == "true" || v == "yes" || v == "on" |
| } |
|
|
| func (s *Store) IsEnvWritebackEnabled() bool { |
| return envWritebackEnabled() |
| } |
|
|
| func (s *Store) HasEnvConfigSource() bool { |
| rawCfg := strings.TrimSpace(os.Getenv("DS2API_CONFIG_JSON")) |
| return rawCfg != "" |
| } |
|
|
| func (s *Store) ConfigPath() string { |
| return s.path |
| } |
|
|
| func writeConfigFile(path string, cfg Config) error { |
| persistCfg := cfg.Clone() |
| persistCfg.ClearAccountTokens() |
| b, err := json.MarshalIndent(persistCfg, "", " ") |
| if err != nil { |
| return err |
| } |
| return writeConfigBytes(path, b) |
| } |
|
|
| |
| |
| |
| func overwriteFile(path string, b []byte, perm os.FileMode) error { |
| if err := os.WriteFile(path, b, perm); err != nil { |
| if removeErr := os.Remove(path); removeErr == nil { |
| return os.WriteFile(path, b, perm) |
| } |
| return err |
| } |
| return nil |
| } |
|
|
| func writeConfigBytes(path string, b []byte) error { |
| dir := filepath.Dir(path) |
| if dir == "." || dir == "" { |
| return overwriteFile(path, b, 0o644) |
| } |
| if err := os.MkdirAll(dir, 0o755); err != nil { |
| return fmt.Errorf("mkdir config dir: %w", err) |
| } |
| |
| |
| tmp, err := os.CreateTemp(dir, ".ds2api-config-*") |
| if err != nil { |
| return fmt.Errorf("create temp config file: %w", err) |
| } |
| tmpName := tmp.Name() |
| wrote := false |
| defer func() { |
| if !wrote { |
| _ = tmp.Close() |
| _ = os.Remove(tmpName) |
| } |
| }() |
| if _, err := tmp.Write(b); err != nil { |
| return fmt.Errorf("write temp config: %w", err) |
| } |
| if err := tmp.Sync(); err != nil { |
| return fmt.Errorf("sync temp config: %w", err) |
| } |
| if err := tmp.Close(); err != nil { |
| return fmt.Errorf("close temp config: %w", err) |
| } |
| wrote = true |
| if err := os.Rename(tmpName, path); err != nil { |
| |
| |
| |
| if removeErr := os.Remove(path); removeErr == nil { |
| if renameErr := os.Rename(tmpName, path); renameErr == nil { |
| return nil |
| } |
| } |
| |
| _ = os.Remove(tmpName) |
| return overwriteFile(path, b, 0o644) |
| } |
| return nil |
| } |
|
|