use std::path::Path;
pub(crate) fn validate(path: &str) -> anyhow::Result<()> {
match plecto_control::validate_manifest_path(Path::new(path)) {
Ok(outcome) => {
println!(
"manifest OK: {path} (config version {})",
outcome.config_version
);
for warning in &outcome.warnings {
println!("warning {warning}");
}
Ok(())
}
Err(e) => anyhow::bail!("manifest INVALID: {path}: {e}"),
}
}
pub(crate) fn conformance(rest: Vec<String>) -> anyhow::Result<()> {
let json = rest.iter().any(|a| a == "--json");
let path = rest
.iter()
.find(|a| a.as_str() != "--json")
.ok_or_else(|| anyhow::anyhow!("usage: plecto conformance <component.wasm> [--json]"))?
.clone();
let bytes = std::fs::read(&path).map_err(|e| anyhow::anyhow!("read {path}: {e}"))?;
let report = plecto_control::run_conformance(&bytes);
if json {
let checks: Vec<serde_json::Value> = report
.checks
.iter()
.map(|c| serde_json::json!({"name": c.name, "passed": c.passed, "detail": c.detail}))
.collect();
println!(
"{}",
serde_json::json!({"conformant": report.is_conformant(), "checks": checks})
);
} else {
for check in &report.checks {
let mark = if check.passed { "PASS" } else { "FAIL" };
println!("[{mark}] {} — {}", check.name, check.detail);
}
}
if report.is_conformant() {
return Ok(());
}
anyhow::bail!("{path} is not conformant with plecto:filter");
}
pub(crate) fn new_filter(rest: Vec<String>) -> anyhow::Result<()> {
let usage = || anyhow::anyhow!("usage: plecto new-filter --lang <lang> <name>");
let lang_idx = rest.iter().position(|a| a == "--lang");
let lang = lang_idx.and_then(|i| rest.get(i + 1)).ok_or_else(usage)?;
let lang_value_idx = lang_idx.map(|i| i + 1);
let name = rest
.iter()
.enumerate()
.find(|(i, a)| a.as_str() != "--lang" && Some(*i) != lang_value_idx)
.map(|(_, a)| a.as_str())
.ok_or_else(usage)?;
let project_root = std::env::current_dir()
.map_err(|e| anyhow::anyhow!("resolve the current directory: {e}"))?;
crate::new_filter::run(lang, name, &project_root)
}