Skip to content
This repository was archived by the owner on Nov 6, 2025. It is now read-only.

Commit 050c527

Browse files
committed
Update Issues GraphQL query and related codes
- Added new fields (specified in #169) to the GraphQL query. - Restored previously commented-out project-related fields. - Explicitly mapped GraphQL custom scalar `URI` to Rust. - Made `Issue` struct support serialization/deserialization to enable storing/retrieving from the database. - Updated `GitHubIssue` struct to align with the `Issue` struct, and adjusted related functions accordingly. Close: #169
1 parent 803a0a6 commit 050c527

File tree

5 files changed

+406
-19
lines changed

5 files changed

+406
-19
lines changed

src/database.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -65,12 +65,8 @@ impl Database {
6565
name: &str,
6666
) -> Result<()> {
6767
for item in resp {
68-
let keystr: String = format!("{owner}/{name}#{}", item.number);
69-
Database::insert(
70-
&keystr,
71-
(&item.title, &item.author, &item.closed_at),
72-
&self.issue_tree,
73-
)?;
68+
let keystr = format!("{owner}/{name}#{}", item.number);
69+
Database::insert(&keystr, &item, &self.issue_tree)?;
7470
}
7571
Ok(())
7672
}

src/github.rs

Lines changed: 116 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@ use anyhow::{bail, Context, Result};
44
use chrono::Utc;
55
use graphql_client::{GraphQLQuery, QueryBody, Response as GraphQlResponse};
66
use reqwest::{Client, RequestBuilder, Response};
7-
use serde::Serialize;
7+
use serde::{Deserialize, Serialize};
88
use tokio::time;
99
use tracing::error;
1010

11+
use crate::graphql::issue::{Comment, ProjectV2, SubIssue, ParentIssue, PullRequestRef};
1112
use crate::{database::Database, github::{
1213
issues::IssuesRepositoryIssuesNodesAuthor::User as userName,
1314
pull_requests::PullRequestsRepositoryPullRequestsNodesReviewRequestsNodesRequestedReviewer::User,
@@ -19,6 +20,8 @@ const APP_USER_AGENT: &str = concat!(env!("CARGO_PKG_NAME"), "/", env!("CARGO_PK
1920
const INIT_TIME: &str = "1992-06-05T00:00:00Z";
2021

2122
type DateTime = String;
23+
#[allow(clippy::upper_case_acronyms)]
24+
type URI = String;
2225

2326
#[derive(GraphQLQuery)]
2427
#[graphql(
@@ -35,12 +38,27 @@ struct Issues;
3538
)]
3639
struct PullRequests;
3740

38-
#[derive(Debug)]
41+
#[derive(Debug, Serialize, Deserialize)]
3942
pub(super) struct GitHubIssue {
43+
pub(super) id: String,
4044
pub(super) number: i64,
4145
pub(super) title: String,
4246
pub(super) author: String,
43-
pub(super) closed_at: Option<DateTime>,
47+
pub(super) body: String,
48+
pub(super) state: String,
49+
pub(super) assignees: Vec<String>,
50+
pub(super) labels: Vec<String>,
51+
pub(super) comments: Vec<Comment>,
52+
pub(super) project_items: Vec<String>,
53+
pub(super) project_v2: Option<ProjectV2>,
54+
pub(super) projects_v2: Vec<ProjectV2>,
55+
pub(super) sub_issues: Vec<SubIssue>,
56+
pub(super) parent: Option<ParentIssue>,
57+
pub(super) url: String,
58+
pub(super) closed_by_pull_requests: Vec<PullRequestRef>,
59+
pub(super) created_at: String,
60+
pub(super) updated_at: String,
61+
pub(super) closed_at: Option<String>,
4462
}
4563

4664
#[derive(Debug)]
@@ -116,6 +134,7 @@ pub(super) async fn fetch_periodically(
116134
}
117135
}
118136

137+
#[allow(clippy::too_many_lines)]
119138
async fn send_github_issue_query(
120139
owner: &str,
121140
name: &str,
@@ -148,9 +167,103 @@ async fn send_github_issue_query(
148167
author.clone_from(&on_user.login.clone());
149168
}
150169
issues.push(GitHubIssue {
170+
id: issue.id.clone(),
151171
number: issue.number,
152172
title: issue.title.to_string(),
153173
author,
174+
body: issue.body.clone(),
175+
state: format!("{:?}", issue.state),
176+
assignees: issue.assignees.nodes.iter()
177+
.flat_map(|v| v.iter())
178+
.flatten()
179+
.map(|n| &n.login)
180+
.cloned()
181+
.collect(),
182+
labels: issue.labels.as_ref()
183+
.into_iter()
184+
.flat_map(|l| &l.nodes)
185+
.flatten()
186+
.flatten()
187+
.map(|node| node.name.clone())
188+
.collect(),
189+
comments: issue.comments.nodes.iter().flatten().flatten().map(|comment| Comment {
190+
author: comment.author.as_ref().and_then(|auth| {
191+
match auth {
192+
issues::IssuesRepositoryIssuesNodesCommentsNodesAuthor::User(user) => Some(user.login.clone()),
193+
_ => None,
194+
}
195+
}).unwrap_or_default(),
196+
body: comment.body.clone(),
197+
created_at: comment.created_at.clone(),
198+
id: comment.id.clone(),
199+
repository_name: comment.repository.name.clone(),
200+
updated_at: comment.updated_at.clone(),
201+
url: comment.url.clone(),
202+
}).collect(),
203+
project_items: issue
204+
.project_items
205+
.nodes
206+
.as_ref()
207+
.map(|nodes| nodes.iter().flatten().map(|node| node.id.clone()).collect())
208+
.unwrap_or_default(),
209+
project_v2: issue.project_v2.as_ref().map(|pv2| ProjectV2 {
210+
id: pv2.id.clone(),
211+
title: pv2.title.clone(),
212+
item_count: i32::try_from(pv2.items.total_count).unwrap_or_default(),
213+
}),
214+
projects_v2: issue
215+
.projects_v2
216+
.nodes
217+
.as_ref()
218+
.map(|nodes| nodes.iter().flatten().map(|pv2| ProjectV2 {
219+
id: pv2.id.clone(),
220+
title: pv2.title.clone(),
221+
item_count: i32::try_from(pv2.items.total_count).unwrap_or_default(),
222+
}).collect())
223+
.unwrap_or_default(),
224+
sub_issues: issue.sub_issues.nodes.iter().flatten().flatten().map(|si| SubIssue {
225+
id: si.id.clone(),
226+
number: si.number.try_into().unwrap_or_default(),
227+
title: si.title.clone(),
228+
state: format!("{:?}", si.state),
229+
closed_at: si.closed_at.clone(),
230+
created_at: si.created_at.clone(),
231+
updated_at: si.updated_at.clone(),
232+
author: si.author.as_ref().and_then(|auth| {
233+
match auth {
234+
issues::IssuesRepositoryIssuesNodesSubIssuesNodesAuthor::User(user) => Some(user.login.clone()),
235+
_ => None,
236+
}
237+
}).unwrap_or_default(),
238+
assignees: si.assignees.nodes.iter().flatten().flatten().map(|n| n.login.clone()).collect(),
239+
}).collect(),
240+
parent: issue.parent.as_ref().map(|parent| ParentIssue {
241+
id: parent.id.clone(),
242+
number: i32::try_from(parent.number).unwrap_or_default(),
243+
title: parent.title.clone(),
244+
}),
245+
url: issue.url.clone(),
246+
closed_by_pull_requests: issue.closed_by_pull_requests_references
247+
.as_ref()
248+
.into_iter()
249+
.flat_map(|refs| refs.edges.iter().flatten().flatten())
250+
.filter_map(|edge| edge.node.as_ref().map(|node| PullRequestRef {
251+
number: node.number.try_into().unwrap_or_default(),
252+
state: format!("{:?}", node.state),
253+
closed_at: node.closed_at.clone(),
254+
created_at: node.created_at.clone(),
255+
updated_at: node.updated_at.clone(),
256+
author: node.author.as_ref()
257+
.and_then(|auth| match auth {
258+
issues::IssuesRepositoryIssuesNodesClosedByPullRequestsReferencesEdgesNodeAuthor::User(user) => Some(user.login.clone()),
259+
_ => None,
260+
})
261+
.unwrap_or_default(),
262+
url: node.url.clone(),
263+
}))
264+
.collect(),
265+
created_at: issue.created_at.clone(),
266+
updated_at: issue.updated_at.clone(),
154267
closed_at: issue.closed_at.clone(),
155268
});
156269
}

src/github/issues.graphql

Lines changed: 106 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,21 +20,126 @@ query Issues(
2020
endCursor
2121
}
2222
nodes {
23+
id
2324
number
2425
title
26+
body
2527
state
28+
closedAt
2629
createdAt
2730
updatedAt
28-
closedAt
2931
repository {
3032
name
33+
owner {
34+
__typename
35+
login
36+
}
3137
}
3238
author {
3339
__typename
3440
... on User {
3541
login
3642
}
3743
}
44+
assignees(last: 5) {
45+
nodes {
46+
login
47+
}
48+
}
49+
labels(last: 5) {
50+
nodes {
51+
name
52+
}
53+
}
54+
comments(last: 100) {
55+
totalCount
56+
nodes {
57+
author {
58+
__typename
59+
... on User {
60+
login
61+
}
62+
}
63+
body
64+
createdAt
65+
id
66+
repository {
67+
name
68+
}
69+
updatedAt
70+
url
71+
}
72+
}
73+
projectItems(last: 5) {
74+
totalCount
75+
nodes {
76+
id
77+
}
78+
}
79+
projectV2(number: 4) {
80+
id
81+
title
82+
items(last: 5) {
83+
totalCount
84+
}
85+
}
86+
projectsV2(last: 5) {
87+
totalCount
88+
nodes {
89+
id
90+
title
91+
items(last: 5) {
92+
totalCount
93+
}
94+
}
95+
}
96+
subIssues(last: 20) {
97+
totalCount
98+
nodes {
99+
id
100+
number
101+
title
102+
state
103+
closedAt
104+
createdAt
105+
updatedAt
106+
author {
107+
__typename
108+
... on User {
109+
login
110+
}
111+
}
112+
assignees(last: 5) {
113+
nodes {
114+
login
115+
}
116+
}
117+
}
118+
}
119+
parent {
120+
id
121+
number
122+
title
123+
}
124+
url
125+
closedByPullRequestsReferences(last: 5) {
126+
edges {
127+
node {
128+
number
129+
state
130+
closedAt
131+
createdAt
132+
updatedAt
133+
author {
134+
__typename
135+
... on User {
136+
login
137+
}
138+
}
139+
url
140+
}
141+
}
142+
}
38143
}
39144
}
40145
}

src/graphql.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
mod issue;
1+
pub(crate) mod issue;
22
mod pull_request;
33

44
use std::fmt::Display;

0 commit comments

Comments
 (0)