143 lines
4.6 KiB
Rust
143 lines
4.6 KiB
Rust
use std::collections::{BTreeMap, BTreeSet};
|
|
|
|
pub struct OutputInfo {
|
|
pub path: String,
|
|
pub hash_algo: String,
|
|
pub hash: String,
|
|
}
|
|
|
|
pub struct DerivationData {
|
|
pub name: String,
|
|
pub outputs: BTreeMap<String, OutputInfo>,
|
|
pub input_drvs: BTreeMap<String, BTreeSet<String>>,
|
|
pub input_srcs: BTreeSet<String>,
|
|
pub platform: String,
|
|
pub builder: String,
|
|
pub args: Vec<String>,
|
|
pub env: BTreeMap<String, String>,
|
|
}
|
|
|
|
fn escape_string(s: &str) -> String {
|
|
let mut result = String::with_capacity(s.len() + 2);
|
|
result.push('"');
|
|
for c in s.chars() {
|
|
match c {
|
|
'"' => result.push_str("\\\""),
|
|
'\\' => result.push_str("\\\\"),
|
|
'\n' => result.push_str("\\n"),
|
|
'\r' => result.push_str("\\r"),
|
|
'\t' => result.push_str("\\t"),
|
|
_ => result.push(c),
|
|
}
|
|
}
|
|
result.push('"');
|
|
result
|
|
}
|
|
|
|
fn quote_string(s: &str) -> String {
|
|
format!("\"{}\"", s)
|
|
}
|
|
|
|
impl DerivationData {
|
|
pub fn generate_aterm(&self) -> String {
|
|
let mut output_entries = Vec::new();
|
|
for (name, info) in &self.outputs {
|
|
output_entries.push(format!(
|
|
"({},{},{},{})",
|
|
quote_string(name),
|
|
quote_string(&info.path),
|
|
quote_string(&info.hash_algo),
|
|
quote_string(&info.hash),
|
|
));
|
|
}
|
|
let outputs = output_entries.join(",");
|
|
|
|
let mut input_drv_entries = Vec::new();
|
|
for (drv_path, output_names) in &self.input_drvs {
|
|
let sorted_outs: Vec<String> = output_names.iter().map(|s| quote_string(s)).collect();
|
|
let out_list = format!("[{}]", sorted_outs.join(","));
|
|
input_drv_entries.push(format!("({},{})", quote_string(drv_path), out_list));
|
|
}
|
|
let input_drvs = input_drv_entries.join(",");
|
|
|
|
let input_srcs: Vec<String> = self.input_srcs.iter().map(|s| quote_string(s)).collect();
|
|
let input_srcs = input_srcs.join(",");
|
|
|
|
let args: Vec<String> = self.args.iter().map(|s| escape_string(s)).collect();
|
|
let args = args.join(",");
|
|
|
|
let mut env_entries: Vec<String> = Vec::new();
|
|
for (k, v) in &self.env {
|
|
env_entries.push(format!("({},{})", escape_string(k), escape_string(v)));
|
|
}
|
|
|
|
format!(
|
|
"Derive([{}],[{}],[{}],{},{},[{}],[{}])",
|
|
outputs,
|
|
input_drvs,
|
|
input_srcs,
|
|
quote_string(&self.platform),
|
|
escape_string(&self.builder),
|
|
args,
|
|
env_entries.join(","),
|
|
)
|
|
}
|
|
|
|
pub fn generate_aterm_modulo(&self, input_drv_hashes: &BTreeMap<String, String>) -> String {
|
|
let mut output_entries = Vec::new();
|
|
for (name, info) in &self.outputs {
|
|
output_entries.push(format!(
|
|
"({},{},{},{})",
|
|
quote_string(name),
|
|
quote_string(&info.path),
|
|
quote_string(&info.hash_algo),
|
|
quote_string(&info.hash),
|
|
));
|
|
}
|
|
let outputs = output_entries.join(",");
|
|
|
|
let mut input_drv_entries = Vec::new();
|
|
for (drv_hash, outputs_csv) in input_drv_hashes {
|
|
let mut sorted_outs: Vec<&str> = outputs_csv.split(',').collect();
|
|
sorted_outs.sort();
|
|
let out_list: Vec<String> = sorted_outs.iter().map(|s| quote_string(s)).collect();
|
|
let out_list = format!("[{}]", out_list.join(","));
|
|
input_drv_entries.push(format!("({},{})", quote_string(drv_hash), out_list));
|
|
}
|
|
let input_drvs = input_drv_entries.join(",");
|
|
|
|
let input_srcs: Vec<String> = self.input_srcs.iter().map(|s| quote_string(s)).collect();
|
|
let input_srcs = input_srcs.join(",");
|
|
|
|
let args: Vec<String> = self.args.iter().map(|s| escape_string(s)).collect();
|
|
let args = args.join(",");
|
|
|
|
let mut env_entries: Vec<String> = Vec::new();
|
|
for (k, v) in &self.env {
|
|
env_entries.push(format!("({},{})", escape_string(k), escape_string(v)));
|
|
}
|
|
|
|
format!(
|
|
"Derive([{}],[{}],[{}],{},{},[{}],[{}])",
|
|
outputs,
|
|
input_drvs,
|
|
input_srcs,
|
|
quote_string(&self.platform),
|
|
escape_string(&self.builder),
|
|
args,
|
|
env_entries.join(","),
|
|
)
|
|
}
|
|
|
|
pub fn collect_references(&self) -> Vec<String> {
|
|
let mut refs = BTreeSet::new();
|
|
for src in &self.input_srcs {
|
|
refs.insert(src.clone());
|
|
}
|
|
for drv_path in self.input_drvs.keys() {
|
|
refs.insert(drv_path.clone());
|
|
}
|
|
refs.into_iter().collect()
|
|
}
|
|
}
|