Compare commits

...

3 commits

Author SHA1 Message Date
dda5992596 refactor(server): more derive_more replacing boilerplate
Some checks failed
ci/woodpecker/push/cron-docker-builder Pipeline was successful
/ test (push) Successful in 2s
ci/woodpecker/push/tag-created Pipeline was successful
ci/woodpecker/push/push-next Pipeline failed
2024-05-15 21:01:19 +01:00
f8375ed1fc refactor(server/config): rename RepoConfigValidationError as Error
Some checks failed
ci/woodpecker/cron/cron-docker-builder Pipeline was successful
ci/woodpecker/cron/push-next Pipeline was successful
ci/woodpecker/cron/tag-created Pipeline was successful
/ test (push) Successful in 2s
ci/woodpecker/push/tag-created Pipeline was successful
ci/woodpecker/push/cron-docker-builder Pipeline was successful
ci/woodpecker/push/push-next Pipeline failed
It is never referenced directly outside of this module.
2024-05-15 20:46:29 +01:00
eb7d14bc33 refactor(git): more derive_more replacing boilerplate
All checks were successful
/ test (push) Successful in 2s
ci/woodpecker/push/cron-docker-builder Pipeline was successful
ci/woodpecker/push/push-next Pipeline was successful
ci/woodpecker/push/tag-created Pipeline was successful
2024-05-15 20:40:25 +01:00
14 changed files with 65 additions and 172 deletions

View file

@ -1,16 +1,10 @@
#[derive(Clone, Debug, PartialEq, Eq, derive_more::Display)] #[derive(Clone, Debug, PartialEq, Eq, derive_more::Constructor, derive_more::Display)]
#[display("{}", sha)] #[display("{}", sha)]
pub struct Commit { pub struct Commit {
sha: Sha, sha: Sha,
message: Message, message: Message,
} }
impl Commit { impl Commit {
pub fn new(sha: &str, message: &str) -> Self {
Self {
sha: Sha::new(sha.to_string()),
message: Message::new(message.to_string()),
}
}
pub const fn sha(&self) -> &Sha { pub const fn sha(&self) -> &Sha {
&self.sha &self.sha
} }
@ -19,18 +13,8 @@ impl Commit {
} }
} }
#[derive(Clone, Debug, PartialEq, Eq, derive_more::Display)] #[derive(Clone, Debug, PartialEq, Eq, derive_more::Constructor, derive_more::Display)]
pub struct Sha(String); pub struct Sha(String);
impl Sha {
pub const fn new(value: String) -> Self {
Self(value)
}
}
#[derive(Clone, Debug, PartialEq, Eq, derive_more::Display)] #[derive(Clone, Debug, PartialEq, Eq, derive_more::Constructor, derive_more::Display)]
pub struct Message(String); pub struct Message(String);
impl Message {
pub const fn new(value: String) -> Self {
Self(value)
}
}

View file

@ -1,7 +1,7 @@
use crate::Commit; use crate::Commit;
#[derive(Clone, Debug, Hash, PartialEq, Eq, derive_more::Display)] #[derive(Clone, Debug, Hash, PartialEq, Eq, derive_more::Display)]
pub struct GitRef(pub String); pub struct GitRef(String);
impl From<Commit> for GitRef { impl From<Commit> for GitRef {
fn from(value: Commit) -> Self { fn from(value: Commit) -> Self {
Self(value.sha().to_string()) Self(value.sha().to_string())

View file

@ -1,15 +1,12 @@
use git_next_config::{Hostname, RepoPath}; use git_next_config::{Hostname, RepoPath};
#[derive(Clone, Debug, PartialEq, Eq, derive_more::Display)] #[derive(Clone, Debug, PartialEq, Eq, derive_more::Constructor, derive_more::Display)]
#[display("{}:{}", host, repo_path)] #[display("{}:{}", host, repo_path)]
pub struct GitRemote { pub struct GitRemote {
host: Hostname, host: Hostname,
repo_path: RepoPath, repo_path: RepoPath,
} }
impl GitRemote { impl GitRemote {
pub const fn new(host: Hostname, repo_path: RepoPath) -> Self {
Self { host, repo_path }
}
pub const fn host(&self) -> &Hostname { pub const fn host(&self) -> &Hostname {
&self.host &self.host
} }

View file

@ -7,17 +7,13 @@ use tracing::{debug, info};
const CHECK_INTERVAL: Duration = Duration::from_secs(1); const CHECK_INTERVAL: Duration = Duration::from_secs(1);
#[derive(Debug, Clone)] #[derive(Debug, Clone, Message)]
#[rtype(result = "()")]
pub struct WatchFile; pub struct WatchFile;
impl Message for WatchFile {
type Result = ();
}
#[derive(Debug)] #[derive(Debug, Message)]
#[rtype(result = "()")]
pub struct FileUpdated; pub struct FileUpdated;
impl Message for FileUpdated {
type Result = ();
}
#[derive(Debug, derive_more::From, derive_more::Display)] #[derive(Debug, derive_more::From, derive_more::Display)]
pub enum Error { pub enum Error {
@ -72,13 +68,3 @@ impl Handler<WatchFile> for FileWatcher {
} }
} }
} }
// impl Handler<Stop> for FileWatcher {
// type Result = anyhow::Result<()>;
//
// fn handle(&mut self, _msg: Stop, ctx: &mut Self::Context) -> Self::Result {
// warn!("Stopping file watcher actor");
// self.run_interval.take();
// ctx.stop();
// Ok(())
// }
// }

View file

@ -16,6 +16,8 @@ use crate::{actors::repo::webhook::WebhookAuth, config::Webhook, gitforge, types
use self::webhook::WebhookId; use self::webhook::WebhookId;
#[derive(Debug, derive_more::Display)]
#[display("{}:{}:{}", generation, details.forge.forge_name(), details.repo_alias)]
pub struct RepoActor { pub struct RepoActor {
generation: Generation, generation: Generation,
message_token: MessageToken, message_token: MessageToken,
@ -79,17 +81,6 @@ impl Actor for RepoActor {
} }
} }
} }
impl std::fmt::Display for RepoActor {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{}:{}:{}",
self.generation,
self.details.forge.forge_name(),
self.details.repo_alias
)
}
}
#[derive(Message)] #[derive(Message)]
#[rtype(result = "()")] #[rtype(result = "()")]
@ -136,7 +127,7 @@ impl Handler<LoadConfigFromRepo> for RepoActor {
#[derive(Message)] #[derive(Message)]
#[rtype(result = "()")] #[rtype(result = "()")]
struct LoadedConfig(pub RepoConfig); struct LoadedConfig(RepoConfig);
impl Handler<LoadedConfig> for RepoActor { impl Handler<LoadedConfig> for RepoActor {
type Result = (); type Result = ();
#[tracing::instrument(name = "RepoActor::LoadedConfig", skip_all, fields(repo = %self.details, branches = %msg.0))] #[tracing::instrument(name = "RepoActor::LoadedConfig", skip_all, fields(repo = %self.details, branches = %msg.0))]
@ -151,16 +142,11 @@ impl Handler<LoadedConfig> for RepoActor {
} }
} }
#[derive(Message)] #[derive(derive_more::Constructor, Message)]
#[rtype(result = "()")] #[rtype(result = "()")]
pub struct ValidateRepo { pub struct ValidateRepo {
message_token: MessageToken, message_token: MessageToken,
} }
impl ValidateRepo {
pub const fn new(message_token: MessageToken) -> Self {
Self { message_token }
}
}
impl Handler<ValidateRepo> for RepoActor { impl Handler<ValidateRepo> for RepoActor {
type Result = (); type Result = ();
#[tracing::instrument(name = "RepoActor::ValidateRepo", skip_all, fields(repo = %self.details, token = %msg.message_token))] #[tracing::instrument(name = "RepoActor::ValidateRepo", skip_all, fields(repo = %self.details, token = %msg.message_token))]
@ -208,17 +194,19 @@ impl Handler<ValidateRepo> for RepoActor {
} }
} }
#[derive(Debug, Message)] #[derive(Debug, derive_more::Constructor, Message)]
#[rtype(result = "()")] #[rtype(result = "()")]
pub struct StartMonitoring { pub struct StartMonitoring {
pub main: git::Commit, main: git::Commit,
pub next: git::Commit, next: git::Commit,
pub dev: git::Commit, dev: git::Commit,
pub dev_commit_history: Vec<git::Commit>, dev_commit_history: Vec<git::Commit>,
} }
impl Handler<StartMonitoring> for RepoActor { impl Handler<StartMonitoring> for RepoActor {
type Result = (); type Result = ();
#[tracing::instrument(name = "RepoActor::StartMonitoring", skip_all, fields(token = %self.message_token, repo = %self.details, main = %msg.main, next= %msg.next, dev = %msg.dev))] #[tracing::instrument(name = "RepoActor::StartMonitoring", skip_all,
fields(token = %self.message_token, repo = %self.details, main = %msg.main, next= %msg.next, dev = %msg.dev))
]
fn handle(&mut self, msg: StartMonitoring, ctx: &mut Self::Context) -> Self::Result { fn handle(&mut self, msg: StartMonitoring, ctx: &mut Self::Context) -> Self::Result {
info!("Message Received"); info!("Message Received");
let Some(repo_config) = self.details.repo_config.clone() else { let Some(repo_config) = self.details.repo_config.clone() else {
@ -259,7 +247,7 @@ impl Handler<StartMonitoring> for RepoActor {
#[derive(Message)] #[derive(Message)]
#[rtype(result = "()")] #[rtype(result = "()")]
pub struct WebhookRegistered(pub WebhookId, pub WebhookAuth); pub struct WebhookRegistered(WebhookId, WebhookAuth);
impl Handler<WebhookRegistered> for RepoActor { impl Handler<WebhookRegistered> for RepoActor {
type Result = (); type Result = ();
#[tracing::instrument(name = "RepoActor::WebhookRegistered", skip_all, fields(repo = %self.details, webhook_id = %msg.0))] #[tracing::instrument(name = "RepoActor::WebhookRegistered", skip_all, fields(repo = %self.details, webhook_id = %msg.0))]
@ -272,7 +260,7 @@ impl Handler<WebhookRegistered> for RepoActor {
#[derive(Message)] #[derive(Message)]
#[rtype(result = "()")] #[rtype(result = "()")]
pub struct AdvanceMainTo(pub git::Commit); pub struct AdvanceMainTo(git::Commit);
impl Handler<AdvanceMainTo> for RepoActor { impl Handler<AdvanceMainTo> for RepoActor {
type Result = (); type Result = ();
#[tracing::instrument(name = "RepoActor::AdvanceMainTo", skip_all, fields(repo = %self.details, commit = %msg.0))] #[tracing::instrument(name = "RepoActor::AdvanceMainTo", skip_all, fields(repo = %self.details, commit = %msg.0))]

View file

@ -6,13 +6,25 @@ mod branch {
#[actix_rt::test] #[actix_rt::test]
async fn test_find_next_commit_on_dev() { async fn test_find_next_commit_on_dev() {
let next = git::Commit::new("current-next", "foo"); let next = git::Commit::new(
let expected = git::Commit::new("dev-next", "next-should-go-here"); git::commit::Sha::new("current-next".to_string()),
git::commit::Message::new("foo".to_string()),
);
let expected = git::Commit::new(
git::commit::Sha::new("dev-next".to_string()),
git::commit::Message::new("next-should-go-here".to_string()),
);
let dev_commit_history = vec![ let dev_commit_history = vec![
git::Commit::new("dev", "future"), git::Commit::new(
git::commit::Sha::new("dev".to_string()),
git::commit::Message::new("future".to_string()),
),
expected.clone(), expected.clone(),
next.clone(), next.clone(),
git::Commit::new("current-main", "history"), git::Commit::new(
git::commit::Sha::new("current-main".to_string()),
git::commit::Message::new("history".to_string()),
),
]; ];
let next_commit = find_next_commit_on_dev(next, dev_commit_history); let next_commit = find_next_commit_on_dev(next, dev_commit_history);

View file

@ -5,7 +5,7 @@ use kxio::network::{self, json};
use tracing::{debug, info, warn}; use tracing::{debug, info, warn};
use ulid::DecodeError; use ulid::DecodeError;
use std::{collections::HashMap, fmt::Display, ops::Deref, str::FromStr}; use std::{collections::HashMap, str::FromStr};
use crate::{ use crate::{
actors::{ actors::{
@ -15,27 +15,12 @@ use crate::{
config::{Webhook, WebhookUrl}, config::{Webhook, WebhookUrl},
}; };
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(
Clone, Debug, PartialEq, Eq, derive_more::Constructor, derive_more::Deref, derive_more::Display,
)]
pub struct WebhookId(String); pub struct WebhookId(String);
impl WebhookId {
#[allow(dead_code)]
pub const fn new(id: String) -> Self {
Self(id)
}
}
impl Deref for WebhookId {
type Target = String;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl Display for WebhookId {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq, derive_more::Deref)]
pub struct WebhookAuth(ulid::Ulid); pub struct WebhookAuth(ulid::Ulid);
impl WebhookAuth { impl WebhookAuth {
pub fn from_str(authorisation: &str) -> Result<Self, DecodeError> { pub fn from_str(authorisation: &str) -> Result<Self, DecodeError> {
@ -51,12 +36,6 @@ impl WebhookAuth {
format!("Basic {}", self.0.to_string()) format!("Basic {}", self.0.to_string())
} }
} }
impl Deref for WebhookAuth {
type Target = ulid::Ulid;
fn deref(&self) -> &Self::Target {
&self.0
}
}
#[tracing::instrument(skip_all, fields(%webhook_id))] #[tracing::instrument(skip_all, fields(%webhook_id))]
pub async fn unregister(webhook_id: WebhookId, repo_details: RepoDetails, net: network::Network) { pub async fn unregister(webhook_id: WebhookId, repo_details: RepoDetails, net: network::Network) {
@ -301,7 +280,10 @@ impl Push {
} }
pub fn commit(&self) -> git::Commit { pub fn commit(&self) -> git::Commit {
git::Commit::new(&self.after, &self.head_commit.message) git::Commit::new(
git::commit::Sha::new(self.after.clone()),
git::commit::Message::new(self.head_commit.message.clone()),
)
} }
} }

View file

@ -3,46 +3,21 @@ use actix::prelude::*;
use crate::actors::repo::webhook::WebhookAuth; use crate::actors::repo::webhook::WebhookAuth;
#[derive(Message, Debug, Clone)] #[derive(Message, Debug, Clone, derive_more::Constructor)]
#[rtype(result = "()")] #[rtype(result = "()")]
pub struct WebhookMessage { pub struct WebhookMessage {
id: String, id: String,
path: String, path: String,
authorisation: String, authorisation: String,
// query: String,
// headers: warp::http::HeaderMap,
body: String, body: String,
} }
impl WebhookMessage { impl WebhookMessage {
pub const fn new(
id: String,
path: String,
// query: String,
// headers: warp::http::HeaderMap,
body: String,
authorisation: String,
) -> Self {
Self {
id,
path,
// query,
// headers,
body,
authorisation,
}
}
pub const fn id(&self) -> &String { pub const fn id(&self) -> &String {
&self.id &self.id
} }
pub const fn path(&self) -> &String { pub const fn path(&self) -> &String {
&self.path &self.path
} }
// pub const fn query(&self) -> &String {
// &self.query
// }
// pub const fn headers(&self) -> &warp::http::HeaderMap {
// &self.headers
// }
pub const fn body(&self) -> &String { pub const fn body(&self) -> &String {
&self.body &self.body
} }

View file

@ -42,11 +42,9 @@ impl Actor for WebhookActor {
} }
} }
#[derive(Debug)] #[derive(Debug, Message)]
#[rtype(result = "()")]
pub struct ShutdownWebhook; pub struct ShutdownWebhook;
impl Message for ShutdownWebhook {
type Result = ();
}
impl Handler<ShutdownWebhook> for WebhookActor { impl Handler<ShutdownWebhook> for WebhookActor {
type Result = (); type Result = ();

View file

@ -8,15 +8,7 @@ use crate::gitforge::{self, ForgeFileError};
pub async fn load( pub async fn load(
details: &RepoDetails, details: &RepoDetails,
forge: &gitforge::Forge, forge: &gitforge::Forge,
) -> Result< ) -> Result<RepoConfig, OneOf<(ForgeFileError, crate::config::Error, toml::de::Error, Error)>> {
RepoConfig,
OneOf<(
ForgeFileError,
crate::config::Error,
toml::de::Error,
RepoConfigValidationErrors,
)>,
> {
let contents = forge let contents = forge
.file_contents_get(&details.branch, ".git-next.toml") .file_contents_get(&details.branch, ".git-next.toml")
.await .await
@ -27,42 +19,33 @@ pub async fn load(
} }
#[derive(Debug)] #[derive(Debug)]
pub enum RepoConfigValidationErrors { pub enum Error {
Forge(gitforge::ForgeBranchError), Forge(gitforge::ForgeBranchError),
BranchNotFound(BranchName), BranchNotFound(BranchName),
} }
pub async fn validate( pub async fn validate(config: RepoConfig, forge: &gitforge::Forge) -> Result<RepoConfig, Error> {
config: RepoConfig,
forge: &gitforge::Forge,
) -> Result<RepoConfig, RepoConfigValidationErrors> {
let branches = forge.branches_get_all().await.map_err(|e| { let branches = forge.branches_get_all().await.map_err(|e| {
error!(?e, "Failed to list branches"); error!(?e, "Failed to list branches");
RepoConfigValidationErrors::Forge(e) Error::Forge(e)
})?; })?;
if !branches if !branches
.iter() .iter()
.any(|branch| branch == &config.branches().main()) .any(|branch| branch == &config.branches().main())
{ {
return Err(RepoConfigValidationErrors::BranchNotFound( return Err(Error::BranchNotFound(config.branches().main()));
config.branches().main(),
));
} }
if !branches if !branches
.iter() .iter()
.any(|branch| branch == &config.branches().next()) .any(|branch| branch == &config.branches().next())
{ {
return Err(RepoConfigValidationErrors::BranchNotFound( return Err(Error::BranchNotFound(config.branches().next()));
config.branches().next(),
));
} }
if !branches if !branches
.iter() .iter()
.any(|branch| branch == &config.branches().dev()) .any(|branch| branch == &config.branches().dev())
{ {
return Err(RepoConfigValidationErrors::BranchNotFound( return Err(Error::BranchNotFound(config.branches().dev()));
config.branches().dev(),
));
} }
Ok(config) Ok(config)
} }

View file

@ -89,13 +89,8 @@ impl Webhook {
} }
/// The URL for the webhook where forges should send their updates /// The URL for the webhook where forges should send their updates
#[derive(Clone, Debug, PartialEq, Eq, serde::Deserialize)] #[derive(Clone, Debug, PartialEq, Eq, serde::Deserialize, derive_more::AsRef)]
pub struct WebhookUrl(String); pub struct WebhookUrl(String);
impl AsRef<str> for WebhookUrl {
fn as_ref(&self) -> &str {
&self.0
}
}
/// The directory to store server data, such as cloned repos /// The directory to store server data, such as cloned repos
#[derive(Clone, Debug, PartialEq, Eq, serde::Deserialize)] #[derive(Clone, Debug, PartialEq, Eq, serde::Deserialize)]

View file

@ -254,6 +254,9 @@ struct RepoCommit {
} }
impl From<Commit> for git::Commit { impl From<Commit> for git::Commit {
fn from(value: Commit) -> Self { fn from(value: Commit) -> Self {
Self::new(&value.sha, &value.commit.message) Self::new(
git::commit::Sha::new(value.sha),
git::commit::Message::new(value.commit.message),
)
} }
} }

View file

@ -59,12 +59,7 @@ impl super::ForgeLike for ForgeJoEnv {
dev, dev,
dev_commit_history, dev_commit_history,
}) => { }) => {
addr.do_send(StartMonitoring { addr.do_send(StartMonitoring::new(main, next, dev, dev_commit_history));
main,
next,
dev,
dev_commit_history,
});
} }
Err(err) => { Err(err) => {
warn!("{}", err); warn!("{}", err);

View file

@ -1,4 +1,4 @@
#[derive(Copy, Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord)] #[derive(Copy, Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord, derive_more::Display)]
pub struct MessageToken(u32); pub struct MessageToken(u32);
impl MessageToken { impl MessageToken {
pub fn new() -> Self { pub fn new() -> Self {
@ -8,8 +8,3 @@ impl MessageToken {
Self(self.0 + 1) Self(self.0 + 1)
} }
} }
impl std::fmt::Display for MessageToken {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}