Envious (envious v1.4.1)

Copy Markdown View Source

Parser for .env files.

Envious provides a simple, functional parser for .env files. It does not mutate the environment or have any side effects.

Example

iex> Envious.parse("KEY=value")
{:ok, %{"KEY" => "value"}}

iex> Envious.parse("""
...> export FOO=bar
...> # This is a comment
...> BAZ=qux
...> """)
{:ok, %{"FOO" => "bar", "BAZ" => "qux"}}

Variable Interpolation

Enable shell-style variable interpolation with the :interpolate option:

iex> Envious.parse("BASE=/app\nPATH=$BASE/bin", interpolate: true)
{:ok, %{"BASE" => "/app", "PATH" => "/app/bin"}}

See parse/2 for all available options.

Using Envious

You can use Envious to import both the parser functions and the environment variable helpers:

use Envious

# Now you have access to:
parse!/1, parse!/2        # from Envious
optional/1, optional/2    # from Envious.Env
required!/1               # from Envious.Env
integer!/1, float!/1, etc.  # from Envious.Env

Summary

Functions

Parse a .env file string into a map.

Parse a .env file string into a map, raising on error.

Types

interpolation_opt()

@type interpolation_opt() :: {:interpolate, boolean()}

parse_opt()

@type parse_opt() :: interpolation_opt() | undefined_vars_opt()

undefined_vars_opt()

@type undefined_vars_opt() :: {:undefined_vars, :keep | :empty | :error}

Functions

parse(str, opts \\ [])

@spec parse(String.t(), [parse_opt()]) :: {:ok, map()} | {:error, String.t()}

Parse a .env file string into a map.

Options

  • :interpolate - Enable variable interpolation with $VAR or ${VAR} syntax. Defaults to false.
  • :undefined_vars - How to handle undefined variables when interpolation is enabled:
    • :keep - Keep the literal $VAR text (default, safest)
    • :empty - Replace with empty string (shell-compatible)
    • :error - Return an error for undefined variables

Examples

iex> Envious.parse("PORT=3000")
{:ok, %{"PORT" => "3000"}}

iex> Envious.parse("export API_KEY=secret\nDATABASE_URL=postgres://localhost")
{:ok, %{"API_KEY" => "secret", "DATABASE_URL" => "postgres://localhost"}}

# Interpolation disabled by default
iex> Envious.parse("A=foo\nB=$A")
{:ok, %{"A" => "foo", "B" => "$A"}}

# Enable interpolation
iex> Envious.parse("A=foo\nB=$A", interpolate: true)
{:ok, %{"A" => "foo", "B" => "foo"}}

# Undefined variables with :keep (default)
iex> Envious.parse("B=$UNDEFINED", interpolate: true)
{:ok, %{"B" => "$UNDEFINED"}}

# Undefined variables with :empty
iex> Envious.parse("B=$UNDEFINED", interpolate: true, undefined_vars: :empty)
{:ok, %{"B" => ""}}

iex> Envious.parse("KEY=value\n!INVALID")
{:error, ~s(Parse error at line 2, column 1: could not parse remaining input starting with: "!INVALID")}

parse!(str, opts \\ [])

@spec parse!(String.t(), [parse_opt()]) :: map()

Parse a .env file string into a map, raising on error.

Same as parse/2 but raises a RuntimeError if the input cannot be parsed or if an undefined variable error occurs.

Examples

iex> Envious.parse!("PORT=3000")
%{"PORT" => "3000"}

iex> Envious.parse!("export API_KEY=secret\nDATABASE_URL=postgres://localhost")
%{"API_KEY" => "secret", "DATABASE_URL" => "postgres://localhost"}

iex> Envious.parse!("A=foo\nB=$A", interpolate: true)
%{"A" => "foo", "B" => "foo"}

iex> Envious.parse!("INVALID")
** (RuntimeError) Parse error at line 1, column 1: could not parse remaining input starting with: "INVALID"