use bson::{doc, Document};
use derive_builder::Builder;
use derive_default_builder::DefaultBuilder;
use partial_derive2::Partial;
use serde::{Deserialize, Serialize};
use strum::Display;
use typeshare::typeshare;
use crate::entities::I64;
use super::{
resource::{Resource, ResourceListItem, ResourceQuery},
EnvironmentVar, SystemCommand,
};
#[typeshare]
pub type RepoListItem = ResourceListItem<RepoListItemInfo>;
#[typeshare]
#[derive(Serialize, Deserialize, Debug, Clone, Default)]
pub struct RepoListItemInfo {
pub server_id: String,
pub builder_id: String,
pub last_pulled_at: I64,
pub last_built_at: I64,
pub git_provider: String,
pub repo: String,
pub branch: String,
pub state: RepoState,
pub cloned_hash: Option<String>,
pub cloned_message: Option<String>,
pub built_hash: Option<String>,
pub latest_hash: Option<String>,
}
#[typeshare]
#[derive(
Debug, Clone, Copy, Default, Serialize, Deserialize, Display,
)]
pub enum RepoState {
#[default]
Unknown,
Ok,
Failed,
Cloning,
Pulling,
Building,
}
#[typeshare]
pub type Repo = Resource<RepoConfig, RepoInfo>;
#[typeshare]
#[derive(Serialize, Deserialize, Debug, Clone, Default)]
pub struct RepoInfo {
#[serde(default)]
pub last_pulled_at: I64,
#[serde(default)]
pub last_built_at: I64,
pub built_hash: Option<String>,
pub built_message: Option<String>,
pub latest_hash: Option<String>,
pub latest_message: Option<String>,
}
#[typeshare(serialized_as = "Partial<RepoConfig>")]
pub type _PartialRepoConfig = PartialRepoConfig;
#[typeshare]
#[derive(Serialize, Deserialize, Debug, Clone, Builder, Partial)]
#[partial_derive(Serialize, Deserialize, Debug, Clone, Default)]
#[partial(skip_serializing_none, from, diff)]
pub struct RepoConfig {
#[serde(default)]
#[builder(default)]
pub server_id: String,
#[serde(default)]
#[builder(default)]
pub builder_id: String,
#[serde(default = "default_git_provider")]
#[builder(default = "default_git_provider()")]
#[partial_default(default_git_provider())]
pub git_provider: String,
#[serde(default = "default_git_https")]
#[builder(default = "default_git_https()")]
#[partial_default(default_git_https())]
pub git_https: bool,
#[serde(default)]
#[builder(default)]
pub git_account: String,
#[serde(default)]
#[builder(default)]
pub repo: String,
#[serde(default = "default_branch")]
#[builder(default = "default_branch()")]
#[partial_default(default_branch())]
pub branch: String,
#[serde(default)]
#[builder(default)]
pub commit: String,
#[serde(default)]
#[builder(default)]
pub path: String,
#[serde(default = "default_webhook_enabled")]
#[builder(default = "default_webhook_enabled()")]
#[partial_default(default_webhook_enabled())]
pub webhook_enabled: bool,
#[serde(default)]
#[builder(default)]
pub webhook_secret: String,
#[serde(default)]
#[builder(default)]
pub on_clone: SystemCommand,
#[serde(default)]
#[builder(default)]
pub on_pull: SystemCommand,
#[serde(
default,
deserialize_with = "super::env_vars_deserializer"
)]
#[partial_attr(serde(
default,
deserialize_with = "super::option_env_vars_deserializer"
))]
#[builder(default)]
pub environment: Vec<EnvironmentVar>,
#[serde(default = "default_env_file_path")]
#[builder(default = "default_env_file_path()")]
#[partial_default(default_env_file_path())]
pub env_file_path: String,
#[serde(default)]
#[builder(default)]
pub skip_secret_interp: bool,
}
impl RepoConfig {
pub fn builder() -> RepoConfigBuilder {
RepoConfigBuilder::default()
}
}
fn default_git_provider() -> String {
String::from("github.com")
}
fn default_git_https() -> bool {
true
}
fn default_branch() -> String {
String::from("main")
}
fn default_env_file_path() -> String {
String::from(".env")
}
fn default_webhook_enabled() -> bool {
true
}
impl Default for RepoConfig {
fn default() -> Self {
Self {
server_id: Default::default(),
builder_id: Default::default(),
git_provider: default_git_provider(),
git_https: default_git_https(),
repo: Default::default(),
branch: default_branch(),
commit: Default::default(),
git_account: Default::default(),
path: Default::default(),
on_clone: Default::default(),
on_pull: Default::default(),
environment: Default::default(),
env_file_path: default_env_file_path(),
skip_secret_interp: Default::default(),
webhook_enabled: default_webhook_enabled(),
webhook_secret: Default::default(),
}
}
}
#[typeshare]
#[derive(Serialize, Deserialize, Debug, Clone, Copy, Default)]
pub struct RepoActionState {
pub cloning: bool,
pub pulling: bool,
pub building: bool,
}
#[typeshare]
pub type RepoQuery = ResourceQuery<RepoQuerySpecifics>;
#[typeshare]
#[derive(
Serialize, Deserialize, Debug, Clone, Default, DefaultBuilder,
)]
pub struct RepoQuerySpecifics {
pub repos: Vec<String>,
}
impl super::resource::AddFilters for RepoQuerySpecifics {
fn add_filters(&self, filters: &mut Document) {
if !self.repos.is_empty() {
filters.insert("config.repo", doc! { "$in": &self.repos });
}
}
}