use crate::{
BuiltinTransformer, Error, ShellCommandTransformer, Transformer, builtin_transformers,
create_shell_transformer,
};
use git2::Repository;
use glob::Pattern;
use semver::VersionReq;
use serde::{Deserialize, Serialize};
use std::path::Path;
#[derive(Debug, Serialize, Deserialize)]
pub enum TransformerOptions {
Builtin(BuiltinTransformer),
External(ShellCommandTransformer),
}
impl TransformerOptions {
pub fn transformer(&self, repository_path: &Path) -> Box<dyn Transformer> {
match self {
Self::Builtin(BuiltinTransformer::TrailingWhitespace) => {
Box::new(builtin_transformers::trailing_whitespace)
}
Self::External(command_type) => {
let command_type = command_type.clone();
let repository_path = repository_path.to_path_buf();
Box::new(create_shell_transformer(move |extension: Option<&str>| {
command_type.get_command(&repository_path, extension)
}))
}
}
}
}
#[derive(Debug, Serialize, Deserialize)]
pub struct ConfigurationItem {
pub glob: String,
pub transformers: Vec<TransformerOptions>,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct Configuration {
pub requires_yact_version: Option<VersionReq>,
pub items: Vec<ConfigurationItem>,
}
pub fn load_configuration(repository: &Repository) -> Result<Configuration, Error> {
let path = repository.workdir().ok_or(Error::RepositoryIsBare)?;
let file = std::fs::read(path.join("yactrc.toml")).map_err(|_| Error::ConfigurationNotFound)?;
let config_str = std::str::from_utf8(&file)?;
let configuration: Configuration = toml::from_str(config_str)?;
for item in &configuration.items {
if Pattern::new(&item.glob).is_err() {
return Err(Error::InvalidGlob(item.glob.clone()));
}
}
Ok(configuration)
}