From 789f02da7e24697704dc18681dd6a90531c0d976 Mon Sep 17 00:00:00 2001 From: Dmytro Horskyi Date: Fri, 1 Dec 2023 14:09:18 +0200 Subject: [PATCH 1/3] added repos/list_contributors --- src/api/repos.rs | 13 +++++++++ src/api/repos/contributors.rs | 52 +++++++++++++++++++++++++++++++++++ src/models.rs | 8 ++++++ 3 files changed, 73 insertions(+) create mode 100644 src/api/repos/contributors.rs diff --git a/src/api/repos.rs b/src/api/repos.rs index 4a9cc31f..256cd1fd 100644 --- a/src/api/repos.rs +++ b/src/api/repos.rs @@ -7,6 +7,7 @@ use snafu::ResultExt; mod branches; mod collaborators; +mod contributors; mod commits; pub mod events; mod file; @@ -37,6 +38,7 @@ pub use stargazers::ListStarGazersBuilder; pub use status::{CreateStatusBuilder, ListStatusesBuilder}; pub use tags::ListTagsBuilder; pub use teams::ListTeamsBuilder; +use crate::repos::contributors::ListContributorsBuilder; /// Handler for GitHub's repository API. /// @@ -426,6 +428,17 @@ impl<'octo> RepoHandler<'octo> { ListCollaboratorsBuilder::new(self) } + /// List contributors from a repository. + /// ```no_run + /// # async fn run() -> octocrab::Result<()> { + /// let contributors = octocrab::instance().repos("owner", "repo").list_contributors().send().await?; + /// # Ok(()) + /// # } + /// ``` + pub fn list_contributors(&self) -> ListContributorsBuilder<'_, '_> { + ListContributorsBuilder::new(self) + } + /// List star_gazers from a repository. /// ```no_run /// # async fn run() -> octocrab::Result<()> { diff --git a/src/api/repos/contributors.rs b/src/api/repos/contributors.rs new file mode 100644 index 00000000..31d3e3b8 --- /dev/null +++ b/src/api/repos/contributors.rs @@ -0,0 +1,52 @@ +use super::*; + +#[derive(serde::Serialize)] +pub struct ListContributorsBuilder<'octo, 'r> { + #[serde(skip)] + handler: &'r RepoHandler<'octo>, + #[serde(skip_serializing_if = "Option::is_none")] + anon: Option, + #[serde(skip_serializing_if = "Option::is_none")] + per_page: Option, + #[serde(skip_serializing_if = "Option::is_none")] + page: Option, +} + +impl<'octo, 'r> ListContributorsBuilder<'octo, 'r> { + pub fn new(handler: &'r RepoHandler<'octo>) -> Self { + Self { + handler, + anon: None, + per_page: None, + page: None, + } + } + + /// Set to 1 or true to include anonymous contributors in results. + pub fn anon(mut self, include_anon: impl Into) -> Self { + self.anon = Some(include_anon.into()); + self + } + + /// Results per page (max 100). + pub fn per_page(mut self, per_page: impl Into) -> Self { + self.per_page = Some(per_page.into()); + self + } + + /// Page number of the results to fetch. + pub fn page(mut self, page: impl Into) -> Self { + self.page = Some(page.into()); + self + } + + /// Sends the actual request. + pub async fn send(self) -> crate::Result> { + let route = format!( + "/repos/{owner}/{repo}/contributors", + owner = self.handler.owner, + repo = self.handler.repo + ); + self.handler.crab.get(route, Some(&self)).await + } +} diff --git a/src/models.rs b/src/models.rs index 778ea017..907b4bc1 100644 --- a/src/models.rs +++ b/src/models.rs @@ -443,6 +443,14 @@ pub struct Collaborator { pub permissions: Permissions, } +#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)] +#[non_exhaustive] +pub struct Contributor { + #[serde(flatten)] + pub author: Author, + pub contributions: u32, +} + #[derive(Debug, Clone, Hash, Eq, PartialEq, Serialize, Deserialize)] #[non_exhaustive] pub struct StarGazer { From eef5d8e40d686428de0331430fc57ff2f4a78336 Mon Sep 17 00:00:00 2001 From: Dmytro Horskyi Date: Sat, 2 Dec 2023 16:29:14 +0200 Subject: [PATCH 2/3] fixed `fmt` --- src/api/repos.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/api/repos.rs b/src/api/repos.rs index 256cd1fd..ba6959a3 100644 --- a/src/api/repos.rs +++ b/src/api/repos.rs @@ -7,8 +7,8 @@ use snafu::ResultExt; mod branches; mod collaborators; -mod contributors; mod commits; +mod contributors; pub mod events; mod file; pub mod forks; @@ -28,6 +28,7 @@ use crate::{models, params, Octocrab, Result}; pub use branches::ListBranchesBuilder; pub use collaborators::ListCollaboratorsBuilder; pub use commits::ListCommitsBuilder; +pub use contributors::ListContributorsBuilder; pub use file::{DeleteFileBuilder, GetContentBuilder, UpdateFileBuilder}; pub use generate::GenerateRepositoryBuilder; pub use merges::MergeBranchBuilder; @@ -38,7 +39,6 @@ pub use stargazers::ListStarGazersBuilder; pub use status::{CreateStatusBuilder, ListStatusesBuilder}; pub use tags::ListTagsBuilder; pub use teams::ListTeamsBuilder; -use crate::repos::contributors::ListContributorsBuilder; /// Handler for GitHub's repository API. /// From 284051a2b026dc03028adcce85f5ad1cdda7b61e Mon Sep 17 00:00:00 2001 From: Dmytro Horskyi Date: Mon, 18 Dec 2023 13:57:04 +0200 Subject: [PATCH 3/3] added mock + test (as usage example) --- tests/repo_contributors_test.rs | 71 +++ tests/resources/repo_contributors.json | 632 +++++++++++++++++++++++++ 2 files changed, 703 insertions(+) create mode 100644 tests/repo_contributors_test.rs create mode 100644 tests/resources/repo_contributors.json diff --git a/tests/repo_contributors_test.rs b/tests/repo_contributors_test.rs new file mode 100644 index 00000000..2d694422 --- /dev/null +++ b/tests/repo_contributors_test.rs @@ -0,0 +1,71 @@ +use wiremock::{ + matchers::{method, path}, + Mock, MockServer, ResponseTemplate, +}; + +use mock_error::setup_error_handler; +use octocrab::models::{Author, Contributor}; +use octocrab::Octocrab; + +/// Unit test for calls to the `/repos/OWNER/REPO/contributors` endpoint +mod mock_error; + +const OWNER: &str = "XAMPPRocky"; +const REPO: &str = "octocrab"; + +async fn setup_api(template: ResponseTemplate) -> MockServer { + let mock_server = MockServer::start().await; + + Mock::given(method("GET")) + .and(path(format!("/repos/{OWNER}/{REPO}/contributors"))) + .respond_with(template) + .mount(&mock_server) + .await; + setup_error_handler( + &mock_server, + "GET on /repos/OWNER/REPO/contributors not called", + ) + .await; + mock_server +} + +fn setup_octocrab(uri: &str) -> Octocrab { + Octocrab::builder().base_uri(uri).unwrap().build().unwrap() +} + +#[tokio::test] +async fn should_return_repo_contributors() { + let repo_contributors_response: Vec = + serde_json::from_str(include_str!("resources/repo_contributors.json")).unwrap(); + let template = ResponseTemplate::new(200).set_body_json(&repo_contributors_response); + let mock_server = setup_api(template).await; + let client = setup_octocrab(&mock_server.uri()); + + let result = client + .repos(OWNER, REPO) + .list_contributors() + .anon(true) + .send() + .await; + + assert!( + result.is_ok(), + "expected successful result, got error: {:#?}", + result + ); + + let contributors = result.unwrap(); + + assert!(contributors.items.len() > 0); + + let Contributor { + author: Author { login, .. }, + contributions, + .. + } = contributors.items.first().unwrap(); + + { + assert_eq!(login, "XAMPPRocky"); + assert!(*contributions > 0); + } +} diff --git a/tests/resources/repo_contributors.json b/tests/resources/repo_contributors.json new file mode 100644 index 00000000..39dcb2a6 --- /dev/null +++ b/tests/resources/repo_contributors.json @@ -0,0 +1,632 @@ +[ + { + "login": "XAMPPRocky", + "id": 4464295, + "node_id": "MDQ6VXNlcjQ0NjQyOTU=", + "avatar_url": "https://avatars.githubusercontent.com/u/4464295?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/XAMPPRocky", + "html_url": "https://github.com/XAMPPRocky", + "followers_url": "https://api.github.com/users/XAMPPRocky/followers", + "following_url": "https://api.github.com/users/XAMPPRocky/following{/other_user}", + "gists_url": "https://api.github.com/users/XAMPPRocky/gists{/gist_id}", + "starred_url": "https://api.github.com/users/XAMPPRocky/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/XAMPPRocky/subscriptions", + "organizations_url": "https://api.github.com/users/XAMPPRocky/orgs", + "repos_url": "https://api.github.com/users/XAMPPRocky/repos", + "events_url": "https://api.github.com/users/XAMPPRocky/events{/privacy}", + "received_events_url": "https://api.github.com/users/XAMPPRocky/received_events", + "type": "User", + "site_admin": false, + "contributions": 167 + }, + { + "login": "Jake-Shadle", + "id": 2316028, + "node_id": "MDQ6VXNlcjIzMTYwMjg=", + "avatar_url": "https://avatars.githubusercontent.com/u/2316028?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Jake-Shadle", + "html_url": "https://github.com/Jake-Shadle", + "followers_url": "https://api.github.com/users/Jake-Shadle/followers", + "following_url": "https://api.github.com/users/Jake-Shadle/following{/other_user}", + "gists_url": "https://api.github.com/users/Jake-Shadle/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Jake-Shadle/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Jake-Shadle/subscriptions", + "organizations_url": "https://api.github.com/users/Jake-Shadle/orgs", + "repos_url": "https://api.github.com/users/Jake-Shadle/repos", + "events_url": "https://api.github.com/users/Jake-Shadle/events{/privacy}", + "received_events_url": "https://api.github.com/users/Jake-Shadle/received_events", + "type": "User", + "site_admin": false, + "contributions": 19 + }, + { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false, + "contributions": 16 + }, + { + "login": "rocallahan", + "id": 296135, + "node_id": "MDQ6VXNlcjI5NjEzNQ==", + "avatar_url": "https://avatars.githubusercontent.com/u/296135?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/rocallahan", + "html_url": "https://github.com/rocallahan", + "followers_url": "https://api.github.com/users/rocallahan/followers", + "following_url": "https://api.github.com/users/rocallahan/following{/other_user}", + "gists_url": "https://api.github.com/users/rocallahan/gists{/gist_id}", + "starred_url": "https://api.github.com/users/rocallahan/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/rocallahan/subscriptions", + "organizations_url": "https://api.github.com/users/rocallahan/orgs", + "repos_url": "https://api.github.com/users/rocallahan/repos", + "events_url": "https://api.github.com/users/rocallahan/events{/privacy}", + "received_events_url": "https://api.github.com/users/rocallahan/received_events", + "type": "User", + "site_admin": false, + "contributions": 14 + }, + { + "login": "wayofthepie", + "id": 1102174, + "node_id": "MDQ6VXNlcjExMDIxNzQ=", + "avatar_url": "https://avatars.githubusercontent.com/u/1102174?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/wayofthepie", + "html_url": "https://github.com/wayofthepie", + "followers_url": "https://api.github.com/users/wayofthepie/followers", + "following_url": "https://api.github.com/users/wayofthepie/following{/other_user}", + "gists_url": "https://api.github.com/users/wayofthepie/gists{/gist_id}", + "starred_url": "https://api.github.com/users/wayofthepie/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/wayofthepie/subscriptions", + "organizations_url": "https://api.github.com/users/wayofthepie/orgs", + "repos_url": "https://api.github.com/users/wayofthepie/repos", + "events_url": "https://api.github.com/users/wayofthepie/events{/privacy}", + "received_events_url": "https://api.github.com/users/wayofthepie/received_events", + "type": "User", + "site_admin": false, + "contributions": 12 + }, + { + "login": "gagbo", + "id": 10496163, + "node_id": "MDQ6VXNlcjEwNDk2MTYz", + "avatar_url": "https://avatars.githubusercontent.com/u/10496163?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/gagbo", + "html_url": "https://github.com/gagbo", + "followers_url": "https://api.github.com/users/gagbo/followers", + "following_url": "https://api.github.com/users/gagbo/following{/other_user}", + "gists_url": "https://api.github.com/users/gagbo/gists{/gist_id}", + "starred_url": "https://api.github.com/users/gagbo/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/gagbo/subscriptions", + "organizations_url": "https://api.github.com/users/gagbo/orgs", + "repos_url": "https://api.github.com/users/gagbo/repos", + "events_url": "https://api.github.com/users/gagbo/events{/privacy}", + "received_events_url": "https://api.github.com/users/gagbo/received_events", + "type": "User", + "site_admin": false, + "contributions": 11 + }, + { + "login": "LeSeulArtichaut", + "id": 38361244, + "node_id": "MDQ6VXNlcjM4MzYxMjQ0", + "avatar_url": "https://avatars.githubusercontent.com/u/38361244?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/LeSeulArtichaut", + "html_url": "https://github.com/LeSeulArtichaut", + "followers_url": "https://api.github.com/users/LeSeulArtichaut/followers", + "following_url": "https://api.github.com/users/LeSeulArtichaut/following{/other_user}", + "gists_url": "https://api.github.com/users/LeSeulArtichaut/gists{/gist_id}", + "starred_url": "https://api.github.com/users/LeSeulArtichaut/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/LeSeulArtichaut/subscriptions", + "organizations_url": "https://api.github.com/users/LeSeulArtichaut/orgs", + "repos_url": "https://api.github.com/users/LeSeulArtichaut/repos", + "events_url": "https://api.github.com/users/LeSeulArtichaut/events{/privacy}", + "received_events_url": "https://api.github.com/users/LeSeulArtichaut/received_events", + "type": "User", + "site_admin": false, + "contributions": 10 + }, + { + "login": "envp", + "id": 3663231, + "node_id": "MDQ6VXNlcjM2NjMyMzE=", + "avatar_url": "https://avatars.githubusercontent.com/u/3663231?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/envp", + "html_url": "https://github.com/envp", + "followers_url": "https://api.github.com/users/envp/followers", + "following_url": "https://api.github.com/users/envp/following{/other_user}", + "gists_url": "https://api.github.com/users/envp/gists{/gist_id}", + "starred_url": "https://api.github.com/users/envp/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/envp/subscriptions", + "organizations_url": "https://api.github.com/users/envp/orgs", + "repos_url": "https://api.github.com/users/envp/repos", + "events_url": "https://api.github.com/users/envp/events{/privacy}", + "received_events_url": "https://api.github.com/users/envp/received_events", + "type": "User", + "site_admin": false, + "contributions": 9 + }, + { + "login": "kellda", + "id": 59569234, + "node_id": "MDQ6VXNlcjU5NTY5MjM0", + "avatar_url": "https://avatars.githubusercontent.com/u/59569234?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/kellda", + "html_url": "https://github.com/kellda", + "followers_url": "https://api.github.com/users/kellda/followers", + "following_url": "https://api.github.com/users/kellda/following{/other_user}", + "gists_url": "https://api.github.com/users/kellda/gists{/gist_id}", + "starred_url": "https://api.github.com/users/kellda/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/kellda/subscriptions", + "organizations_url": "https://api.github.com/users/kellda/orgs", + "repos_url": "https://api.github.com/users/kellda/repos", + "events_url": "https://api.github.com/users/kellda/events{/privacy}", + "received_events_url": "https://api.github.com/users/kellda/received_events", + "type": "User", + "site_admin": false, + "contributions": 9 + }, + { + "login": "maflcko", + "id": 6399679, + "node_id": "MDQ6VXNlcjYzOTk2Nzk=", + "avatar_url": "https://avatars.githubusercontent.com/u/6399679?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/maflcko", + "html_url": "https://github.com/maflcko", + "followers_url": "https://api.github.com/users/maflcko/followers", + "following_url": "https://api.github.com/users/maflcko/following{/other_user}", + "gists_url": "https://api.github.com/users/maflcko/gists{/gist_id}", + "starred_url": "https://api.github.com/users/maflcko/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/maflcko/subscriptions", + "organizations_url": "https://api.github.com/users/maflcko/orgs", + "repos_url": "https://api.github.com/users/maflcko/repos", + "events_url": "https://api.github.com/users/maflcko/events{/privacy}", + "received_events_url": "https://api.github.com/users/maflcko/received_events", + "type": "User", + "site_admin": false, + "contributions": 9 + }, + { + "login": "MarcoIeni", + "id": 11428655, + "node_id": "MDQ6VXNlcjExNDI4NjU1", + "avatar_url": "https://avatars.githubusercontent.com/u/11428655?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/MarcoIeni", + "html_url": "https://github.com/MarcoIeni", + "followers_url": "https://api.github.com/users/MarcoIeni/followers", + "following_url": "https://api.github.com/users/MarcoIeni/following{/other_user}", + "gists_url": "https://api.github.com/users/MarcoIeni/gists{/gist_id}", + "starred_url": "https://api.github.com/users/MarcoIeni/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/MarcoIeni/subscriptions", + "organizations_url": "https://api.github.com/users/MarcoIeni/orgs", + "repos_url": "https://api.github.com/users/MarcoIeni/repos", + "events_url": "https://api.github.com/users/MarcoIeni/events{/privacy}", + "received_events_url": "https://api.github.com/users/MarcoIeni/received_events", + "type": "User", + "site_admin": false, + "contributions": 6 + }, + { + "login": "0xB10C", + "id": 19157360, + "node_id": "MDQ6VXNlcjE5MTU3MzYw", + "avatar_url": "https://avatars.githubusercontent.com/u/19157360?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/0xB10C", + "html_url": "https://github.com/0xB10C", + "followers_url": "https://api.github.com/users/0xB10C/followers", + "following_url": "https://api.github.com/users/0xB10C/following{/other_user}", + "gists_url": "https://api.github.com/users/0xB10C/gists{/gist_id}", + "starred_url": "https://api.github.com/users/0xB10C/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/0xB10C/subscriptions", + "organizations_url": "https://api.github.com/users/0xB10C/orgs", + "repos_url": "https://api.github.com/users/0xB10C/repos", + "events_url": "https://api.github.com/users/0xB10C/events{/privacy}", + "received_events_url": "https://api.github.com/users/0xB10C/received_events", + "type": "User", + "site_admin": false, + "contributions": 5 + }, + { + "login": "dependabot-preview[bot]", + "id": 27856297, + "node_id": "MDM6Qm90Mjc4NTYyOTc=", + "avatar_url": "https://avatars.githubusercontent.com/in/2141?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/dependabot-preview%5Bbot%5D", + "html_url": "https://github.com/apps/dependabot-preview", + "followers_url": "https://api.github.com/users/dependabot-preview%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/dependabot-preview%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/dependabot-preview%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/dependabot-preview%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/dependabot-preview%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/dependabot-preview%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/dependabot-preview%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/dependabot-preview%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/dependabot-preview%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false, + "contributions": 5 + }, + { + "login": "LuaKT", + "id": 1272751, + "node_id": "MDQ6VXNlcjEyNzI3NTE=", + "avatar_url": "https://avatars.githubusercontent.com/u/1272751?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/LuaKT", + "html_url": "https://github.com/LuaKT", + "followers_url": "https://api.github.com/users/LuaKT/followers", + "following_url": "https://api.github.com/users/LuaKT/following{/other_user}", + "gists_url": "https://api.github.com/users/LuaKT/gists{/gist_id}", + "starred_url": "https://api.github.com/users/LuaKT/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/LuaKT/subscriptions", + "organizations_url": "https://api.github.com/users/LuaKT/orgs", + "repos_url": "https://api.github.com/users/LuaKT/repos", + "events_url": "https://api.github.com/users/LuaKT/events{/privacy}", + "received_events_url": "https://api.github.com/users/LuaKT/received_events", + "type": "User", + "site_admin": false, + "contributions": 4 + }, + { + "login": "khuey", + "id": 325892, + "node_id": "MDQ6VXNlcjMyNTg5Mg==", + "avatar_url": "https://avatars.githubusercontent.com/u/325892?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/khuey", + "html_url": "https://github.com/khuey", + "followers_url": "https://api.github.com/users/khuey/followers", + "following_url": "https://api.github.com/users/khuey/following{/other_user}", + "gists_url": "https://api.github.com/users/khuey/gists{/gist_id}", + "starred_url": "https://api.github.com/users/khuey/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/khuey/subscriptions", + "organizations_url": "https://api.github.com/users/khuey/orgs", + "repos_url": "https://api.github.com/users/khuey/repos", + "events_url": "https://api.github.com/users/khuey/events{/privacy}", + "received_events_url": "https://api.github.com/users/khuey/received_events", + "type": "User", + "site_admin": false, + "contributions": 4 + }, + { + "login": "Enselic", + "id": 115040, + "node_id": "MDQ6VXNlcjExNTA0MA==", + "avatar_url": "https://avatars.githubusercontent.com/u/115040?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Enselic", + "html_url": "https://github.com/Enselic", + "followers_url": "https://api.github.com/users/Enselic/followers", + "following_url": "https://api.github.com/users/Enselic/following{/other_user}", + "gists_url": "https://api.github.com/users/Enselic/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Enselic/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Enselic/subscriptions", + "organizations_url": "https://api.github.com/users/Enselic/orgs", + "repos_url": "https://api.github.com/users/Enselic/repos", + "events_url": "https://api.github.com/users/Enselic/events{/privacy}", + "received_events_url": "https://api.github.com/users/Enselic/received_events", + "type": "User", + "site_admin": false, + "contributions": 4 + }, + { + "login": "dependabot[bot]", + "id": 49699333, + "node_id": "MDM6Qm90NDk2OTkzMzM=", + "avatar_url": "https://avatars.githubusercontent.com/in/29110?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/dependabot%5Bbot%5D", + "html_url": "https://github.com/apps/dependabot", + "followers_url": "https://api.github.com/users/dependabot%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/dependabot%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/dependabot%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/dependabot%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/dependabot%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/dependabot%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/dependabot%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/dependabot%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/dependabot%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false, + "contributions": 4 + }, + { + "login": "goodspark", + "id": 29210237, + "node_id": "MDQ6VXNlcjI5MjEwMjM3", + "avatar_url": "https://avatars.githubusercontent.com/u/29210237?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/goodspark", + "html_url": "https://github.com/goodspark", + "followers_url": "https://api.github.com/users/goodspark/followers", + "following_url": "https://api.github.com/users/goodspark/following{/other_user}", + "gists_url": "https://api.github.com/users/goodspark/gists{/gist_id}", + "starred_url": "https://api.github.com/users/goodspark/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/goodspark/subscriptions", + "organizations_url": "https://api.github.com/users/goodspark/orgs", + "repos_url": "https://api.github.com/users/goodspark/repos", + "events_url": "https://api.github.com/users/goodspark/events{/privacy}", + "received_events_url": "https://api.github.com/users/goodspark/received_events", + "type": "User", + "site_admin": false, + "contributions": 4 + }, + { + "login": "mbirtwell", + "id": 4640901, + "node_id": "MDQ6VXNlcjQ2NDA5MDE=", + "avatar_url": "https://avatars.githubusercontent.com/u/4640901?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/mbirtwell", + "html_url": "https://github.com/mbirtwell", + "followers_url": "https://api.github.com/users/mbirtwell/followers", + "following_url": "https://api.github.com/users/mbirtwell/following{/other_user}", + "gists_url": "https://api.github.com/users/mbirtwell/gists{/gist_id}", + "starred_url": "https://api.github.com/users/mbirtwell/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/mbirtwell/subscriptions", + "organizations_url": "https://api.github.com/users/mbirtwell/orgs", + "repos_url": "https://api.github.com/users/mbirtwell/repos", + "events_url": "https://api.github.com/users/mbirtwell/events{/privacy}", + "received_events_url": "https://api.github.com/users/mbirtwell/received_events", + "type": "User", + "site_admin": false, + "contributions": 4 + }, + { + "login": "mkroman", + "id": 173308, + "node_id": "MDQ6VXNlcjE3MzMwOA==", + "avatar_url": "https://avatars.githubusercontent.com/u/173308?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/mkroman", + "html_url": "https://github.com/mkroman", + "followers_url": "https://api.github.com/users/mkroman/followers", + "following_url": "https://api.github.com/users/mkroman/following{/other_user}", + "gists_url": "https://api.github.com/users/mkroman/gists{/gist_id}", + "starred_url": "https://api.github.com/users/mkroman/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/mkroman/subscriptions", + "organizations_url": "https://api.github.com/users/mkroman/orgs", + "repos_url": "https://api.github.com/users/mkroman/repos", + "events_url": "https://api.github.com/users/mkroman/events{/privacy}", + "received_events_url": "https://api.github.com/users/mkroman/received_events", + "type": "User", + "site_admin": false, + "contributions": 4 + }, + { + "login": "L1ghtman2k", + "id": 35672535, + "node_id": "MDQ6VXNlcjM1NjcyNTM1", + "avatar_url": "https://avatars.githubusercontent.com/u/35672535?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/L1ghtman2k", + "html_url": "https://github.com/L1ghtman2k", + "followers_url": "https://api.github.com/users/L1ghtman2k/followers", + "following_url": "https://api.github.com/users/L1ghtman2k/following{/other_user}", + "gists_url": "https://api.github.com/users/L1ghtman2k/gists{/gist_id}", + "starred_url": "https://api.github.com/users/L1ghtman2k/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/L1ghtman2k/subscriptions", + "organizations_url": "https://api.github.com/users/L1ghtman2k/orgs", + "repos_url": "https://api.github.com/users/L1ghtman2k/repos", + "events_url": "https://api.github.com/users/L1ghtman2k/events{/privacy}", + "received_events_url": "https://api.github.com/users/L1ghtman2k/received_events", + "type": "User", + "site_admin": false, + "contributions": 3 + }, + { + "login": "aureleoules", + "id": 22493292, + "node_id": "MDQ6VXNlcjIyNDkzMjky", + "avatar_url": "https://avatars.githubusercontent.com/u/22493292?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/aureleoules", + "html_url": "https://github.com/aureleoules", + "followers_url": "https://api.github.com/users/aureleoules/followers", + "following_url": "https://api.github.com/users/aureleoules/following{/other_user}", + "gists_url": "https://api.github.com/users/aureleoules/gists{/gist_id}", + "starred_url": "https://api.github.com/users/aureleoules/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/aureleoules/subscriptions", + "organizations_url": "https://api.github.com/users/aureleoules/orgs", + "repos_url": "https://api.github.com/users/aureleoules/repos", + "events_url": "https://api.github.com/users/aureleoules/events{/privacy}", + "received_events_url": "https://api.github.com/users/aureleoules/received_events", + "type": "User", + "site_admin": false, + "contributions": 3 + }, + { + "login": "udzura", + "id": 91011, + "node_id": "MDQ6VXNlcjkxMDEx", + "avatar_url": "https://avatars.githubusercontent.com/u/91011?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/udzura", + "html_url": "https://github.com/udzura", + "followers_url": "https://api.github.com/users/udzura/followers", + "following_url": "https://api.github.com/users/udzura/following{/other_user}", + "gists_url": "https://api.github.com/users/udzura/gists{/gist_id}", + "starred_url": "https://api.github.com/users/udzura/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/udzura/subscriptions", + "organizations_url": "https://api.github.com/users/udzura/orgs", + "repos_url": "https://api.github.com/users/udzura/repos", + "events_url": "https://api.github.com/users/udzura/events{/privacy}", + "received_events_url": "https://api.github.com/users/udzura/received_events", + "type": "User", + "site_admin": false, + "contributions": 3 + }, + { + "login": "lineville", + "id": 25349044, + "node_id": "MDQ6VXNlcjI1MzQ5MDQ0", + "avatar_url": "https://avatars.githubusercontent.com/u/25349044?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/lineville", + "html_url": "https://github.com/lineville", + "followers_url": "https://api.github.com/users/lineville/followers", + "following_url": "https://api.github.com/users/lineville/following{/other_user}", + "gists_url": "https://api.github.com/users/lineville/gists{/gist_id}", + "starred_url": "https://api.github.com/users/lineville/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/lineville/subscriptions", + "organizations_url": "https://api.github.com/users/lineville/orgs", + "repos_url": "https://api.github.com/users/lineville/repos", + "events_url": "https://api.github.com/users/lineville/events{/privacy}", + "received_events_url": "https://api.github.com/users/lineville/received_events", + "type": "User", + "site_admin": true, + "contributions": 3 + }, + { + "login": "matthewgapp", + "id": 61894094, + "node_id": "MDQ6VXNlcjYxODk0MDk0", + "avatar_url": "https://avatars.githubusercontent.com/u/61894094?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/matthewgapp", + "html_url": "https://github.com/matthewgapp", + "followers_url": "https://api.github.com/users/matthewgapp/followers", + "following_url": "https://api.github.com/users/matthewgapp/following{/other_user}", + "gists_url": "https://api.github.com/users/matthewgapp/gists{/gist_id}", + "starred_url": "https://api.github.com/users/matthewgapp/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/matthewgapp/subscriptions", + "organizations_url": "https://api.github.com/users/matthewgapp/orgs", + "repos_url": "https://api.github.com/users/matthewgapp/repos", + "events_url": "https://api.github.com/users/matthewgapp/events{/privacy}", + "received_events_url": "https://api.github.com/users/matthewgapp/received_events", + "type": "User", + "site_admin": false, + "contributions": 3 + }, + { + "login": "wtfiscrq", + "id": 8532541, + "node_id": "MDQ6VXNlcjg1MzI1NDE=", + "avatar_url": "https://avatars.githubusercontent.com/u/8532541?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/wtfiscrq", + "html_url": "https://github.com/wtfiscrq", + "followers_url": "https://api.github.com/users/wtfiscrq/followers", + "following_url": "https://api.github.com/users/wtfiscrq/following{/other_user}", + "gists_url": "https://api.github.com/users/wtfiscrq/gists{/gist_id}", + "starred_url": "https://api.github.com/users/wtfiscrq/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/wtfiscrq/subscriptions", + "organizations_url": "https://api.github.com/users/wtfiscrq/orgs", + "repos_url": "https://api.github.com/users/wtfiscrq/repos", + "events_url": "https://api.github.com/users/wtfiscrq/events{/privacy}", + "received_events_url": "https://api.github.com/users/wtfiscrq/received_events", + "type": "User", + "site_admin": false, + "contributions": 3 + }, + { + "login": "kafji", + "id": 1842143, + "node_id": "MDQ6VXNlcjE4NDIxNDM=", + "avatar_url": "https://avatars.githubusercontent.com/u/1842143?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/kafji", + "html_url": "https://github.com/kafji", + "followers_url": "https://api.github.com/users/kafji/followers", + "following_url": "https://api.github.com/users/kafji/following{/other_user}", + "gists_url": "https://api.github.com/users/kafji/gists{/gist_id}", + "starred_url": "https://api.github.com/users/kafji/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/kafji/subscriptions", + "organizations_url": "https://api.github.com/users/kafji/orgs", + "repos_url": "https://api.github.com/users/kafji/repos", + "events_url": "https://api.github.com/users/kafji/events{/privacy}", + "received_events_url": "https://api.github.com/users/kafji/received_events", + "type": "User", + "site_admin": false, + "contributions": 3 + }, + { + "login": "Roger-luo", + "id": 8445510, + "node_id": "MDQ6VXNlcjg0NDU1MTA=", + "avatar_url": "https://avatars.githubusercontent.com/u/8445510?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Roger-luo", + "html_url": "https://github.com/Roger-luo", + "followers_url": "https://api.github.com/users/Roger-luo/followers", + "following_url": "https://api.github.com/users/Roger-luo/following{/other_user}", + "gists_url": "https://api.github.com/users/Roger-luo/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Roger-luo/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Roger-luo/subscriptions", + "organizations_url": "https://api.github.com/users/Roger-luo/orgs", + "repos_url": "https://api.github.com/users/Roger-luo/repos", + "events_url": "https://api.github.com/users/Roger-luo/events{/privacy}", + "received_events_url": "https://api.github.com/users/Roger-luo/received_events", + "type": "User", + "site_admin": false, + "contributions": 3 + }, + { + "login": "qbx2", + "id": 5977817, + "node_id": "MDQ6VXNlcjU5Nzc4MTc=", + "avatar_url": "https://avatars.githubusercontent.com/u/5977817?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/qbx2", + "html_url": "https://github.com/qbx2", + "followers_url": "https://api.github.com/users/qbx2/followers", + "following_url": "https://api.github.com/users/qbx2/following{/other_user}", + "gists_url": "https://api.github.com/users/qbx2/gists{/gist_id}", + "starred_url": "https://api.github.com/users/qbx2/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/qbx2/subscriptions", + "organizations_url": "https://api.github.com/users/qbx2/orgs", + "repos_url": "https://api.github.com/users/qbx2/repos", + "events_url": "https://api.github.com/users/qbx2/events{/privacy}", + "received_events_url": "https://api.github.com/users/qbx2/received_events", + "type": "User", + "site_admin": false, + "contributions": 3 + }, + { + "login": "suryapandian", + "id": 10370495, + "node_id": "MDQ6VXNlcjEwMzcwNDk1", + "avatar_url": "https://avatars.githubusercontent.com/u/10370495?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/suryapandian", + "html_url": "https://github.com/suryapandian", + "followers_url": "https://api.github.com/users/suryapandian/followers", + "following_url": "https://api.github.com/users/suryapandian/following{/other_user}", + "gists_url": "https://api.github.com/users/suryapandian/gists{/gist_id}", + "starred_url": "https://api.github.com/users/suryapandian/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/suryapandian/subscriptions", + "organizations_url": "https://api.github.com/users/suryapandian/orgs", + "repos_url": "https://api.github.com/users/suryapandian/repos", + "events_url": "https://api.github.com/users/suryapandian/events{/privacy}", + "received_events_url": "https://api.github.com/users/suryapandian/received_events", + "type": "User", + "site_admin": false, + "contributions": 3 + } +]