86 lines
2.3 KiB
Rust
86 lines
2.3 KiB
Rust
use anyhow::{Context, Result};
|
|
use serde::{Deserialize, Serialize};
|
|
use serde_json;
|
|
use std::{
|
|
collections::BTreeMap,
|
|
fs::File,
|
|
io::Read,
|
|
path::{Path, PathBuf},
|
|
};
|
|
|
|
/// The top-level configuration for settings. This will typically be stored
|
|
/// at the repository root at `./.config/mfgames-conventional-commit.json`.
|
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
|
#[serde(tag = "$schema")]
|
|
pub enum Config {
|
|
#[serde(
|
|
rename = "https://mfgames.com/mfgames-conventional-commit/schemas/v0.0.json"
|
|
)]
|
|
Config0(Config0),
|
|
}
|
|
|
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
|
pub struct Config0 {
|
|
/// Settings for specific projects.
|
|
pub packages: BTreeMap<String, PackageSettings>,
|
|
}
|
|
|
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
|
pub struct PackageSettings {
|
|
/// The prefix of the Git tag to search for.
|
|
pub tag_prefix: String,
|
|
|
|
/// The matching for paths.
|
|
pub paths: Option<IncludeExcludeList>,
|
|
}
|
|
|
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
|
pub struct IncludeExcludeList {
|
|
/// The strings to include. If this is None, then everything is included.
|
|
pub include: Option<Vec<String>>,
|
|
|
|
/// The entries to exclude. If this is None, then nothing is excluded.
|
|
pub exclude: Option<Vec<String>>,
|
|
}
|
|
|
|
impl Config {
|
|
pub fn get_git_config_file(git_dir: &Path) -> PathBuf {
|
|
let mut path = PathBuf::from(git_dir);
|
|
|
|
path.push(".config");
|
|
path.push("mfgames-conventional-commit.json");
|
|
|
|
path
|
|
}
|
|
|
|
pub fn load(path: &PathBuf) -> Result<Config> {
|
|
let mut file = File::open(path)?;
|
|
let mut data = String::new();
|
|
|
|
file.read_to_string(&mut data)?;
|
|
|
|
let config: Config = serde_json::from_str(&data)
|
|
.with_context(|| format!("cannot read config from {:?}", &path))?;
|
|
|
|
Ok(config)
|
|
}
|
|
|
|
pub fn get_package(
|
|
&self,
|
|
package_name: impl Into<String>,
|
|
) -> Result<PackageSettings> {
|
|
let package_name = package_name.into();
|
|
let Config::Config0(config) = &self;
|
|
let config = config.clone();
|
|
let packages = config.packages;
|
|
|
|
let package = packages
|
|
.get(&package_name)
|
|
.context(format!("cannot find package {}", package_name))?;
|
|
|
|
let package = package.clone();
|
|
|
|
Ok(package)
|
|
}
|
|
}
|