An update will be applied December 9th, between 12PM and 1:00PM EST (UTC -5:00). The site may be slow during that time.

Commit d50d8ca0 authored by Ben Boeckel's avatar Ben Boeckel
Browse files

webhooks: add data structures for webhooks

parent 8dbe1e04
......@@ -16,6 +16,7 @@ pub fn main() {
let out_dir = env::var_os("OUT_DIR").unwrap();
let paths = [
"types",
"webhooks",
];
for path in &paths {
......
......@@ -22,6 +22,7 @@ mod gitlab;
#[macro_use]
mod macros;
pub mod types;
pub mod webhooks;
pub use error::Error;
pub use gitlab::Gitlab;
......
// Copyright 2016 Kitware, Inc.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
include!(concat!(env!("OUT_DIR"), "/webhooks.rs"));
// Copyright 2016 Kitware, Inc.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
extern crate chrono;
use self::chrono::{DateTime, UTC};
extern crate serde;
use self::serde::{Deserialize, Deserializer, Serialize, Serializer};
use self::serde::de::{Error, Type};
extern crate serde_json;
use self::serde_json::Value;
use super::types::{BuildId, IssueId, IssueState, MergeRequestId, MergeRequestState, MergeStatus, MilestoneId, NoteId, NoteType, ObjectId, ProjectId, UserId};
use std::borrow::Borrow;
#[derive(Serialize, Deserialize, Debug)]
/// Project information exposed in hooks.
pub struct ProjectHookAttrs {
/// The display name of the project.
pub name: String,
/// The description of the project.
pub description: String,
/// The URL for the project's homepage.
pub web_url: String,
/// The URL to the project avatar.
pub avatar_url: String,
/// The URL to clone the repository over SSH.
pub git_ssh_url: String,
/// The URL to clone the repository over HTTPS.
pub git_http_url: String,
/// The namespace the project lives in.
pub namespace: String,
/// Integral value for the project's visibility.
pub visibility_level: u64,
/// The path to the project's repository with its namespace.
pub path_with_namespace: String,
/// The default branch for the project.
pub default_branch: String,
}
#[derive(Serialize, Deserialize, Debug)]
/// Wiki project information exposed in hooks.
pub struct ProjectWikiHookAttrs {
/// The URL for the project's homepage.
pub web_url: String,
/// The URL to clone the repository over SSH.
pub git_ssh_url: String,
/// The URL to clone the repository over HTTPS.
pub git_http_url: String,
/// The path to the project's repository with its namespace.
pub path_with_namespace: String,
/// The default branch for the project.
pub default_branch: String,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct UserHookAttrs {
pub name: String,
pub username: String,
pub avatar_url: String,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct HookCommitIdentity {
pub name: String,
pub email: String,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct CommitHookAttrs {
pub id: ObjectId,
pub message: String,
pub timestamp: DateTime<UTC>,
pub url: String,
pub author: HookCommitIdentity,
pub added: Vec<String>,
pub modified: Vec<String>,
pub removed: Vec<String>,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct PushHook {
pub object_kind: String,
pub before: String,
pub after: String,
#[serde(rename="ref")]
pub ref_: String,
pub checkout_sha: String,
pub message: String,
pub user_id: UserId,
pub user_name: String,
pub user_email: String,
pub user_avatar: String,
pub project_id: ProjectId,
pub project: ProjectHookAttrs,
pub commits: Vec<CommitHookAttrs>, // limited to 20 commits
pub total_commits_count: u64,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum IssueAction {
Update,
Open,
Close,
Reopen,
}enum_serialize!(IssueAction -> "issue action",
Update => "update",
Open => "open",
Close => "close",
Reopen => "reopen"
);
#[derive(Serialize, Deserialize, Debug)]
pub struct IssueHookAttrs {
pub id: IssueId,
pub title: String,
pub assignee_id: Option<UserId>,
pub author_id: UserId,
pub project_id: ProjectId,
pub created_at: DateTime<UTC>,
pub updated_at: DateTime<UTC>,
pub position: u64,
pub branch_name: Option<String>,
pub description: String,
pub milestone_id: Option<MilestoneId>,
pub state: IssueState,
pub iid: u64,
pub url: String,
pub action: IssueAction,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct IssueHook {
pub object_kind: String,
pub user: UserHookAttrs,
pub project: ProjectHookAttrs,
pub object_attributes: IssueHookAttrs,
pub assignee: Option<UserHookAttrs>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum MergeRequestAction {
Update,
Open,
Close,
Reopen,
Merge,
}
enum_serialize!(MergeRequestAction -> "merge request action",
Update => "update",
Open => "open",
Close => "close",
Reopen => "reopen",
Merge => "merge"
);
#[derive(Serialize, Deserialize, Debug)]
pub struct MergeRequestHookAttrs {
pub source: ProjectHookAttrs,
pub target: ProjectHookAttrs,
pub last_commit: Option<CommitHookAttrs>,
pub work_in_progress: bool,
pub id: MergeRequestId,
pub target_branch: String,
pub target_project_id: ProjectId,
pub source_branch: String,
pub source_project_id: ProjectId,
pub author_id: UserId,
pub assignee_id: Option<UserId>,
pub title: String,
pub created_at: DateTime<UTC>,
pub updated_at: DateTime<UTC>,
// st_commits
// st_diffs
pub milestone_id: Option<MilestoneId>,
pub state: MergeRequestState,
pub merge_status: MergeStatus,
pub iid: u64,
pub description: String,
pub url: String,
pub action: MergeRequestAction,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct MergeRequestHook {
pub object_kind: String,
pub user: UserHookAttrs,
pub project: ProjectHookAttrs,
pub object_attributes: MergeRequestHookAttrs,
pub assignee: Option<UserHookAttrs>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SnippetType {
Project,
Personal,
}
enum_serialize!(SnippetType -> "snippet type",
Project => "ProjectSnippet",
Personal => "PersonalSnippet"
);
#[derive(Serialize, Deserialize, Debug)]
pub struct SnippetHookAttrs {
pub title: String,
pub content: String,
pub author_id: UserId,
pub project_id: Option<ProjectId>,
pub created_at: DateTime<UTC>,
pub updated_at: DateTime<UTC>,
pub file_name: String,
#[serde(rename="type")]
pub type_: SnippetType,
pub visibility_level: u64,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum WikiPageAction {
Create,
Update,
}
enum_serialize!(WikiPageAction -> "wiki page action",
Create => "create",
Update => "update"
);
#[derive(Serialize, Deserialize, Debug)]
pub struct WikiPageHookAttrs {
pub title: String,
pub content: String,
pub format: String,
pub message: String,
pub slug: String,
pub url: String,
pub action: WikiPageAction,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct DiffHookAttrs {
pub diff: String,
pub new_path: String,
pub old_path: String,
pub a_mode: String, // TODO: Create a mode type.
pub b_mode: String, // TODO: Create a mode type.
pub new_file: bool,
pub renamed_file: bool,
pub deleted_file: bool
}
#[derive(Serialize, Deserialize, Debug)]
pub struct NoteHookAttrs {
pub id: NoteId,
pub note: String,
pub noteable_type: NoteType,
pub author_id: UserId,
pub created_at: DateTime<UTC>,
pub updated_at: DateTime<UTC>,
pub project_id: ProjectId,
pub attachment: Option<String>,
pub line_code: Option<String>, // TODO: This is some internal format.
pub commit_id: String,
pub noteable_id: u64,
pub system: bool,
pub st_diff: Option<DiffHookAttrs>,
pub url: String,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct NoteHook {
pub object_kind: String,
pub user: UserHookAttrs,
pub project_id: ProjectId,
pub project: ProjectHookAttrs,
pub object_attributes: NoteHookAttrs,
pub commit: Option<CommitHookAttrs>,
pub issue: Option<IssueHookAttrs>,
pub merge_request: Option<MergeRequestHookAttrs>,
pub snippet: Option<SnippetHookAttrs>,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct BuildUserHookAttrs {
pub id: Option<UserId>,
pub name: Option<String>,
pub email: Option<String>,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct BuildCommitHookAttrs {
pub id: String,
pub sha: String,
pub message: String,
pub author_name: String,
pub author_email: String,
pub status: String,
pub duration: u64,
pub started_at: Option<DateTime<UTC>>,
pub finished_at: Option<DateTime<UTC>>,
}
#[derive(Serialize, Deserialize, Debug)]
/// Project information exposed in build hooks.
pub struct BuildProjectHookAttrs {
/// The display name of the project.
pub name: String,
pub url: String,
/// The description of the project.
pub description: String,
/// The URL for the project's homepage.
pub homepage: String,
/// The URL to clone the repository over HTTPS.
pub git_http_url: String,
/// The URL to clone the repository over SSH.
pub git_ssh_url: String,
/// Integral value for the project's visibility.
pub visibility_level: u64,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct BuildHook {
pub object_kind: String,
#[serde(rename="ref")]
pub ref_: String,
pub tag: String,
pub before_sha: String,
pub sha: String,
pub build_id: BuildId,
pub build_name: String,
pub build_stage: String,
pub build_started_at: Option<DateTime<UTC>>,
pub build_finished_at: Option<DateTime<UTC>>,
pub build_duration: Option<u64>,
pub build_allow_failure: bool,
pub project_id: ProjectId,
pub user: BuildUserHookAttrs,
pub commit: BuildCommitHookAttrs,
pub repository: BuildProjectHookAttrs,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct WikiPageHook {
pub object_kind: String,
pub user: UserHookAttrs,
pub project: ProjectHookAttrs,
pub wiki: ProjectWikiHookAttrs,
pub object_attributes: WikiPageHookAttrs,
}
#[derive(Debug)]
pub enum WebHook {
Push(PushHook),
Issue(IssueHook),
MergeRequest(MergeRequestHook),
Note(NoteHook),
Build(BuildHook),
WikiPage(WikiPageHook),
}
impl Deserialize for WebHook {
fn deserialize<D: Deserializer>(deserializer: &mut D) -> Result<Self, D::Error> {
let val = try!(Value::deserialize(deserializer));
let event_name = match val.pointer("/object_kind") {
Some(mstring) => {
match mstring.as_string() {
Some(string) => string,
None => {
return Err(D::Error::invalid_type(Type::String));
},
}
},
None => {
return Err(D::Error::missing_field("object_kind"));
},
};
match event_name {
"push" |
"tag_push" => {
Ok(WebHook::Push(try!(PushHook::deserialize(deserializer))))
},
"issue" => {
Ok(WebHook::Issue(try!(IssueHook::deserialize(deserializer))))
},
"merge_request" => {
Ok(WebHook::MergeRequest(try!(MergeRequestHook::deserialize(deserializer))))
},
"note" => {
Ok(WebHook::Note(try!(NoteHook::deserialize(deserializer))))
},
"build" => {
Ok(WebHook::Build(try!(BuildHook::deserialize(deserializer))))
},
_ => Err(D::Error::invalid_value(&format!("unrecognized system object kind: {}", event_name))),
}
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment