feat: M3.7.7 signature extraction CLI + integration tests (unit tests pass, integration tests pending mem-cli fix)
This commit is contained in:
@@ -136,6 +136,16 @@ enum Commands {
|
||||
#[arg(long)]
|
||||
database_url: Option<String>,
|
||||
},
|
||||
|
||||
/// Extract and explain failure signature
|
||||
Sig {
|
||||
/// Tool name (e.g. npm, cargo, kubectl)
|
||||
#[arg(long, value_name = "TOOL")]
|
||||
tool: String,
|
||||
/// Read failure log from file (stdin if not specified)
|
||||
#[arg(long, value_name = "FILE")]
|
||||
file: Option<PathBuf>,
|
||||
},
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
@@ -191,6 +201,9 @@ async fn main() -> anyhow::Result<()> {
|
||||
};
|
||||
cmd_verify(&project, db, log, log_dir, output_format, &database_url).await?
|
||||
}
|
||||
Commands::Sig { tool, file } => {
|
||||
cmd_sig(&tool, file.as_ref())?
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@@ -356,3 +369,36 @@ async fn cmd_verify(
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn cmd_sig(tool: &str, file: Option<&PathBuf>) -> anyhow::Result<()> {
|
||||
use mem_core::lesson;
|
||||
use std::io::Read;
|
||||
|
||||
// Read failure log from file or stdin
|
||||
let mut output = String::new();
|
||||
if let Some(file_path) = file {
|
||||
output = fs::read_to_string(file_path)?;
|
||||
} else {
|
||||
std::io::stdin().read_to_string(&mut output)?;
|
||||
}
|
||||
|
||||
// Extract signature
|
||||
match lesson::extract(tool, &output) {
|
||||
Some(sig) => {
|
||||
println!("=== Failure Signature ===");
|
||||
println!("Tool: {}", sig.tool);
|
||||
println!("Rule: {}", sig.rule);
|
||||
println!("Hash (SHA256): {}", sig.sig_sha);
|
||||
println!("\n=== Raw Error ===");
|
||||
println!("{}", sig.raw);
|
||||
println!("\n=== Normalised Form ===");
|
||||
println!("{}", sig.normalised);
|
||||
}
|
||||
None => {
|
||||
eprintln!("Failed to extract signature for tool: {}", tool);
|
||||
std::process::exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user