// Copyright (C) 2023-2099 The crate authors. // // This program is free software: you can redistribute it and/or modify it // under the terms of the GNU Affero General Public License as published by the // Free Software Foundation, either version 3 of the License, or (at your // option) any later version. // // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License // for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . mod forgejo; mod gitlab; mod types; pub use crate::hooks::forgejo::ForgejoHook; #[allow(deprecated)] pub use crate::hooks::gitlab::GitlabHook; pub use crate::hooks::types::Hook; use crate::hooks::types::{IssueAction, MergeRequestAction, WikiAction}; pub fn format_hook(hook: &Hook) -> Option { Some(match hook { Hook::Push(push) if push.object_kind == "tag_push" => { let ref_ = push.ref_.strip_prefix("refs/tags/").unwrap_or("?!"); format!( "[{}] {} pushed tag {}.", push.repository.name, push.pusher.name, ref_ ) } Hook::Push(push) => { if push.commits.len() == 0 { // Ignore: Branch got deleted return None; } let mut text = format!( "[{}] {} pushed {} commits to {}", push.repository.name, push.pusher.name, push.commits.len(), push.ref_, ); // Display max 3 commits for commit in push.commits.clone().into_iter().take(3) { match commit.message.lines().nth(0) { Some(subject) => { text = format!("{}\n• {} <{}>", text, subject, commit.url); } None => {} } } text } Hook::Issue(issue) => { let action = match issue.action { Some(IssueAction::Update) => return None, Some(IssueAction::Open) => "opened", Some(IssueAction::Close) => "closed", Some(IssueAction::Reopen) => "reopened", None => return None, }; format!( "[{}] {} {} issue {}: {}{}", issue.repository.name, issue.author.name, action, issue.id, issue.title, issue .url .as_ref() .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) = ¬e.commit { format!( "[{}] {} commented on commit {:?} <{}>", note.repository.name, note.author.name, commit.ref_, commit.url, ) } else if let Some(issue) = ¬e.issue { format!( "[{}] {} commented on issue {}: {} <{}>", note.repository.name, note.author.name, issue.id, issue.title, note.url, ) } else if let Some(mr) = ¬e.merge_request { format!( "[{}] {} commented on merge request {}: {} <{}>", note.repository.name, note.author.name, mr.id, mr.title, note.url, ) } else { unreachable!() } } Hook::Wiki(page) => { let action = match page.action { WikiAction::Update => "updated", WikiAction::Create => "created", }; format!( "[{}] {} {} wiki page {} <{}>", page.repository.name, page.author.name, action, page.title, page.url, ) } }) }