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 crate::server::{
config, forge,
gitforge::{self, Force, Forge},
};
use crate::server::{config, gitforge};
// advance next to the next commit towards the head of the dev branch
#[tracing::instrument(fields(next), skip_all)]
pub async fn advance_next(
next: forge::Commit,
dev_commit_history: Vec<forge::Commit>,
next: gitforge::Commit,
dev_commit_history: Vec<gitforge::Commit>,
repo_config: config::RepoConfig,
forge: Forge,
forge: gitforge::Forge,
) {
let next_commit = find_next_commit_on_dev(next, dev_commit_history);
let Some(commit) = next_commit else {
@ -23,13 +20,17 @@ pub async fn advance_next(
return;
}
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")
}
}
#[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();
if message.to_ascii_lowercase().starts_with("wip") {
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(
next: forge::Commit,
dev_commit_history: Vec<forge::Commit>,
) -> Option<forge::Commit> {
let mut next_commit: Option<forge::Commit> = None;
next: gitforge::Commit,
dev_commit_history: Vec<gitforge::Commit>,
) -> Option<gitforge::Commit> {
let mut next_commit: Option<gitforge::Commit> = None;
for commit in dev_commit_history.into_iter() {
if commit == next {
break;
@ -63,12 +64,16 @@ fn find_next_commit_on_dev(
// advance main branch to the commit 'next'
#[tracing::instrument(fields(next), skip_all)]
pub async fn advance_main(
next: forge::Commit,
next: gitforge::Commit,
repo_config: config::RepoConfig,
forge: gitforge::Forge,
) {
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")
};
}
@ -79,13 +84,13 @@ mod tests {
#[actix_rt::test]
async fn test_find_next_commit_on_dev() {
let next = forge::Commit::new("current-next", "foo");
let expected = forge::Commit::new("dev-next", "next-should-go-here");
let next = gitforge::Commit::new("current-next", "foo");
let expected = gitforge::Commit::new("dev-next", "next-should-go-here");
let dev_commit_history = vec![
forge::Commit::new("dev", "future"),
gitforge::Commit::new("dev", "future"),
expected.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);
assert_eq!(next_commit, Some(expected));

View file

@ -10,7 +10,7 @@ use tracing::{info, warn};
use crate::server::{
actors::repo::webhook::WebhookAuth,
config::{RepoConfig, RepoDetails, Webhook},
forge, gitforge,
gitforge,
};
use self::webhook::WebhookId;
@ -20,9 +20,9 @@ pub struct RepoActor {
webhook: Webhook,
webhook_id: Option<WebhookId>, // 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_next_commit: Option<forge::Commit>,
last_dev_commit: Option<forge::Commit>,
last_main_commit: Option<gitforge::Commit>,
last_next_commit: Option<gitforge::Commit>,
last_dev_commit: Option<gitforge::Commit>,
net: Network,
forge: gitforge::Forge,
}
@ -124,10 +124,10 @@ impl Handler<ValidateRepo> for RepoActor {
#[derive(Debug, Message)]
#[rtype(result = "()")]
pub struct StartMonitoring {
pub main: forge::Commit,
pub next: forge::Commit,
pub dev: forge::Commit,
pub dev_commit_history: Vec<forge::Commit>,
pub main: gitforge::Commit,
pub next: gitforge::Commit,
pub dev: gitforge::Commit,
pub dev_commit_history: Vec<gitforge::Commit>,
}
impl Handler<StartMonitoring> for RepoActor {
type Result = ();
@ -176,7 +176,7 @@ impl Handler<WebhookRegistered> for RepoActor {
#[derive(Message)]
#[rtype(result = "()")]
pub struct AdvanceMainTo(pub forge::Commit);
pub struct AdvanceMainTo(pub gitforge::Commit);
impl Handler<AdvanceMainTo> for RepoActor {
type 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 tracing::info;
use crate::server::{actors::repo::ValidateRepo, forge, gitforge};
use crate::server::{actors::repo::ValidateRepo, gitforge};
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)
let status = forge.commit_status(&next).await;
info!(?status, "Checking next branch");

View file

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

View file

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

View file

@ -1,5 +1,3 @@
use std::fmt::{Display, Formatter};
#[cfg(feature = "forgejo")]
pub mod forgejo;
@ -7,61 +5,3 @@ pub mod forgejo;
pub mod mock;
#[cfg(test)]
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]
const fn test_is_send() {
const fn assert_send<T: Send>() {}
assert_send::<CommitHistories>();
assert_send::<NetworkError>();
assert_send::<gitforge::CommitHistories>();
assert_send::<network::NetworkError>();
}

View file

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

View file

@ -9,8 +9,7 @@ use tracing::{error, warn};
use crate::server::{
actors::repo::RepoActor,
config::{BranchName, RepoConfig, RepoDetails},
forge::Commit,
gitforge::{BranchResetResult, CommitStatus, Force, ForgeBranchError, ForgeFileError},
gitforge,
types::GitRef,
};
@ -31,7 +30,7 @@ impl super::ForgeLike for ForgeJoEnv {
"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
}
@ -39,7 +38,7 @@ impl super::ForgeLike for ForgeJoEnv {
&self,
branch: &BranchName,
file_path: &str,
) -> Result<String, ForgeFileError> {
) -> Result<String, gitforge::ForgeFileError> {
file::contents_get(&self.repo_details, &self.net, branch, file_path).await
}
@ -51,12 +50,12 @@ impl super::ForgeLike for ForgeJoEnv {
&self,
branch_name: BranchName,
to_commit: GitRef,
force: Force,
) -> BranchResetResult {
force: gitforge::Force,
) -> gitforge::BranchResetResult {
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 hostname = &repo_details.forge.hostname;
let path = &repo_details.repo;
@ -81,21 +80,21 @@ impl super::ForgeLike for ForgeJoEnv {
Ok(response) => {
match response.response_body() {
Some(status) => match status.state {
CommitStatusState::Success => CommitStatus::Pass,
CommitStatusState::Pending => CommitStatus::Pending,
CommitStatusState::Failure => CommitStatus::Fail,
CommitStatusState::Error => CommitStatus::Fail,
CommitStatusState::Blank => CommitStatus::Pending,
CommitStatusState::Success => gitforge::CommitStatus::Pass,
CommitStatusState::Pending => gitforge::CommitStatus::Pending,
CommitStatusState::Failure => gitforge::CommitStatus::Fail,
CommitStatusState::Error => gitforge::CommitStatus::Fail,
CommitStatusState::Blank => gitforge::CommitStatus::Pending,
},
None => {
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) => {
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::{
actors::repo::RepoActor,
config::{BranchName, RepoConfig},
forge::Commit,
gitforge::{BranchResetResult, CommitStatus, Force, ForgeBranchError, ForgeFileError},
gitforge,
types::GitRef,
};
@ -20,7 +19,7 @@ impl super::ForgeLike for MockForgeEnv {
"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!()
}
@ -28,7 +27,7 @@ impl super::ForgeLike for MockForgeEnv {
&self,
_branch: &BranchName,
_file_path: &str,
) -> Result<String, ForgeFileError> {
) -> Result<String, gitforge::ForgeFileError> {
todo!()
}
@ -44,12 +43,12 @@ impl super::ForgeLike for MockForgeEnv {
&self,
_branch_name: BranchName,
_to_commit: GitRef,
_force: Force,
) -> BranchResetResult {
_force: gitforge::Force,
) -> gitforge::BranchResetResult {
todo!()
}
async fn commit_status(&self, _commit: &Commit) -> CommitStatus {
async fn commit_status(&self, _commit: &gitforge::Commit) -> gitforge::CommitStatus {
todo!()
}
}

View file

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

View file

@ -27,3 +27,61 @@ pub enum CommitStatus {
Fail,
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 crate::server::{config::BranchName, forge};
use crate::server::{config::BranchName, gitforge};
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
pub struct GitRef(pub String);
impl From<forge::Commit> for GitRef {
fn from(value: forge::Commit) -> Self {
impl From<gitforge::Commit> for GitRef {
fn from(value: gitforge::Commit) -> Self {
Self(value.sha().to_string())
}
}