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 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;
@ -30,6 +33,8 @@ pub(crate) struct User {
#[derive(Debug, Clone)]
pub(crate) struct Commit {
/// Reference of the commit
ref_: String,
/// Commit message
message: String,
/// URL where the commit can be read at
@ -74,6 +79,52 @@ pub(crate) struct Issue {
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
/// we support.
#[derive(Debug)]
@ -81,6 +132,131 @@ pub(crate) enum Hook {
/// Push event
Push(Push),
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 {
@ -88,41 +264,10 @@ impl TryFrom<GitlabHook> for Hook {
fn try_from(hook: GitlabHook) -> Result<Hook, Error> {
Ok(match hook {
GitlabHook::Push(push) => Hook::Push(Push {
ref_: push.ref_,
object_kind: push.object_kind,
commits: push
.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,
}),
GitlabHook::Push(push) => Hook::Push((*push).into()),
GitlabHook::Issue(issue) => Hook::Issue((*issue).into()),
GitlabHook::MergeRequest(mr) => Hook::MergeRequest((*mr).into()),
GitlabHook::Note(note) => Hook::Note((*note).into()),
_ => return Err(Error::UnsupportedHookConversion),
})
}
@ -140,6 +285,7 @@ impl TryFrom<ForgejoHook> for Hook {
.commits
.into_iter()
.map(|commit| Commit {
ref_: commit.id,
message: commit.message,
url: commit.url,
})
@ -213,66 +359,58 @@ pub(crate) fn format_hook(hook: &Hook) -> Option<String> {
.map(|url| format!(" <{}>", url))
.unwrap_or("".to_owned())
)
}
Hook::MergeRequest(merge_req) => {
let action = match merge_req.action {
Some(MergeRequestAction::Update) => return None,
Some(MergeRequestAction::Open) => "opened",
Some(MergeRequestAction::Close) => "closed",
Some(MergeRequestAction::Reopen) => "reopened",
Some(MergeRequestAction::Merge) => "merged",
None => return None,
_ => {
log::warn!("Unsupported merge request action: {:?}", merge_req.action);
return None;
}
};
format!(
"[{}] {} {} merge request {}: {}{}",
merge_req.repository.name,
merge_req.author.name,
action,
merge_req.id,
merge_req.title,
merge_req
.url
.as_ref()
.map(|url| format!(" <{}>", url))
.unwrap_or("".to_owned())
)
}
Hook::Note(note) => {
if note.snippet {
return None;
}
if let Some(commit) = &note.commit {
format!(
"[{}] {} commented on commit {:?} <{}>",
note.repository.name, note.author.name, commit.ref_, commit.url,
)
} else if let Some(issue) = &note.issue {
format!(
"[{}] {} commented on issue {}: {} <{}>",
note.repository.name, note.author.name, issue.id, issue.title, note.url,
)
} else if let Some(mr) = &note.merge_request {
format!(
"[{}] {} commented on merge request {}: {} <{}>",
note.repository.name, note.author.name, mr.id, mr.title, note.url,
)
} else {
unreachable!()
}
} /*
Hook::MergeRequest(merge_req) => {
let action = match merge_req.object_attributes.action {
Some(MergeRequestAction::Update) => return None,
Some(MergeRequestAction::Open) => "opened",
Some(MergeRequestAction::Close) => "closed",
Some(MergeRequestAction::Reopen) => "reopened",
Some(MergeRequestAction::Merge) => "merged",
None => return None,
_ => {
log::warn!(
"Unsupported merge request action: {:?}",
merge_req.object_attributes.action
);
return None;
}
};
format!(
"[{}] {} {} merge request {}: {}{}",
merge_req.project.name,
merge_req.user.name,
action,
merge_req.object_attributes.iid,
merge_req.object_attributes.title,
merge_req
.object_attributes
.url
.as_ref()
.map(|url| format!(" <{}>", url))
.unwrap_or("".to_owned())
)
}
Hook::Note(note) => {
if let Some(_) = note.snippet {
return None;
}
if let Some(commit) = &note.commit {
format!(
"[{}] {} commented on commit {:?} <{}>",
note.project.name, note.user.name, commit.id, commit.url,
)
} else if let Some(issue) = &note.issue {
format!(
"[{}] {} commented on issue {}: {} <{}>",
note.project.name,
note.user.name,
issue.iid,
issue.title,
note.object_attributes.url,
)
} else if let Some(mr) = &note.merge_request {
format!(
"[{}] {} commented on merge request {}: {} <{}>",
note.project.name, note.user.name, mr.iid, mr.title, note.object_attributes.url,
)
} else {
unreachable!()
}
}
Hook::Build(build) => {
Hook::Build(build) => {
println!("Build: {:?}", build);
return None;
}