ollie/env/env.go

87 lines
2.2 KiB
Go

// Package env manages the daemon-global environment for ollie.
// It loads $XDG_CONFIG_HOME/ollie/env and provides defaults,
// formatted for export to frontends via ollie/env.
package env
import (
"bufio"
"fmt"
"os"
"path/filepath"
"strings"
"ollie/paths"
)
// managed is the ordered list of env vars that ollie exposes to frontends.
var managed = []string{}
// EnsureDefaults loads $XDG_CONFIG_HOME/ollie/env and sets default values for any
// OLLIE_* vars not already present in the process environment.
func EnsureDefaults() {
LoadFile(filepath.Join(paths.CfgDir(), "env"))
}
// Set sets a variable in the process environment.
func Set(k, v string) { os.Setenv(k, v) } //nolint:errcheck
// LoadFile reads KEY=VALUE pairs from path and sets any key not already
// present in the environment. Lines beginning with # and blank lines are
// ignored. Missing file is silently ignored.
func LoadFile(path string) {
f, err := os.Open(path)
if err != nil {
return
}
defer f.Close()
sc := bufio.NewScanner(f)
for sc.Scan() {
line := strings.TrimSpace(sc.Text())
if line == "" || strings.HasPrefix(line, "#") {
continue
}
k, v, ok := strings.Cut(line, "=")
if !ok {
continue
}
k = strings.TrimSpace(k)
if i := strings.Index(v, " #"); i >= 0 {
v = v[:i]
}
v = strings.TrimSpace(v)
if len(v) >= 2 && (v[0] == '"' && v[len(v)-1] == '"' || v[0] == '\'' && v[len(v)-1] == '\'') {
v = v[1 : len(v)-1]
}
if k != "" && os.Getenv(k) == "" {
os.Setenv(k, paths.ExpandHome(os.ExpandEnv(v))) //nolint:errcheck
}
}
}
// Get returns a variable from the process environment.
func Get(k string) string { return os.Getenv(k) }
// All returns the full process environment as a map.
func All() map[string]string {
pairs := os.Environ()
m := make(map[string]string, len(pairs))
for _, pair := range pairs {
k, v, _ := strings.Cut(pair, "=")
m[k] = v
}
return m
}
// Format returns the managed environment variables as NAME=VALUE lines,
// suitable for serving as ollie/env.
func Format() []byte {
var sb strings.Builder
for _, k := range managed {
if v := os.Getenv(k); v != "" {
fmt.Fprintf(&sb, "%s=%s\n", k, v)
}
}
return []byte(sb.String())
}