use serde::{Deserialize, Serialize};
use std::{collections::HashMap, path::PathBuf};
use url::Url;
#[derive(Serialize, Deserialize, Default, PartialEq, Eq, Debug)]
pub struct Config {
pub workspace: Workspace,
#[serde(default)]
pub package: HashMap<String, PackageConfig>,
}
#[derive(Serialize, Deserialize, Default, PartialEq, Eq, Debug)]
pub struct Workspace {
#[serde(flatten)]
pub update: UpdateConfig,
#[serde(flatten)]
pub packages_defaults: PackageConfig,
}
#[derive(Serialize, Deserialize, Default, PartialEq, Eq, Debug)]
pub struct UpdateConfig {
pub update_dependencies: bool,
pub changelog_config: Option<PathBuf>,
pub allow_dirty: bool,
pub repo_url: Option<Url>,
}
#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Default)]
pub struct PackageConfig {
#[serde(flatten)]
update: PackageUpdateConfig,
#[serde(flatten)]
release: PackageReleaseConfig,
}
#[derive(Serialize, Deserialize, PartialEq, Eq, Debug)]
pub struct PackageUpdateConfig {
pub semver_check: SemverCheck,
pub update_changelog: bool,
}
#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Default)]
pub struct PackageReleaseConfig {
pub git_release: GitReleaseConfig,
}
#[derive(Serialize, Deserialize, Default, PartialEq, Eq, Debug)]
#[serde(rename_all = "snake_case")]
pub enum SemverCheck {
#[default]
Lib,
Yes,
No,
}
impl Default for PackageUpdateConfig {
fn default() -> Self {
Self {
semver_check: SemverCheck::default(),
update_changelog: true,
}
}
}
#[derive(Serialize, Deserialize, PartialEq, Eq, Debug)]
pub struct GitReleaseConfig {
pub enable: bool,
pub release_type: ReleaseType,
pub draft: bool,
}
impl Default for GitReleaseConfig {
fn default() -> Self {
Self {
enable: true,
release_type: ReleaseType::default(),
draft: false,
}
}
}
#[derive(Serialize, Deserialize, Default, PartialEq, Eq, Debug)]
#[serde(rename_all = "snake_case")]
pub enum ReleaseType {
#[default]
Prod,
Pre,
Auto,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn config_is_deserialized() {
let config = r#"
[workspace]
update_dependencies = false
changelog_config = "../git-cliff.toml"
allow_dirty = false
repo_url = "https://github.com/MarcoIeni/release-plz"
semver_check = "lib"
update_changelog = true
[workspace.git_release]
enable = true
release_type = "prod"
draft = false
"#;
let expected_config = Config {
workspace: Workspace {
update: UpdateConfig {
update_dependencies: false,
changelog_config: Some("../git-cliff.toml".into()),
allow_dirty: false,
repo_url: Some("https://github.com/MarcoIeni/release-plz".parse().unwrap()),
},
packages_defaults: PackageConfig {
update: PackageUpdateConfig {
semver_check: SemverCheck::Lib,
update_changelog: true,
},
release: PackageReleaseConfig {
git_release: GitReleaseConfig {
enable: true,
release_type: ReleaseType::Prod,
draft: false,
},
},
},
},
package: [].into(),
};
let config: Config = toml::from_str(config).unwrap();
assert_eq!(config, expected_config)
}
#[test]
fn config_is_serialized() {
let config = Config {
workspace: Workspace {
update: UpdateConfig {
update_dependencies: false,
changelog_config: Some("../git-cliff.toml".into()),
allow_dirty: false,
repo_url: Some("https://github.com/MarcoIeni/release-plz".parse().unwrap()),
},
packages_defaults: PackageConfig {
update: PackageUpdateConfig {
semver_check: SemverCheck::Lib,
update_changelog: true,
},
release: PackageReleaseConfig {
git_release: GitReleaseConfig {
enable: true,
release_type: ReleaseType::Prod,
draft: false,
},
},
},
},
package: [(
"crate1".to_string(),
PackageConfig {
update: PackageUpdateConfig {
semver_check: SemverCheck::No,
update_changelog: true,
},
release: PackageReleaseConfig {
git_release: GitReleaseConfig {
enable: true,
release_type: ReleaseType::Prod,
draft: false,
},
},
},
)]
.into(),
};
expect_test::expect![[r#"
[workspace]
update_dependencies = false
changelog_config = "../git-cliff.toml"
allow_dirty = false
repo_url = "https://github.com/MarcoIeni/release-plz"
semver_check = "lib"
update_changelog = true
[workspace.git_release]
enable = true
release_type = "prod"
draft = false
[package.crate1]
semver_check = "no"
update_changelog = true
[package.crate1.git_release]
enable = true
release_type = "prod"
draft = false
"#]]
.assert_eq(&toml::to_string(&config).unwrap());
}
}