Skip to content
Clone
b7b40ce
68 lines 1.8 KB Rust
use std::sync::Arc;
/// on every ref/tag mutation to decide whether the operation is allowed.
pub trait PolicyProvider: Send + Sync {
fn is_branch_protected(&self, branch: &str) -> bool;
fn is_tag_protected(&self, tag: &str) -> bool;
}
/// deletion of `main`/`master`/`develop` and `release/*` tags, while allowing
#[derive(Debug, Clone, Default)]
pub struct DefaultPolicy;
impl DefaultPolicy {
fn is_integration_branch(branch: &str) -> bool {
matches!(branch, "main" | "master" | "develop")
}
}
impl PolicyProvider for DefaultPolicy {
fn is_branch_protected(&self, branch: &str) -> bool {
Self::is_integration_branch(branch)
}
fn is_tag_protected(&self, tag: &str) -> bool {
tag.starts_with("release/")
}
}
#[derive(Debug, Clone, Default)]
pub struct NoProtection;
impl PolicyProvider for NoProtection {
fn is_branch_protected(&self, _branch: &str) -> bool {
false
}
fn is_tag_protected(&self, _tag: &str) -> bool {
false
}
}
pub type Policy = Arc<dyn PolicyProvider>;
pub fn arc<P: PolicyProvider + 'static>(provider: P) -> Policy {
Arc::new(provider)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn default_policy_protects_integration_branches() {
let p = DefaultPolicy;
assert!(p.is_branch_protected("main"));
assert!(p.is_branch_protected("master"));
assert!(p.is_branch_protected("develop"));
assert!(!p.is_branch_protected("feature"));
assert!(p.is_tag_protected("release/v1.0"));
assert!(!p.is_tag_protected("v1.0"));
}
#[test]
fn no_protection_protects_nothing() {
let p = NoProtection;
assert!(!p.is_branch_protected("main"));
assert!(!p.is_tag_protected("release/v1.0"));
}
}