Readd support for Gitlab's NoteHook

Trying to reuse other converters so that we don't have to redo all the
work

Signed-off-by: Maxime “pep” Buquet <pep@bouah.net>
This commit is contained in:
Maxime “pep” Buquet 2024-08-31 22:16:19 +02:00 committed by pep
parent 6e6ed92026
commit b281cf8b44

View file

@ -17,7 +17,10 @@ use crate::Error;
pub use forgejo_hooks::Hook as ForgejoHook; pub use forgejo_hooks::Hook as ForgejoHook;
pub use gitlab::webhooks::{ pub use gitlab::webhooks::{
IssueAction as GlIssueAction, MergeRequestAction, WebHook as GitlabHook, WikiPageAction, CommitHookAttrs, IssueAction as GlIssueAction, IssueHook as GlIssueHook,
IssueHookAttrs as GlIssueHookAttrs, MergeRequestAction as GlMergeRequestAction,
MergeRequestHook as GlMergeRequestHook, MergeRequestHookAttrs as GlMergeRequestHookAttrs,
NoteHook as GlNoteHook, PushHook as GlPushHook, WebHook as GitlabHook, WikiPageAction,
}; };
use log::debug; use log::debug;
@ -30,6 +33,8 @@ pub(crate) struct User {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub(crate) struct Commit { pub(crate) struct Commit {
/// Reference of the commit
ref_: String,
/// Commit message /// Commit message
message: String, message: String,
/// URL where the commit can be read at /// URL where the commit can be read at
@ -74,6 +79,52 @@ pub(crate) struct Issue {
url: Option<String>, url: Option<String>,
} }
#[derive(Debug, Clone)]
pub(crate) struct IssueAttrs {
id: u64,
title: String,
}
#[derive(Debug, Clone)]
pub(crate) enum MergeRequestAction {
Update,
Open,
Close,
Reopen,
Merge,
Approved,
Unapproved,
Approval,
Unapproval,
}
#[derive(Debug, Clone)]
pub(crate) struct MergeRequest {
action: Option<MergeRequestAction>,
repository: Repository,
author: User,
id: u64,
title: String,
url: Option<String>,
}
#[derive(Debug, Clone)]
pub(crate) struct MergeRequestAttrs {
id: u64,
title: String,
}
#[derive(Debug, Clone)]
pub(crate) struct Note {
snippet: bool,
commit: Option<Commit>,
issue: Option<IssueAttrs>,
merge_request: Option<MergeRequestAttrs>,
repository: Repository,
author: User,
url: String,
}
/// Lowest common denominator struct so that we don't have to duplicate our code for each platform /// Lowest common denominator struct so that we don't have to duplicate our code for each platform
/// we support. /// we support.
#[derive(Debug)] #[derive(Debug)]
@ -81,6 +132,131 @@ pub(crate) enum Hook {
/// Push event /// Push event
Push(Push), Push(Push),
Issue(Issue), Issue(Issue),
MergeRequest(MergeRequest),
Note(Note),
}
impl From<CommitHookAttrs> for Commit {
fn from(other: CommitHookAttrs) -> Commit {
Commit {
ref_: other.id,
message: other.message,
url: other.url,
}
}
}
impl From<GlPushHook> for Push {
fn from(other: GlPushHook) -> Push {
Push {
ref_: other.ref_,
object_kind: other.object_kind,
commits: other.commits.into_iter().map(Into::into).collect(),
repository: Repository {
name: other.project.name,
},
pusher: User {
name: other.user_name,
},
}
}
}
impl From<GlIssueAction> for IssueAction {
fn from(other: GlIssueAction) -> IssueAction {
match other {
GlIssueAction::Update => IssueAction::Update,
GlIssueAction::Open => IssueAction::Open,
GlIssueAction::Close => IssueAction::Close,
GlIssueAction::Reopen => IssueAction::Reopen,
}
}
}
impl From<GlIssueHook> for Issue {
fn from(other: GlIssueHook) -> Issue {
Issue {
action: other.object_attributes.action.map(Into::into),
repository: Repository {
name: other.project.name,
},
author: User {
name: other.user.name,
},
id: other.object_attributes.iid,
title: other.object_attributes.title,
url: other.object_attributes.url,
}
}
}
impl From<GlIssueHookAttrs> for IssueAttrs {
fn from(other: GlIssueHookAttrs) -> IssueAttrs {
IssueAttrs {
id: other.iid,
title: other.title,
}
}
}
impl From<GlMergeRequestAction> for MergeRequestAction {
fn from(other: GlMergeRequestAction) -> MergeRequestAction {
match other {
GlMergeRequestAction::Update => MergeRequestAction::Update,
GlMergeRequestAction::Open => MergeRequestAction::Open,
GlMergeRequestAction::Close => MergeRequestAction::Close,
GlMergeRequestAction::Reopen => MergeRequestAction::Reopen,
GlMergeRequestAction::Merge => MergeRequestAction::Merge,
GlMergeRequestAction::Approved => MergeRequestAction::Approved,
GlMergeRequestAction::Unapproved => MergeRequestAction::Unapproved,
GlMergeRequestAction::Approval => MergeRequestAction::Approval,
GlMergeRequestAction::Unapproval => MergeRequestAction::Unapproval,
}
}
}
impl From<GlMergeRequestHook> for MergeRequest {
fn from(other: GlMergeRequestHook) -> MergeRequest {
MergeRequest {
action: other.object_attributes.action.map(Into::into),
repository: Repository {
name: other.project.name,
},
author: User {
name: other.user.name,
},
id: other.object_attributes.iid,
title: other.object_attributes.title,
url: other.object_attributes.url,
}
}
}
impl From<GlMergeRequestHookAttrs> for MergeRequestAttrs {
fn from(other: GlMergeRequestHookAttrs) -> MergeRequestAttrs {
MergeRequestAttrs {
id: other.id,
title: other.title,
}
}
}
impl From<GlNoteHook> for Note {
fn from(other: GlNoteHook) -> Note {
Note {
snippet: other.snippet.is_some(),
commit: other.commit.map(Into::into),
issue: other.issue.map(Into::into),
merge_request: other.merge_request.map(Into::into),
repository: Repository {
name: other.project.name,
},
author: User {
name: other.user.name,
},
url: other.object_attributes.url,
}
}
} }
impl TryFrom<GitlabHook> for Hook { impl TryFrom<GitlabHook> for Hook {
@ -88,41 +264,10 @@ impl TryFrom<GitlabHook> for Hook {
fn try_from(hook: GitlabHook) -> Result<Hook, Error> { fn try_from(hook: GitlabHook) -> Result<Hook, Error> {
Ok(match hook { Ok(match hook {
GitlabHook::Push(push) => Hook::Push(Push { GitlabHook::Push(push) => Hook::Push((*push).into()),
ref_: push.ref_, GitlabHook::Issue(issue) => Hook::Issue((*issue).into()),
object_kind: push.object_kind, GitlabHook::MergeRequest(mr) => Hook::MergeRequest((*mr).into()),
commits: push GitlabHook::Note(note) => Hook::Note((*note).into()),
.commits
.into_iter()
.map(|commit| Commit {
message: commit.message,
url: commit.url,
})
.collect(),
repository: Repository {
name: push.project.name,
},
pusher: User {
name: push.user_name,
},
}),
GitlabHook::Issue(issue) => Hook::Issue(Issue {
action: issue.object_attributes.action.map(|action| match action {
GlIssueAction::Update => IssueAction::Update,
GlIssueAction::Open => IssueAction::Open,
GlIssueAction::Close => IssueAction::Close,
GlIssueAction::Reopen => IssueAction::Reopen,
}),
repository: Repository {
name: issue.project.name,
},
author: User {
name: issue.user.name,
},
id: issue.object_attributes.iid,
title: issue.object_attributes.title,
url: issue.object_attributes.url,
}),
_ => return Err(Error::UnsupportedHookConversion), _ => return Err(Error::UnsupportedHookConversion),
}) })
} }
@ -140,6 +285,7 @@ impl TryFrom<ForgejoHook> for Hook {
.commits .commits
.into_iter() .into_iter()
.map(|commit| Commit { .map(|commit| Commit {
ref_: commit.id,
message: commit.message, message: commit.message,
url: commit.url, url: commit.url,
}) })
@ -213,9 +359,9 @@ pub(crate) fn format_hook(hook: &Hook) -> Option<String> {
.map(|url| format!(" <{}>", url)) .map(|url| format!(" <{}>", url))
.unwrap_or("".to_owned()) .unwrap_or("".to_owned())
) )
} /* }
Hook::MergeRequest(merge_req) => { Hook::MergeRequest(merge_req) => {
let action = match merge_req.object_attributes.action { let action = match merge_req.action {
Some(MergeRequestAction::Update) => return None, Some(MergeRequestAction::Update) => return None,
Some(MergeRequestAction::Open) => "opened", Some(MergeRequestAction::Open) => "opened",
Some(MergeRequestAction::Close) => "closed", Some(MergeRequestAction::Close) => "closed",
@ -223,22 +369,18 @@ pub(crate) fn format_hook(hook: &Hook) -> Option<String> {
Some(MergeRequestAction::Merge) => "merged", Some(MergeRequestAction::Merge) => "merged",
None => return None, None => return None,
_ => { _ => {
log::warn!( log::warn!("Unsupported merge request action: {:?}", merge_req.action);
"Unsupported merge request action: {:?}",
merge_req.object_attributes.action
);
return None; return None;
} }
}; };
format!( format!(
"[{}] {} {} merge request {}: {}{}", "[{}] {} {} merge request {}: {}{}",
merge_req.project.name, merge_req.repository.name,
merge_req.user.name, merge_req.author.name,
action, action,
merge_req.object_attributes.iid, merge_req.id,
merge_req.object_attributes.title, merge_req.title,
merge_req merge_req
.object_attributes
.url .url
.as_ref() .as_ref()
.map(|url| format!(" <{}>", url)) .map(|url| format!(" <{}>", url))
@ -246,32 +388,28 @@ pub(crate) fn format_hook(hook: &Hook) -> Option<String> {
) )
} }
Hook::Note(note) => { Hook::Note(note) => {
if let Some(_) = note.snippet { if note.snippet {
return None; return None;
} }
if let Some(commit) = &note.commit { if let Some(commit) = &note.commit {
format!( format!(
"[{}] {} commented on commit {:?} <{}>", "[{}] {} commented on commit {:?} <{}>",
note.project.name, note.user.name, commit.id, commit.url, note.repository.name, note.author.name, commit.ref_, commit.url,
) )
} else if let Some(issue) = &note.issue { } else if let Some(issue) = &note.issue {
format!( format!(
"[{}] {} commented on issue {}: {} <{}>", "[{}] {} commented on issue {}: {} <{}>",
note.project.name, note.repository.name, note.author.name, issue.id, issue.title, note.url,
note.user.name,
issue.iid,
issue.title,
note.object_attributes.url,
) )
} else if let Some(mr) = &note.merge_request { } else if let Some(mr) = &note.merge_request {
format!( format!(
"[{}] {} commented on merge request {}: {} <{}>", "[{}] {} commented on merge request {}: {} <{}>",
note.project.name, note.user.name, mr.iid, mr.title, note.object_attributes.url, note.repository.name, note.author.name, mr.id, mr.title, note.url,
) )
} else { } else {
unreachable!() unreachable!()
} }
} } /*
Hook::Build(build) => { Hook::Build(build) => {
println!("Build: {:?}", build); println!("Build: {:?}", build);
return None; return None;