use std::collections::HashSet;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct GitCapabilities {
#[serde(default = "default_git_ops")]
pub allowed_ops: HashSet<GitOperation>,
#[serde(default)]
pub protected_branches: Vec<String>,
#[serde(default)]
pub can_force_push: bool,
#[serde(default)]
pub can_destructive: bool,
#[serde(default)]
pub require_pr_branches: Vec<String>,
}
fn default_git_ops() -> HashSet<GitOperation> {
let mut ops = HashSet::new();
ops.insert(GitOperation::Status);
ops.insert(GitOperation::Diff);
ops.insert(GitOperation::Log);
ops
}
impl Default for GitCapabilities {
fn default() -> Self {
Self {
allowed_ops: default_git_ops(),
protected_branches: vec!["main".to_string(), "master".to_string()],
can_force_push: false,
can_destructive: false,
require_pr_branches: Vec::new(),
}
}
}
impl GitCapabilities {
pub fn read_only() -> Self {
let mut ops = HashSet::new();
ops.insert(GitOperation::Status);
ops.insert(GitOperation::Diff);
ops.insert(GitOperation::Log);
ops.insert(GitOperation::Fetch);
Self {
allowed_ops: ops,
protected_branches: vec!["main".to_string(), "master".to_string()],
can_force_push: false,
can_destructive: false,
require_pr_branches: Vec::new(),
}
}
pub fn standard() -> Self {
let mut ops = HashSet::new();
ops.insert(GitOperation::Status);
ops.insert(GitOperation::Diff);
ops.insert(GitOperation::Log);
ops.insert(GitOperation::Add);
ops.insert(GitOperation::Commit);
ops.insert(GitOperation::Push);
ops.insert(GitOperation::Pull);
ops.insert(GitOperation::Fetch);
ops.insert(GitOperation::Branch);
ops.insert(GitOperation::Checkout);
ops.insert(GitOperation::Stash);
Self {
allowed_ops: ops,
protected_branches: vec!["main".to_string(), "master".to_string()],
can_force_push: false,
can_destructive: false,
require_pr_branches: Vec::new(),
}
}
pub fn full() -> Self {
let mut ops = HashSet::new();
ops.insert(GitOperation::Status);
ops.insert(GitOperation::Diff);
ops.insert(GitOperation::Log);
ops.insert(GitOperation::Add);
ops.insert(GitOperation::Commit);
ops.insert(GitOperation::Push);
ops.insert(GitOperation::Pull);
ops.insert(GitOperation::Fetch);
ops.insert(GitOperation::Branch);
ops.insert(GitOperation::Checkout);
ops.insert(GitOperation::Merge);
ops.insert(GitOperation::Rebase);
ops.insert(GitOperation::Reset);
ops.insert(GitOperation::Stash);
ops.insert(GitOperation::Tag);
ops.insert(GitOperation::ForcePush);
Self {
allowed_ops: ops,
protected_branches: Vec::new(),
can_force_push: true,
can_destructive: true,
require_pr_branches: Vec::new(),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum GitOperation {
Status,
Diff,
Log,
Add,
Commit,
Push,
Pull,
Fetch,
Branch,
Checkout,
Merge,
Rebase,
Reset,
Stash,
Tag,
ForcePush,
}
impl GitOperation {
pub fn is_destructive(&self) -> bool {
matches!(
self,
GitOperation::Rebase
| GitOperation::Reset
| GitOperation::ForcePush
| GitOperation::Merge
)
}
}