1use std::collections::BTreeMap;
2
3use hcl::eval::{Context, FuncArgs, FuncDef};
4use hcl::Value;
5
6use once_cell::sync::OnceCell;
8use parking_lot::Mutex;
9
10static GLOBAL_CONTEXT: OnceCell<Mutex<Context>> = OnceCell::new();
12
13pub fn hcl_context() -> Context<'static> {
20 let env_func = |args: FuncArgs| {
21 let env = std::env::vars().collect::<BTreeMap<String, String>>();
22 let key = args.first().and_then(|v| v.as_str()).ok_or("Invalid argument")?;
23 let value = env.get(key).ok_or("Key not found in environment variables")?;
24 Ok(Value::String(value.to_string()))
25 };
26 let c = GLOBAL_CONTEXT.get_or_init(|| {
27 dotenv::dotenv().ok();
28 let mut ctx = Context::new();
29 let env_func = FuncDef::builder().param(hcl::eval::ParamType::String).build(env_func);
30 ctx.declare_func("env", env_func);
31
32 let env = std::env::vars().collect::<BTreeMap<String, String>>();
33 let mut map = hcl::Map::new();
34
35 map.extend(env.into_iter().map(|(k, v)| (k, Value::String(v))));
36
37 ctx.declare_var("env", Value::Object(map));
38
39 Mutex::new(ctx)
40 });
41 c.lock().clone()
42}