Documentation
¶
Overview ¶
Package dotenv is a pure-Go (CGO=0) reimplementation of Ruby's `dotenv` gem (bkeepers/dotenv 3.2.0) `.env` file parser — the deterministic, interpreter-independent core of `Dotenv::Parser.call`. It parses the `.env` format into an insertion-ordered set of key/value pairs, byte-faithful to MRI, with variable interpolation and command-substitution parsing, but WITHOUT any Ruby runtime and WITHOUT touching the process environment.
The pieces that are genuinely a host concern — mutating `ENV` (what `Dotenv.load` does after parsing) and executing `$(command)` substitutions (which the gem does by shelling out) — are surfaced as explicit seams rather than performed here, keeping the package pure compute.
Index ¶
- func Load(src string, overwrite bool, env *Env) (*OrderedMap, []Command, error)
- func ParseWithCommands(src string, overwrite bool, lookupEnv func(string) (string, bool)) (*OrderedMap, []Command, error)
- func ParseWithRunner(src string, overwrite bool, lookupEnv func(string) (string, bool), ...) (*OrderedMap, []Command, error)
- type Command
- type Env
- type FormatError
- type OrderedMap
- func (m *OrderedMap) Each(fn func(key, val string))
- func (m *OrderedMap) Get(key string) (string, bool)
- func (m *OrderedMap) Has(key string) bool
- func (m *OrderedMap) Keys() []string
- func (m *OrderedMap) Len() int
- func (m *OrderedMap) Map() map[string]string
- func (m *OrderedMap) Set(key, val string)
- type Parser
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Load ¶
Load parses src and then sets each parsed pair into the environment via env.Set, mirroring `Dotenv.load` (parse + update ENV). It honours the gem's rule that a key already present in the environment is not overwritten unless overwrite is true (the parse already resolves such keys to their existing value). The mutation is entirely the host's Env.Set seam; the parsed OrderedMap is returned so the host can inspect exactly what was applied. Parsed `$(command)` substitutions are available via the returned Commands, since executing a shell is a host concern.
func ParseWithCommands ¶
func ParseWithCommands(src string, overwrite bool, lookupEnv func(string) (string, bool)) (*OrderedMap, []Command, error)
ParseWithCommands is Parse but also returns the parsed `$(command)` substitutions (the host-execution seam) in source order. With no runner every command substitutes "" (the pure result); to have chains resolve, supply a command runner via ParseWithRunner.
func ParseWithRunner ¶
func ParseWithRunner(src string, overwrite bool, lookupEnv func(string) (string, bool), runCommand func(script string) string) (*OrderedMap, []Command, error)
ParseWithRunner is Parse with the command-execution seam wired: runCommand is invoked inline during parsing for each `$(command)` (with the variable-expanded script), and its chomped return value is spliced into the value — so a command feeding a later variable or command resolves exactly as MRI's shelling-out does. A nil runCommand behaves like Parse (commands become ""). It also returns the recorded commands.
Types ¶
type Command ¶
type Command struct {
// Key is the .env key whose value contained the substitution.
Key string
// Script is the command text after inner `$VAR`/`${VAR}` expansion, exactly
// what the gem passes to the shell (its result is chomped and inlined).
Script string
}
Command is a parsed `$(...)` shell-command substitution the gem would execute. The parser records each one (with the fully variable-expanded Script the gem would pass to the shell) and substitutes the empty string in its place, leaving actual execution to the host.
type Env ¶
type Env struct {
Lookup func(string) (string, bool)
Set func(key, val string)
// RunCommand is the command-execution seam (the gem shells out for `$(cmd)`).
// When set, ParseString/Load run it inline for each command and splice the
// chomped output, so chains resolve as in MRI. When nil, commands yield "".
RunCommand func(script string) string
}
Env abstracts the ambient environment the gem reaches through `ENV`: a lookup (for existing-variable checks and `$VAR` interpolation) and a setter (what `Dotenv.load` performs after parsing). The whole struct is the HOST SEAM — a host wiring this to `os.LookupEnv` / `os.Setenv`, to a `go-embedded-ruby` ENV object, or to an in-memory map decides where mutation lands. Both fields are optional; a nil Lookup behaves like an empty environment and a nil Set makes Load a no-op mutation (it still returns the parsed pairs).
type FormatError ¶
type FormatError struct{ Line string }
FormatError is raised when a line declares an exported variable with no value and no prior assignment, mirroring Ruby's `Dotenv::FormatError`.
func (*FormatError) Error ¶
func (e *FormatError) Error() string
type OrderedMap ¶
type OrderedMap struct {
// contains filtered or unexported fields
}
OrderedMap is an insertion-ordered string->string map — the Go analogue of the Ruby `Hash` that `Dotenv::Parser.call` returns. Ruby hashes preserve insertion order, and dotenv relies on it (later keys may interpolate earlier ones), so the order is part of the observable, byte-faithful result.
func Parse ¶
Parse parses the `.env`-format src into an OrderedMap, byte-faithful to `Dotenv::Parser.call`.
- overwrite mirrors the gem's `overwrite:` keyword. When false, a key already present in the ambient environment (per lookupEnv) keeps that ambient value — except "DOTENV_LINEBREAK_MODE", which is always taken from the file.
- lookupEnv stands in for `ENV`: it resolves existing-variable checks and `$VAR` interpolation fallbacks. Pass nil for an empty environment.
It returns a FormatError if an `export KEY` line names a variable that was never assigned. Any `$(command)` substitutions are parsed, expanded, replaced by "" in the value, and returned via Commands for the host to execute.
func ParseString ¶
func ParseString(src string, overwrite bool, env *Env) (*OrderedMap, error)
ParseString parses src with the given Env, mirroring `Dotenv.parse` on a single source string (the gem's `Dotenv::Parser.call`). It does not mutate the environment. overwrite maps to the gem's `overwrite:` keyword. If the Env supplies a RunCommand, `$(cmd)` substitutions execute inline via that seam.
func (*OrderedMap) Each ¶
func (m *OrderedMap) Each(fn func(key, val string))
Each calls fn for every pair in insertion order.
func (*OrderedMap) Get ¶
func (m *OrderedMap) Get(key string) (string, bool)
Get returns the value for key and whether it is present.
func (*OrderedMap) Has ¶
func (m *OrderedMap) Has(key string) bool
Has reports whether key is present (Ruby Hash#member?).
func (*OrderedMap) Keys ¶
func (m *OrderedMap) Keys() []string
Keys returns the keys in insertion order (a copy; safe to mutate).
func (*OrderedMap) Map ¶
func (m *OrderedMap) Map() map[string]string
Map returns a plain (unordered) map copy of the pairs.
func (*OrderedMap) Set ¶
func (m *OrderedMap) Set(key, val string)
Set assigns key=val, appending the key on first insertion and preserving its original position on update (Ruby Hash#[]= semantics).
