Pudu programming language
Menu
Package

@chrismichaelps / pudu-lang-environment

Environment files for Pudu: load .env variables safely with layered files, discovery, expansion, typed reads, and secrets kept out of every message

0.1.0Apache-2.01

InstallClose

Layered.pudu

Pudu45 lines2.1 KB

GitHub ↗
1/** @Examples.Layered.Program — environment cascade and overwrite rules */2module Layered34import Std.Fs as Fs5import Std.Io as Io6import Std.Map as Map7import Std.Path as Path8import PuduLangEnvironment.Loader as Loader9import PuduLangEnvironment.Options as Options10import PuduLangEnvironment.Variables as Variables1112/// Writes four layers and loads them for the `test` environment, over a process that already sets13/// `LOG_LEVEL`, once overwriting and once not.14fn run(project: Str) -> Result[Int, Fs.FsError] {15  let _shared = Io.write(Path.join(project, ".env"), "HOST=localhost\nPORT=8080\nLOG_LEVEL=info\n")16  let _local = Io.write(Path.join(project, ".env.local"), "PORT=8081\n")17  let _named = Io.write(Path.join(project, ".env.test"), "HOST=test.internal\nURL=http://$HOST:$PORT\n")18  let _mine = Io.write(Path.join(project, ".env.test.local"), "PORT=9000\n")19  let process = Map.fromPairs(&[("LOG_LEVEL", "debug")])20  let options = Options.defaults().inDirectory(project).withEnvironment("test").withExpansion()21  let layered = Loader.loadOver(&options, &process)22  let deferring = Loader.loadOver(&options.withoutOverwrite(), &process)23  match (layered, deferring) {24    case (Ok(variables), Ok(kept)) => {25      for source in variables.sources { let _listed = Io.writeLine("read " + Path.nameOf(source)) }26      let url = Variables.find(&variables, "URL")27      let port = Variables.find(&variables, "PORT")28      let level = Variables.find(&variables, "LOG_LEVEL")29      let keptLevel = Variables.find(&kept, "LOG_LEVEL")30      let _shown = Io.writeLine("URL=" + show(url) + " PORT=" + show(port) + " LOG_LEVEL=" + show(level) + " kept LOG_LEVEL=" + show(keptLevel))31      Ok(if url == Some("http://test.internal:8081") && port == Some("9000") && level == Some("info") && keptLevel == Some("debug") { 0 } else { 1 })32    }33    case _ => Ok(1)34  }35}3637/// Runs the example and answers 0 when later layers win, a reference reads the value known where it38/// is written, and a load without overwriting leaves the process its own value.39fn main() -> Int {40  match Fs.withTemporaryDirectory("layered-", run) {41    case Ok(status) => status42    case Err(_) => 143  }44}45