Generating typed definitions from environment variables

An example of how to use embeds/env to generate constants of other types, like integers, boolean flags, or custom enums. Note that for simple cases like booleans or ints, command-line arguments can be used.

You can check out the full example project here.

Running

Run the project, providing some environment variables:

BUILD_ENV=production \
BUILD_KNOWN_BUGS=9001.000000004 \
BUILD_ENABLE_AWESOMENESS=YES \
BUILD_REVISION=16 \
gleam run

Full Example Source

NOTE: In a real project, you would add a seperate build path dev dependency. This avoids issues when regenerating files that your project already depends on.

import embeds/env
import embeds/generate
import gleam/io
import gleam/option

pub fn main() {
  let result =
    env.generate(env.Options(
      module: "build_env",
      prefix: "BUILD_",
      regex: option.None,
      parse: env.typed_parse([
        #("BUILD_ENV", environment),
        #("BUILD_ENABLE_AWESOMENESS", env.bool),
        // needs to be float because otherwise the login email doesn't work
        #("BUILD_KNOWN_BUGS", env.float),
        #("BUILD_REVISION", env.string),
      ]),
      // we need to include the environment type we want to use somehow -
      // right here we just put it onto the top of the generated file.
      // an alternative might be to put this type into a `shared` project.
      header: "
        pub type Environment {
          Development
          Testing
          Production
        }
      ",
    ))

  case result {
    Ok(Nil) -> Nil
    Error(errs) -> io.println_error(generate.describe_errors(errs))
  }
}

// a custom environment parser
fn environment(value: String) -> generate.Code {
  // requires us to set the header above to include the type!
  case value {
    "development" -> generate.Constant("Development")
    "production" -> generate.Constant("Production")
    "testing" -> generate.Constant("Testing")
    _ -> generate.GenerateError("Invalid environment: " <> value)
  }
}
Search Document