refactor(gitforge): migrate some types from forge
All checks were successful
ci/woodpecker/push/cron-docker-builder Pipeline was successful
ci/woodpecker/push/tag-created Pipeline was successful
ci/woodpecker/push/push-next Pipeline was successful

This commit is contained in:
Paul Campbell 2024-04-18 19:15:26 +01:00
parent adb44d18c9
commit 0d57ee7bc0
13 changed files with 141 additions and 138 deletions

View file

@ -1,17 +1,14 @@
use tracing::{info, warn}; use tracing::{info, warn};
use crate::server::{ use crate::server::{config, gitforge};
config, forge,
gitforge::{self, Force, Forge},
};
// advance next to the next commit towards the head of the dev branch // advance next to the next commit towards the head of the dev branch
#[tracing::instrument(fields(next), skip_all)] #[tracing::instrument(fields(next), skip_all)]
pub async fn advance_next( pub async fn advance_next(
next: forge::Commit, next: gitforge::Commit,
dev_commit_history: Vec<forge::Commit>, dev_commit_history: Vec<gitforge::Commit>,
repo_config: config::RepoConfig, repo_config: config::RepoConfig,
forge: Forge, forge: gitforge::Forge,
) { ) {
let next_commit = find_next_commit_on_dev(next, dev_commit_history); let next_commit = find_next_commit_on_dev(next, dev_commit_history);
let Some(commit) = next_commit else { let Some(commit) = next_commit else {
@ -23,13 +20,17 @@ pub async fn advance_next(
return; return;
} }
info!("Advancing next to commit '{}'", commit); info!("Advancing next to commit '{}'", commit);
if let Err(err) = forge.branch_reset(repo_config.branches().next(), commit.into(), Force::No) { if let Err(err) = forge.branch_reset(
repo_config.branches().next(),
commit.into(),
gitforge::Force::No,
) {
warn!(?err, "Failed") warn!(?err, "Failed")
} }
} }
#[tracing::instrument] #[tracing::instrument]
fn validate_commit_message(message: &forge::Message) -> Option<String> { fn validate_commit_message(message: &gitforge::Message) -> Option<String> {
let message = &message.to_string(); let message = &message.to_string();
if message.to_ascii_lowercase().starts_with("wip") { if message.to_ascii_lowercase().starts_with("wip") {
return Some("Is Work-In-Progress".to_string()); return Some("Is Work-In-Progress".to_string());
@ -47,10 +48,10 @@ fn validate_commit_message(message: &forge::Message) -> Option<String> {
} }
fn find_next_commit_on_dev( fn find_next_commit_on_dev(
next: forge::Commit, next: gitforge::Commit,
dev_commit_history: Vec<forge::Commit>, dev_commit_history: Vec<gitforge::Commit>,
) -> Option<forge::Commit> { ) -> Option<gitforge::Commit> {
let mut next_commit: Option<forge::Commit> = None; let mut next_commit: Option<gitforge::Commit> = None;
for commit in dev_commit_history.into_iter() { for commit in dev_commit_history.into_iter() {
if commit == next { if commit == next {
break; break;
@ -63,12 +64,16 @@ fn find_next_commit_on_dev(
// advance main branch to the commit 'next' // advance main branch to the commit 'next'
#[tracing::instrument(fields(next), skip_all)] #[tracing::instrument(fields(next), skip_all)]
pub async fn advance_main( pub async fn advance_main(
next: forge::Commit, next: gitforge::Commit,
repo_config: config::RepoConfig, repo_config: config::RepoConfig,
forge: gitforge::Forge, forge: gitforge::Forge,
) { ) {
info!("Advancing main to next"); info!("Advancing main to next");
if let Err(err) = forge.branch_reset(repo_config.branches().main(), next.into(), Force::No) { if let Err(err) = forge.branch_reset(
repo_config.branches().main(),
next.into(),
gitforge::Force::No,
) {
warn!(?err, "Failed") warn!(?err, "Failed")
}; };
} }
@ -79,13 +84,13 @@ mod tests {
#[actix_rt::test] #[actix_rt::test]
async fn test_find_next_commit_on_dev() { async fn test_find_next_commit_on_dev() {
let next = forge::Commit::new("current-next", "foo"); let next = gitforge::Commit::new("current-next", "foo");
let expected = forge::Commit::new("dev-next", "next-should-go-here"); let expected = gitforge::Commit::new("dev-next", "next-should-go-here");
let dev_commit_history = vec![ let dev_commit_history = vec![
forge::Commit::new("dev", "future"), gitforge::Commit::new("dev", "future"),
expected.clone(), expected.clone(),
next.clone(), next.clone(),
forge::Commit::new("current-main", "history"), gitforge::Commit::new("current-main", "history"),
]; ];
let next_commit = find_next_commit_on_dev(next, dev_commit_history); let next_commit = find_next_commit_on_dev(next, dev_commit_history);
assert_eq!(next_commit, Some(expected)); assert_eq!(next_commit, Some(expected));

View file

@ -10,7 +10,7 @@ use tracing::{info, warn};
use crate::server::{ use crate::server::{
actors::repo::webhook::WebhookAuth, actors::repo::webhook::WebhookAuth,
config::{RepoConfig, RepoDetails, Webhook}, config::{RepoConfig, RepoDetails, Webhook},
forge, gitforge, gitforge,
}; };
use self::webhook::WebhookId; use self::webhook::WebhookId;
@ -20,9 +20,9 @@ pub struct RepoActor {
webhook: Webhook, webhook: Webhook,
webhook_id: Option<WebhookId>, // INFO: if [None] then no webhook is configured webhook_id: Option<WebhookId>, // INFO: if [None] then no webhook is configured
webhook_auth: Option<WebhookAuth>, // INFO: if [None] then no webhook is configured webhook_auth: Option<WebhookAuth>, // INFO: if [None] then no webhook is configured
last_main_commit: Option<forge::Commit>, last_main_commit: Option<gitforge::Commit>,
last_next_commit: Option<forge::Commit>, last_next_commit: Option<gitforge::Commit>,
last_dev_commit: Option<forge::Commit>, last_dev_commit: Option<gitforge::Commit>,
net: Network, net: Network,
forge: gitforge::Forge, forge: gitforge::Forge,
} }
@ -124,10 +124,10 @@ impl Handler<ValidateRepo> for RepoActor {
#[derive(Debug, Message)] #[derive(Debug, Message)]
#[rtype(result = "()")] #[rtype(result = "()")]
pub struct StartMonitoring { pub struct StartMonitoring {
pub main: forge::Commit, pub main: gitforge::Commit,
pub next: forge::Commit, pub next: gitforge::Commit,
pub dev: forge::Commit, pub dev: gitforge::Commit,
pub dev_commit_history: Vec<forge::Commit>, pub dev_commit_history: Vec<gitforge::Commit>,
} }
impl Handler<StartMonitoring> for RepoActor { impl Handler<StartMonitoring> for RepoActor {
type Result = (); type Result = ();
@ -176,7 +176,7 @@ impl Handler<WebhookRegistered> for RepoActor {
#[derive(Message)] #[derive(Message)]
#[rtype(result = "()")] #[rtype(result = "()")]
pub struct AdvanceMainTo(pub forge::Commit); pub struct AdvanceMainTo(pub gitforge::Commit);
impl Handler<AdvanceMainTo> for RepoActor { impl Handler<AdvanceMainTo> for RepoActor {
type Result = (); type Result = ();
fn handle(&mut self, msg: AdvanceMainTo, ctx: &mut Self::Context) -> Self::Result { fn handle(&mut self, msg: AdvanceMainTo, ctx: &mut Self::Context) -> Self::Result {

View file

@ -2,11 +2,15 @@ use actix::prelude::*;
use gix::trace::warn; use gix::trace::warn;
use tracing::info; use tracing::info;
use crate::server::{actors::repo::ValidateRepo, forge, gitforge}; use crate::server::{actors::repo::ValidateRepo, gitforge};
use super::AdvanceMainTo; use super::AdvanceMainTo;
pub async fn check_next(next: forge::Commit, addr: Addr<super::RepoActor>, forge: gitforge::Forge) { pub async fn check_next(
next: gitforge::Commit,
addr: Addr<super::RepoActor>,
forge: gitforge::Forge,
) {
// get the status - pass, fail, pending (all others map to fail, e.g. error) // get the status - pass, fail, pending (all others map to fail, e.g. error)
let status = forge.commit_status(&next).await; let status = forge.commit_status(&next).await;
info!(?status, "Checking next branch"); info!(?status, "Checking next branch");

View file

@ -11,7 +11,7 @@ use crate::server::{
webhook::WebhookMessage, webhook::WebhookMessage,
}, },
config::{RepoBranches, Webhook, WebhookUrl}, config::{RepoBranches, Webhook, WebhookUrl},
forge, gitforge,
}; };
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq)]
@ -298,8 +298,8 @@ impl Push {
warn!(branch, "Unexpected branch"); warn!(branch, "Unexpected branch");
None None
} }
pub fn commit(&self) -> forge::Commit { pub fn commit(&self) -> gitforge::Commit {
forge::Commit::new(&self.after, &self.head_commit.message) gitforge::Commit::new(&self.after, &self.head_commit.message)
} }
} }

View file

@ -1,7 +1,7 @@
use kxio::network; use kxio::network;
use secrecy::ExposeSecret; use secrecy::ExposeSecret;
use crate::server::{self, config::BranchName, forge}; use crate::server::{self, config::BranchName, gitforge};
pub mod config; pub mod config;
@ -9,9 +9,9 @@ pub mod config;
async fn get_commit_history( async fn get_commit_history(
repo_details: &server::config::RepoDetails, repo_details: &server::config::RepoDetails,
branch_name: &BranchName, branch_name: &BranchName,
find_commits: Vec<forge::Commit>, find_commits: Vec<gitforge::Commit>,
net: &kxio::network::Network, net: &kxio::network::Network,
) -> Result<Vec<forge::Commit>, network::NetworkError> { ) -> Result<Vec<gitforge::Commit>, network::NetworkError> {
let hostname = &repo_details.forge.hostname; let hostname = &repo_details.forge.hostname;
let path = &repo_details.repo; let path = &repo_details.repo;
@ -42,7 +42,7 @@ async fn get_commit_history(
.response_body() .response_body()
.unwrap_or_default() .unwrap_or_default()
.into_iter() .into_iter()
.map(forge::Commit::from) .map(gitforge::Commit::from)
.collect::<Vec<_>>(); .collect::<Vec<_>>();
let found = find_commits.is_empty() let found = find_commits.is_empty()
@ -72,7 +72,7 @@ struct Commit {
struct RepoCommit { struct RepoCommit {
message: String, message: String,
} }
impl From<Commit> for forge::Commit { impl From<Commit> for gitforge::Commit {
fn from(value: Commit) -> Self { fn from(value: Commit) -> Self {
Self::new(&value.sha, &value.commit.message) Self::new(&value.sha, &value.commit.message)
} }

View file

@ -1,5 +1,3 @@
use std::fmt::{Display, Formatter};
#[cfg(feature = "forgejo")] #[cfg(feature = "forgejo")]
pub mod forgejo; pub mod forgejo;
@ -7,61 +5,3 @@ pub mod forgejo;
pub mod mock; pub mod mock;
#[cfg(test)] #[cfg(test)]
mod tests; mod tests;
#[derive(Clone, Debug)]
pub struct CommitHistories {
pub main: Vec<Commit>,
pub next: Vec<Commit>,
pub dev: Vec<Commit>,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Commit {
sha: Sha,
message: Message,
}
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 {
&self.sha
}
pub const fn message(&self) -> &Message {
&self.message
}
}
impl Display for Commit {
fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
write!(f, "{}", self.sha)
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Sha(String);
impl Sha {
pub const fn new(value: String) -> Self {
Self(value)
}
}
impl Display for Sha {
fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Message(String);
impl Message {
pub const fn new(value: String) -> Self {
Self(value)
}
}
impl Display for Message {
fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}

View file

@ -1,10 +1,10 @@
use kxio::network::NetworkError; use kxio::network;
use crate::server::forge::CommitHistories; use crate::server::gitforge;
#[test] #[test]
const fn test_is_send() { const fn test_is_send() {
const fn assert_send<T: Send>() {} const fn assert_send<T: Send>() {}
assert_send::<CommitHistories>(); assert_send::<gitforge::CommitHistories>();
assert_send::<NetworkError>(); assert_send::<network::NetworkError>();
} }

View file

@ -7,12 +7,11 @@ use crate::server::{
self, self,
actors::repo::{RepoActor, StartMonitoring}, actors::repo::{RepoActor, StartMonitoring},
config::{BranchName, RepoConfig, RepoDetails}, config::{BranchName, RepoConfig, RepoDetails},
forge, gitforge::{self, ForgeLike},
gitforge::{forgejo::ForgeJoEnv, Force, ForgeLike},
}; };
pub async fn validate_positions( pub async fn validate_positions(
forge: &ForgeJoEnv, forge: &gitforge::forgejo::ForgeJoEnv,
repo_config: RepoConfig, repo_config: RepoConfig,
addr: Addr<RepoActor>, addr: Addr<RepoActor>,
) { ) {
@ -49,7 +48,7 @@ pub async fn validate_positions(
if let Err(err) = forge.branch_reset( if let Err(err) = forge.branch_reset(
repo_config.branches().next(), repo_config.branches().next(),
main.into(), main.into(),
Force::From(next.into()), gitforge::Force::From(next.into()),
) { ) {
warn!(?err, "Failed to reset next to main"); warn!(?err, "Failed to reset next to main");
} }
@ -70,7 +69,7 @@ pub async fn validate_positions(
if let Err(err) = forge.branch_reset( if let Err(err) = forge.branch_reset(
repo_config.branches().next(), repo_config.branches().next(),
main.into(), main.into(),
Force::From(next.into()), gitforge::Force::From(next.into()),
) { ) {
warn!(?err, "Failed to reset next to main"); warn!(?err, "Failed to reset next to main");
} }
@ -124,7 +123,7 @@ async fn get_commit_histories(
repo_details: &RepoDetails, repo_details: &RepoDetails,
repo_config: &RepoConfig, repo_config: &RepoConfig,
net: &network::Network, net: &network::Network,
) -> Result<forge::CommitHistories, network::NetworkError> { ) -> Result<gitforge::CommitHistories, network::NetworkError> {
let main = let main =
(get_commit_history(repo_details, &repo_config.branches().main(), vec![], net).await)?; (get_commit_history(repo_details, &repo_config.branches().main(), vec![], net).await)?;
let main_head = main[0].clone(); let main_head = main[0].clone();
@ -149,7 +148,7 @@ async fn get_commit_histories(
dev = dev.len(), dev = dev.len(),
"Commit histories" "Commit histories"
); );
let histories = forge::CommitHistories { main, next, dev }; let histories = gitforge::CommitHistories { main, next, dev };
Ok(histories) Ok(histories)
} }
@ -157,9 +156,9 @@ async fn get_commit_histories(
async fn get_commit_history( async fn get_commit_history(
repo_details: &server::config::RepoDetails, repo_details: &server::config::RepoDetails,
branch_name: &BranchName, branch_name: &BranchName,
find_commits: Vec<forge::Commit>, find_commits: Vec<gitforge::Commit>,
net: &kxio::network::Network, net: &kxio::network::Network,
) -> Result<Vec<forge::Commit>, network::NetworkError> { ) -> Result<Vec<gitforge::Commit>, network::NetworkError> {
let hostname = &repo_details.forge.hostname; let hostname = &repo_details.forge.hostname;
let path = &repo_details.repo; let path = &repo_details.repo;
@ -192,7 +191,7 @@ async fn get_commit_history(
.response_body() .response_body()
.unwrap_or_default() .unwrap_or_default()
.into_iter() .into_iter()
.map(forge::Commit::from) .map(gitforge::Commit::from)
.collect::<Vec<_>>(); .collect::<Vec<_>>();
let found = find_commits.is_empty() let found = find_commits.is_empty()
@ -222,7 +221,7 @@ struct Commit {
struct RepoCommit { struct RepoCommit {
message: String, message: String,
} }
impl From<Commit> for forge::Commit { impl From<Commit> for gitforge::Commit {
fn from(value: Commit) -> Self { fn from(value: Commit) -> Self {
Self::new(&value.sha, &value.commit.message) Self::new(&value.sha, &value.commit.message)
} }

View file

@ -9,8 +9,7 @@ use tracing::{error, warn};
use crate::server::{ use crate::server::{
actors::repo::RepoActor, actors::repo::RepoActor,
config::{BranchName, RepoConfig, RepoDetails}, config::{BranchName, RepoConfig, RepoDetails},
forge::Commit, gitforge,
gitforge::{BranchResetResult, CommitStatus, Force, ForgeBranchError, ForgeFileError},
types::GitRef, types::GitRef,
}; };
@ -31,7 +30,7 @@ impl super::ForgeLike for ForgeJoEnv {
"forgejo".to_string() "forgejo".to_string()
} }
async fn branches_get_all(&self) -> Result<Vec<super::Branch>, ForgeBranchError> { async fn branches_get_all(&self) -> Result<Vec<super::Branch>, gitforge::ForgeBranchError> {
branch::get_all(&self.repo_details, &self.net).await branch::get_all(&self.repo_details, &self.net).await
} }
@ -39,7 +38,7 @@ impl super::ForgeLike for ForgeJoEnv {
&self, &self,
branch: &BranchName, branch: &BranchName,
file_path: &str, file_path: &str,
) -> Result<String, ForgeFileError> { ) -> Result<String, gitforge::ForgeFileError> {
file::contents_get(&self.repo_details, &self.net, branch, file_path).await file::contents_get(&self.repo_details, &self.net, branch, file_path).await
} }
@ -51,12 +50,12 @@ impl super::ForgeLike for ForgeJoEnv {
&self, &self,
branch_name: BranchName, branch_name: BranchName,
to_commit: GitRef, to_commit: GitRef,
force: Force, force: gitforge::Force,
) -> BranchResetResult { ) -> gitforge::BranchResetResult {
branch::reset(&self.repo_details, branch_name, to_commit, force) branch::reset(&self.repo_details, branch_name, to_commit, force)
} }
async fn commit_status(&self, commit: &Commit) -> CommitStatus { async fn commit_status(&self, commit: &gitforge::Commit) -> gitforge::CommitStatus {
let repo_details = &self.repo_details; let repo_details = &self.repo_details;
let hostname = &repo_details.forge.hostname; let hostname = &repo_details.forge.hostname;
let path = &repo_details.repo; let path = &repo_details.repo;
@ -81,21 +80,21 @@ impl super::ForgeLike for ForgeJoEnv {
Ok(response) => { Ok(response) => {
match response.response_body() { match response.response_body() {
Some(status) => match status.state { Some(status) => match status.state {
CommitStatusState::Success => CommitStatus::Pass, CommitStatusState::Success => gitforge::CommitStatus::Pass,
CommitStatusState::Pending => CommitStatus::Pending, CommitStatusState::Pending => gitforge::CommitStatus::Pending,
CommitStatusState::Failure => CommitStatus::Fail, CommitStatusState::Failure => gitforge::CommitStatus::Fail,
CommitStatusState::Error => CommitStatus::Fail, CommitStatusState::Error => gitforge::CommitStatus::Fail,
CommitStatusState::Blank => CommitStatus::Pending, CommitStatusState::Blank => gitforge::CommitStatus::Pending,
}, },
None => { None => {
warn!("No status found for commit"); warn!("No status found for commit");
CommitStatus::Pending // assume issue is transient and allow retry gitforge::CommitStatus::Pending // assume issue is transient and allow retry
} }
} }
} }
Err(e) => { Err(e) => {
error!(?e, "Failed to get commit status"); error!(?e, "Failed to get commit status");
CommitStatus::Pending // assume issue is transient and allow retry gitforge::CommitStatus::Pending // assume issue is transient and allow retry
} }
} }
} }

View file

@ -1,8 +1,7 @@
use crate::server::{ use crate::server::{
actors::repo::RepoActor, actors::repo::RepoActor,
config::{BranchName, RepoConfig}, config::{BranchName, RepoConfig},
forge::Commit, gitforge,
gitforge::{BranchResetResult, CommitStatus, Force, ForgeBranchError, ForgeFileError},
types::GitRef, types::GitRef,
}; };
@ -20,7 +19,7 @@ impl super::ForgeLike for MockForgeEnv {
"mock".to_string() "mock".to_string()
} }
async fn branches_get_all(&self) -> Result<Vec<super::Branch>, ForgeBranchError> { async fn branches_get_all(&self) -> Result<Vec<super::Branch>, gitforge::ForgeBranchError> {
todo!() todo!()
} }
@ -28,7 +27,7 @@ impl super::ForgeLike for MockForgeEnv {
&self, &self,
_branch: &BranchName, _branch: &BranchName,
_file_path: &str, _file_path: &str,
) -> Result<String, ForgeFileError> { ) -> Result<String, gitforge::ForgeFileError> {
todo!() todo!()
} }
@ -44,12 +43,12 @@ impl super::ForgeLike for MockForgeEnv {
&self, &self,
_branch_name: BranchName, _branch_name: BranchName,
_to_commit: GitRef, _to_commit: GitRef,
_force: Force, _force: gitforge::Force,
) -> BranchResetResult { ) -> gitforge::BranchResetResult {
todo!() todo!()
} }
async fn commit_status(&self, _commit: &Commit) -> CommitStatus { async fn commit_status(&self, _commit: &gitforge::Commit) -> gitforge::CommitStatus {
todo!() todo!()
} }
} }

View file

@ -18,7 +18,6 @@ pub use errors::*;
use crate::server::{ use crate::server::{
config::{BranchName, RepoConfig, RepoDetails}, config::{BranchName, RepoConfig, RepoDetails},
forge::Commit,
types::GitRef, types::GitRef,
}; };

View file

@ -27,3 +27,61 @@ pub enum CommitStatus {
Fail, Fail,
Pending, Pending,
} }
#[derive(Clone, Debug)]
pub struct CommitHistories {
pub main: Vec<Commit>,
pub next: Vec<Commit>,
pub dev: Vec<Commit>,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Commit {
sha: Sha,
message: Message,
}
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 {
&self.sha
}
pub const fn message(&self) -> &Message {
&self.message
}
}
impl std::fmt::Display for Commit {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{}", self.sha)
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Sha(String);
impl Sha {
pub const fn new(value: String) -> Self {
Self(value)
}
}
impl std::fmt::Display for Sha {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Message(String);
impl Message {
pub const fn new(value: String) -> Self {
Self(value)
}
}
impl std::fmt::Display for Message {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}

View file

@ -1,11 +1,11 @@
use std::fmt::Display; use std::fmt::Display;
use crate::server::{config::BranchName, forge}; use crate::server::{config::BranchName, gitforge};
#[derive(Clone, Debug, Hash, PartialEq, Eq)] #[derive(Clone, Debug, Hash, PartialEq, Eq)]
pub struct GitRef(pub String); pub struct GitRef(pub String);
impl From<forge::Commit> for GitRef { impl From<gitforge::Commit> for GitRef {
fn from(value: forge::Commit) -> Self { fn from(value: gitforge::Commit) -> Self {
Self(value.sha().to_string()) Self(value.sha().to_string())
} }
} }