impl TdgHooksConfig {
pub fn load(project_root: &Path) -> Result<Self> {
let config_path = project_root.join(".pmat").join("tdg-rules.toml");
if !config_path.exists() {
return Ok(Self::default());
}
let contents = fs::read_to_string(&config_path)
.context(format!("Failed to read config file: {:?}", config_path))?;
let config: TdgHooksConfig = toml::from_str(&contents)
.context(format!("Failed to parse config file: {:?}", config_path))?;
Ok(config)
}
pub fn create_default(project_root: &Path) -> Result<()> {
let pmat_dir = project_root.join(".pmat");
let config_path = pmat_dir.join("tdg-rules.toml");
if !pmat_dir.exists() {
fs::create_dir_all(&pmat_dir)?;
}
if config_path.exists() {
return Ok(());
}
let default_config = Self::default();
let toml_string = toml::to_string_pretty(&default_config)
.context("Failed to serialize default config")?;
fs::write(&config_path, toml_string)
.context(format!("Failed to write config file: {:?}", config_path))?;
Ok(())
}
}
impl QualityGatesConfig {
pub fn get_min_grade(&self, language: &str) -> Option<&str> {
if let Some(grade) = self.min_grades.get(language) {
return Some(grade.as_str());
}
match language.to_lowercase().as_str() {
"rust" => self.rust_min_grade.as_deref(),
"typescript" | "javascript" => self.typescript_min_grade.as_deref(),
"python" => self.python_min_grade.as_deref(),
_ => None,
}
}
pub fn get_default_min_grade(&self) -> &str {
"B+"
}
}
impl std::fmt::Display for EnforcementMode {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Strict => write!(f, "strict"),
Self::Warning => write!(f, "warning"),
Self::Disabled => write!(f, "disabled"),
}
}
}