use super::CodeQLPack;
use crate::{CodeQL, GHASError, codeql::database::queries::CodeQLQueries};
#[derive(Debug, Clone)]
pub struct CodeQLPackHandler<'db, 'ql> {
pack: &'db CodeQLPack,
codeql: &'ql CodeQL,
suite: Option<String>,
}
impl<'db, 'ql> CodeQLPackHandler<'db, 'ql> {
pub fn new(pack: &'db CodeQLPack, codeql: &'ql CodeQL) -> Self {
Self {
pack,
codeql,
suite: None,
}
}
pub fn suite(mut self, suite: impl Into<String>) -> Self {
self.suite = match CodeQLQueries::parse(suite.into()) {
Ok(q) => q.suite(),
Err(e) => Some(e.to_string()),
};
self
}
fn get_suite(&self) -> Option<String> {
if let Some(suite) = &self.suite {
return Some(suite.clone());
} else if let Some(suite) = &self.codeql.suite {
return Some(suite.clone());
}
None
}
pub async fn resolve(&mut self) -> Result<Vec<String>, GHASError> {
let mut args = vec!["resolve", "queries", "--format=json"];
let name = if let Some(suite) = &self.get_suite() {
format!("{}:{}", self.pack.full_name(), suite)
} else {
self.pack.full_name()
};
args.push(name.as_str());
log::debug!("Resolving queries for pack: {}", name);
println!("Resolving queries for pack: {}", name);
let output = self.codeql.run(args).await?;
let json: Vec<String> = serde_json::from_str(&output)?;
let mut pack_path = self.pack.path().display().to_string();
if !pack_path.ends_with('/') {
pack_path.push('/');
}
Ok(json
.iter()
.map(|query| query.replace(&pack_path, ""))
.collect())
}
pub async fn download(&self) -> Result<(), GHASError> {
log::debug!("Downloading CodeQL Pack: {}", self.pack.full_name());
self.codeql
.run(vec!["pack", "download", self.pack.full_name().as_str()])
.await?;
Ok(())
}
}