use serde::{Deserialize, Serialize};
use std::path::PathBuf;
#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct CodeQLExtractor {
#[serde(skip)]
pub path: PathBuf,
pub name: String,
pub display_name: String,
pub version: String,
#[serde(default)]
pub build_modes: Vec<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub column_kind: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub legacy_qltest_extraction: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub github_api_languages: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub scc_languages: Option<Vec<String>>,
pub file_types: Vec<CodeQLExtractorFileType>,
}
impl CodeQLExtractor {
pub fn load(content: &str) -> Result<Self, crate::errors::GHASError> {
let extractor: CodeQLExtractor = serde_yaml::from_str(content)?;
Ok(extractor)
}
pub fn load_path(path: impl Into<PathBuf>) -> Result<Self, crate::errors::GHASError> {
let mut path: PathBuf = path.into();
if path.is_dir() {
path = path.join("codeql-extractor.yml");
}
log::debug!("Loading CodeQL Extractor from: {}", path.display());
if !path.exists() {
return Err(crate::GHASError::IoError(std::io::Error::new(
std::io::ErrorKind::NotFound,
"File not found",
)));
}
let content = std::fs::read_to_string(&path)?;
let mut extractor: CodeQLExtractor = serde_yaml::from_str(&content)?;
if let Some(parent) = path.parent() {
extractor.path = parent.to_path_buf();
}
Ok(extractor)
}
pub fn languages(&self) -> Vec<String> {
let mut results = Vec::new();
results.extend(self.github_api_languages.clone().unwrap_or_default());
results
}
pub fn build_modes(&self) -> Vec<super::BuildMode> {
self.build_modes
.iter()
.map(|mode| match mode.as_str() {
"none" | "buildless" => super::BuildMode::None,
"auto" => super::BuildMode::AutoBuild,
"manual" => super::BuildMode::Manual,
_ => super::BuildMode::None,
})
.collect()
}
}
#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct CodeQLExtractorFileType {
pub name: String,
pub display_name: String,
pub extensions: Vec<String>,
}
impl TryFrom<PathBuf> for CodeQLExtractor {
type Error = crate::errors::GHASError;
fn try_from(path: PathBuf) -> Result<Self, Self::Error> {
CodeQLExtractor::load_path(path)
}
}