wrds-download

TUI/CLI tool for browsing and downloading WRDS data
Log | Files | Refs | README

config.go (2256B)


      1 package config
      2 
      3 import (
      4 	"bufio"
      5 	"fmt"
      6 	"os"
      7 	"path/filepath"
      8 	"strings"
      9 )
     10 
     11 // CredentialsPath returns the path to the credentials file,
     12 // respecting $XDG_CONFIG_HOME with fallback to ~/.config/wrds-dl/credentials.
     13 func CredentialsPath() string {
     14 	base := os.Getenv("XDG_CONFIG_HOME")
     15 	if base == "" {
     16 		home, _ := os.UserHomeDir()
     17 		base = filepath.Join(home, ".config")
     18 	}
     19 	return filepath.Join(base, "wrds-dl", "credentials")
     20 }
     21 
     22 // LoadCredentials reads PGUSER, PGPASSWORD, and PGDATABASE from the credentials file.
     23 func LoadCredentials() (user, password, database string, err error) {
     24 	f, err := os.Open(CredentialsPath())
     25 	if err != nil {
     26 		return "", "", "", err
     27 	}
     28 	defer f.Close()
     29 
     30 	scanner := bufio.NewScanner(f)
     31 	for scanner.Scan() {
     32 		line := strings.TrimSpace(scanner.Text())
     33 		if line == "" || strings.HasPrefix(line, "#") {
     34 			continue
     35 		}
     36 		key, val, ok := strings.Cut(line, "=")
     37 		if !ok {
     38 			continue
     39 		}
     40 		switch strings.TrimSpace(key) {
     41 		case "PGUSER":
     42 			user = strings.TrimSpace(val)
     43 		case "PGPASSWORD":
     44 			password = strings.TrimSpace(val)
     45 		case "PGDATABASE":
     46 			database = strings.TrimSpace(val)
     47 		}
     48 	}
     49 	return user, password, database, scanner.Err()
     50 }
     51 
     52 // SaveCredentials writes PGUSER, PGPASSWORD, and PGDATABASE to the credentials file.
     53 // It creates the parent directories with 0700 and the file with 0600 permissions.
     54 func SaveCredentials(user, password, database string) error {
     55 	path := CredentialsPath()
     56 	if err := os.MkdirAll(filepath.Dir(path), 0700); err != nil {
     57 		return fmt.Errorf("create config dir: %w", err)
     58 	}
     59 	content := fmt.Sprintf("PGUSER=%s\nPGPASSWORD=%s\nPGDATABASE=%s\n", user, password, database)
     60 	return os.WriteFile(path, []byte(content), 0600)
     61 }
     62 
     63 // ApplyCredentials loads credentials from the config file and sets
     64 // environment variables for any values not already set.
     65 func ApplyCredentials() {
     66 	user, password, database, err := LoadCredentials()
     67 	if err != nil {
     68 		return // file doesn't exist or unreadable — silently skip
     69 	}
     70 	if os.Getenv("PGUSER") == "" && user != "" {
     71 		os.Setenv("PGUSER", user)
     72 	}
     73 	if os.Getenv("PGPASSWORD") == "" && password != "" {
     74 		os.Setenv("PGPASSWORD", password)
     75 	}
     76 	if os.Getenv("PGDATABASE") == "" && database != "" {
     77 		os.Setenv("PGDATABASE", database)
     78 	}
     79 }