Skip to content

Commit

Permalink
feat: issues analysis (#15)
Browse files Browse the repository at this point in the history
* feat: add graphql

* feat: issues analysis

* test: issues analysis

* fix lint

* docs: update

* chore: update version
  • Loading branch information
hirokisan authored Nov 29, 2024
1 parent 0f34354 commit f55110e
Show file tree
Hide file tree
Showing 15 changed files with 1,722 additions and 9 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name = "gh-lens"
authors = ["hirokisan <[email protected]>"]
description = "CLI to analyze your activity on GitHub"
version = "0.0.11"
version = "0.0.12"
edition = "2021"
license = "MIT"
keywords = ["github", "cli", "analysis", "gh-lens"]
Expand Down
81 changes: 81 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,84 @@ $ gh-lens prs --repo hirokisan/gh-lens --start-date 2024-11-12 --end-date 2024-1
]
}
```

```console
gh-lens issues --repo hirokisan/bybit --start-date 2024-01-01 --end-date 2024-10-31 | jq .
{
"start_date": "2024-01-01",
"end_date": "2024-10-31",
"issues_count": 5,
"assigns_count": 1,
"comments_count": {
"sum": 12,
"average": 2.4
},
"time_to_closed": {
"average": 339269.2
},
"issues_summaries": [
{
"url": "https://github.com/hirokisan/bybit/issues/190",
"author": "id-petrov",
"assignees": null,
"participants": [
"id-petrov",
"hirokisan"
],
"comments_count": 1,
"created_at": "2024-10-28T20:10:43Z",
"closed_at": "2024-10-29T05:39:09Z"
},
{
"url": "https://github.com/hirokisan/bybit/issues/181",
"author": "austymenko",
"assignees": null,
"participants": [
"austymenko",
"hirokisan"
],
"comments_count": 5,
"created_at": "2024-07-06T03:31:11Z",
"closed_at": "2024-07-13T13:29:15Z"
},
{
"url": "https://github.com/hirokisan/bybit/issues/175",
"author": "apeman76",
"assignees": null,
"participants": [
"apeman76",
"hirokisan"
],
"comments_count": 2,
"created_at": "2024-06-12T14:13:08Z",
"closed_at": "2024-06-23T07:57:42Z"
},
{
"url": "https://github.com/hirokisan/bybit/issues/171",
"author": "s-prosvirnin",
"assignees": [
"hirokisan"
],
"participants": [
"s-prosvirnin",
"hirokisan"
],
"comments_count": 2,
"created_at": "2024-04-21T10:35:14Z",
"closed_at": "2024-04-22T11:54:24Z"
},
{
"url": "https://github.com/hirokisan/bybit/issues/160",
"author": "biancheng347",
"assignees": null,
"participants": [
"hirokisan",
"biancheng347"
],
"comments_count": 2,
"created_at": "2024-01-25T09:18:51Z",
"closed_at": "2024-01-25T10:01:03Z"
}
]
}
```
5 changes: 5 additions & 0 deletions src/github.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
mod client;
mod gql;
mod issue;
mod issues;
mod issues_summary;
mod pull_request;
mod pull_requests;
mod pull_requests_summary;

pub(crate) use client::*;
pub(crate) use issues::*;
pub(crate) use issues_summary::*;
pub(crate) use pull_requests::*;
pub(crate) use pull_requests_summary::*;
96 changes: 95 additions & 1 deletion src/github/client.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
use graphql_client::GraphQLQuery;

use super::gql::query::{pull_requests_query, PullRequestsQuery};
use super::gql::issues_query::{issues_query, IssuesQuery};
use super::gql::pull_requests_query::{pull_requests_query, PullRequestsQuery};
use super::issue::Issue;
use super::issues::Issues;
use super::issues_summary::IssuesSummary;
use super::pull_request::PullRequest;
use super::pull_requests::PullRequests;
use super::pull_requests_summary::PullRequestsSummary;
Expand Down Expand Up @@ -72,6 +76,56 @@ impl Client {
Ok(result)
}

async fn get_issues(
&self,
repo: &str,
start_date: &str,
end_date: &str,
) -> Result<Issues, anyhow::Error> {
let mut result = Issues::new();

let offset = 10;
let query = format!("repo:{repo} is:issue created:{start_date}..{end_date}");
let mut variables = issues_query::Variables {
first: offset,
query: query.to_string(),
threshold: 50,
after: None,
};

loop {
let response: octocrab::Result<graphql_client::Response<issues_query::ResponseData>> =
self.inner
.graphql(&IssuesQuery::build_query(variables.clone()))
.await;

match response {
Ok(res) => {
let issues = &res.data.as_ref().unwrap().search;
let has_next_page = issues.page_info.has_next_page;
let end_cursor = issues.page_info.end_cursor.clone();

for item in issues.nodes.as_ref().unwrap().iter().flatten() {
match item {
issues_query::IssuesQuerySearchNodes::Issue(issue) => {
result.add(Issue::new(issue.clone()))
}
_ => continue,
};
}

if !has_next_page {
break;
}
variables.after.clone_from(&end_cursor);
}
Err(err) => return Err(anyhow::anyhow!(err)),
}
}

Ok(result)
}

pub async fn get_pull_requests_summary(
&self,
repo: String,
Expand Down Expand Up @@ -115,4 +169,44 @@ impl Client {

Ok(summaries)
}

pub async fn get_issues_summary(
&self,
repo: String,
start_date: String,
end_date: String,
) -> Result<IssuesSummary, anyhow::Error> {
let issues = self.get_issues(&repo, &start_date, &end_date).await?;

Ok(IssuesSummary::new(
start_date.clone(),
end_date.clone(),
&issues,
))
}

pub async fn get_issues_summary_on_individuals(
&self,
repo: String,
start_date: String,
end_date: String,
individuals: Vec<String>,
) -> Result<HashMap<String, IssuesSummary>, anyhow::Error> {
let issues = self.get_issues(&repo, &start_date, &end_date).await?;

let mut summaries: HashMap<String, IssuesSummary> = HashMap::new();

for individual in individuals.iter() {
summaries
.entry(individual.clone())
.or_insert(IssuesSummary::new_with_by(
start_date.clone(),
end_date.clone(),
&issues,
individual,
));
}

Ok(summaries)
}
}
3 changes: 2 additions & 1 deletion src/github/gql.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
pub(super) mod query;
pub(super) mod issues_query;
pub(super) mod pull_requests_query;
pub(super) mod scaler;
51 changes: 51 additions & 0 deletions src/github/gql/issues_query.graphql
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
query IssuesQuery($first: Int!, $after: String, $query: String!, $threshold: Int!) {
search( type: ISSUE first: $first after: $after query: $query) {
issueCount
pageInfo {
hasNextPage
endCursor
}
nodes {
__typename
... on Issue {
url
createdAt
closedAt
author {
__typename
login
}
comments(first: $threshold) {
nodes {
author {
__typename
login
}
}
}
timelineItems(first: 1, itemTypes: CLOSED_EVENT) {
nodes {
__typename
... on ClosedEvent {
actor {
__typename
login
}
createdAt
}
}
}
assignees(first: $threshold) {
nodes {
login
}
}
participants(first: $threshold) {
nodes {
login
}
}
}
}
}
}
Loading

0 comments on commit f55110e

Please sign in to comment.