git.delta.rocks / jrsonnet / refs/commits / fe52b32db444

difftreelog

source

crates/jrsonnet-cli/src/stdlib.rs3.1 KiBsourcehistory
1use std::{fs::read_to_string, str::FromStr};23use clap::Parser;4use jrsonnet_evaluator::{error::Result, tb, trace::PathResolver, State};56use crate::ConfigureState;78#[derive(Clone)]9pub struct ExtStr {10	pub name: String,11	pub value: String,12}1314impl FromStr for ExtStr {15	type Err = &'static str;16	fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {17		let out: Vec<_> = s.split('=').collect();18		match out.len() {19			1 => Ok(ExtStr {20				name: out[0].to_owned(),21				value: std::env::var(out[0]).or(Err("missing env var"))?,22			}),23			2 => Ok(ExtStr {24				name: out[0].to_owned(),25				value: out[1].to_owned(),26			}),2728			_ => Err("bad ext-str syntax"),29		}30	}31}3233#[derive(Clone)]34pub struct ExtFile {35	pub name: String,36	pub value: String,37}3839impl FromStr for ExtFile {40	type Err = String;4142	fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {43		let out: Vec<&str> = s.split('=').collect();44		if out.len() != 2 {45			return Err("bad ext-file syntax".to_owned());46		}47		let file = read_to_string(out[1]);48		match file {49			Ok(content) => Ok(Self {50				name: out[0].into(),51				value: content,52			}),53			Err(e) => Err(format!("{}", e)),54		}55	}56}5758#[derive(Parser)]59#[clap(next_help_heading = "STANDARD LIBRARY")]60pub struct StdOpts {61	/// Disable standard library.62	/// By default standard library will be available via global `std` variable.63	/// Note that standard library will still be loaded64	/// if chosen manifestification method is not `none`.65	#[clap(long)]66	no_stdlib: bool,67	/// Add string external variable.68	/// External variables are globally available so it is preferred69	/// to use top level arguments whenever it's possible.70	/// If [=data] is not set then it will be read from `name` env variable.71	/// Can be accessed from code via `std.extVar("name")`.72	#[clap(long, short = 'V', name = "name[=var data]", number_of_values = 1)]73	ext_str: Vec<ExtStr>,74	/// Read string external variable from file.75	/// See also `--ext-str`76	#[clap(long, name = "name=var path", number_of_values = 1)]77	ext_str_file: Vec<ExtFile>,78	/// Add external variable from code.79	/// See also `--ext-str`80	#[clap(long, name = "name[=var source]", number_of_values = 1)]81	ext_code: Vec<ExtStr>,82	/// Read string external variable from file.83	/// See also `--ext-str`84	#[clap(long, name = "name=var code path", number_of_values = 1)]85	ext_code_file: Vec<ExtFile>,86}87impl ConfigureState for StdOpts {88	type Guards = ();89	fn configure(&self, s: &State) -> Result<()> {90		if self.no_stdlib {91			return Ok(());92		}93		let ctx =94			jrsonnet_stdlib::ContextInitializer::new(s.clone(), PathResolver::new_cwd_fallback());95		for ext in self.ext_str.iter() {96			ctx.add_ext_str((&ext.name as &str).into(), (&ext.value as &str).into());97		}98		for ext in self.ext_str_file.iter() {99			ctx.add_ext_str((&ext.name as &str).into(), (&ext.value as &str).into());100		}101		for ext in self.ext_code.iter() {102			ctx.add_ext_code(&ext.name as &str, &ext.value as &str)?;103		}104		for ext in self.ext_code_file.iter() {105			ctx.add_ext_code(&ext.name as &str, &ext.value as &str)?;106		}107		s.settings_mut().context_initializer = tb!(ctx);108		Ok(())109	}110}