feat: implement program plugin metadata saving

Co-authored-by: aider (openai/andrew/openrouter/qwen/qwen3-coder) <aider@aider.chat>
This commit is contained in:
Andrew Phillips
2025-08-18 08:40:36 -03:00
parent c89fe9bef3
commit 8de8368df7

View File

@@ -3,6 +3,7 @@ use log::*;
use std::io::Write; use std::io::Write;
use std::process::{Command, Stdio, Child}; use std::process::{Command, Stdio, Child};
use which::which; use which::which;
use rusqlite::Connection;
use crate::meta_plugin::MetaPlugin; use crate::meta_plugin::MetaPlugin;
@@ -14,6 +15,9 @@ pub struct MetaPluginProgram {
pub split_whitespace: bool, pub split_whitespace: bool,
process: Option<Child>, process: Option<Child>,
writer: Option<Box<dyn Write>>, writer: Option<Box<dyn Write>>,
item_id: Option<i64>,
conn: Option<*mut Connection>,
result: Option<String>,
} }
impl std::fmt::Debug for MetaPluginProgram { impl std::fmt::Debug for MetaPluginProgram {
@@ -43,6 +47,9 @@ impl MetaPluginProgram {
split_whitespace, split_whitespace,
process: None, process: None,
writer: None, writer: None,
item_id: None,
conn: None,
result: None,
} }
} }
} }
@@ -56,8 +63,12 @@ impl MetaPlugin for MetaPluginProgram {
false false
} }
fn initialize(&mut self, _conn: &rusqlite::Connection, _item_id: i64) -> Result<()> { fn initialize(&mut self, conn: &rusqlite::Connection, item_id: i64) -> Result<()> {
debug!("META: Initializing program plugin: {:?}", self); debug!("META: Initializing program plugin: {:?}", self);
// Store database connection and item ID for later use
self.item_id = Some(item_id);
self.conn = Some(conn as *const _ as *mut Connection);
let program = self.program.clone(); let program = self.program.clone();
let args = self.args.clone(); let args = self.args.clone();
@@ -85,6 +96,46 @@ impl MetaPlugin for MetaPluginProgram {
fn finalize(&mut self) -> Result<()> { fn finalize(&mut self) -> Result<()> {
debug!("META: Finalizing program plugin"); debug!("META: Finalizing program plugin");
if let Some(mut process) = self.process.take() {
// Close stdin to signal end of input
drop(self.writer.take());
// Wait for the process to complete
let output = process.wait_with_output()?;
if output.status.success() {
// Process the output
let output_str = String::from_utf8_lossy(&output.stdout);
let result = if self.split_whitespace {
output_str.split_whitespace().next().unwrap_or("").to_string()
} else {
output_str.trim().to_string()
};
if !result.is_empty() {
debug!("META: Program output: {}", result);
self.result = Some(result);
// Save the result to database if we have connection and item_id
if let (Some(conn), Some(item_id)) = (self.conn, self.item_id) {
// Convert raw pointer back to reference (unsafe)
let conn_ref = unsafe { &*conn };
let meta = crate::db::Meta {
id: item_id,
name: self.meta_name.clone(),
value: self.result.clone().unwrap(),
};
let _ = crate::db::store_meta(conn_ref, meta);
}
}
} else {
debug!("META: Program failed with status: {:?}", output.status);
let stderr = String::from_utf8_lossy(&output.stderr);
if !stderr.is_empty() {
debug!("META: Program stderr: {}", stderr);
}
}
}
Ok(()) Ok(())
} }