1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
use std::{fs::read_to_string, str::FromStr};
use clap::Parser;
use jrsonnet_evaluator::{error::Result, tb, trace::PathResolver, State};
use crate::ConfigureState;
#[derive(Clone)]
pub struct ExtStr {
pub name: String,
pub value: String,
}
impl FromStr for ExtStr {
type Err = &'static str;
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
let out: Vec<_> = s.split('=').collect();
match out.len() {
1 => Ok(ExtStr {
name: out[0].to_owned(),
value: std::env::var(out[0]).or(Err("missing env var"))?,
}),
2 => Ok(ExtStr {
name: out[0].to_owned(),
value: out[1].to_owned(),
}),
_ => Err("bad ext-str syntax"),
}
}
}
#[derive(Clone)]
pub struct ExtFile {
pub name: String,
pub value: String,
}
impl FromStr for ExtFile {
type Err = String;
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
let out: Vec<&str> = s.split('=').collect();
if out.len() != 2 {
return Err("bad ext-file syntax".to_owned());
}
let file = read_to_string(out[1]);
match file {
Ok(content) => Ok(Self {
name: out[0].into(),
value: content,
}),
Err(e) => Err(format!("{}", e)),
}
}
}
#[derive(Parser)]
#[clap(next_help_heading = "STANDARD LIBRARY")]
pub struct StdOpts {
#[clap(long)]
no_stdlib: bool,
#[clap(long, short = 'V', name = "name[=var data]", number_of_values = 1)]
ext_str: Vec<ExtStr>,
#[clap(long, name = "name=var path", number_of_values = 1)]
ext_str_file: Vec<ExtFile>,
#[clap(long, name = "name[=var source]", number_of_values = 1)]
ext_code: Vec<ExtStr>,
#[clap(long, name = "name=var code path", number_of_values = 1)]
ext_code_file: Vec<ExtFile>,
}
impl ConfigureState for StdOpts {
type Guards = ();
fn configure(&self, s: &State) -> Result<()> {
if self.no_stdlib {
return Ok(());
}
let ctx =
jrsonnet_stdlib::ContextInitializer::new(s.clone(), PathResolver::new_cwd_fallback());
for ext in self.ext_str.iter() {
ctx.add_ext_str((&ext.name as &str).into(), (&ext.value as &str).into());
}
for ext in self.ext_str_file.iter() {
ctx.add_ext_str((&ext.name as &str).into(), (&ext.value as &str).into());
}
for ext in self.ext_code.iter() {
ctx.add_ext_code(&ext.name as &str, &ext.value as &str)?;
}
for ext in self.ext_code_file.iter() {
ctx.add_ext_code(&ext.name as &str, &ext.value as &str)?;
}
s.settings_mut().context_initializer = tb!(ctx);
Ok(())
}
}