Skip to content

Commit 4e985d9

Browse files
authored
Merge pull request #45 from tomhoule/github-example
GitHub CLI example
2 parents daf2a19 + 4bb4e22 commit 4e985d9

File tree

5 files changed

+126
-15
lines changed

5 files changed

+126
-15
lines changed

examples/github/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
/target
2+
/.env

examples/github/Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,7 @@ serde = "1.0"
1010
serde_derive = "1.0"
1111
serde_json = "1.0"
1212
reqwest = "*"
13+
prettytable-rs = "0.7.0"
14+
structopt = "0.2.10"
15+
dotenv = "0.13.0"
16+
envy = "0.3.2"

examples/github/README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
11
# graphql-client GitHub API examples
22

33
The schema is taken from [this repo](https://raw.githubusercontent.com/octokit/graphql-schema/master/schema.graphql).
4+
5+
## How to run it
6+
7+
The example expects to find a valid GitHub API Token in the environment (`GITHUB_API_TOKEN`). See the [GitHub documentation](https://developer.github.com/v4/guides/forming-calls/#authenticating-with-graphql) on how to generate one.
8+
9+
Then just run the example with a repository name as argument. For example:
10+
11+
```bash
12+
cargo run -- tomhoule/graphql-client
13+
```

examples/github/src/main.rs

Lines changed: 93 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
extern crate dotenv;
2+
extern crate envy;
3+
#[macro_use]
14
extern crate failure;
25
#[macro_use]
36
extern crate graphql_client;
@@ -6,14 +9,103 @@ extern crate serde;
69
extern crate serde_json;
710
#[macro_use]
811
extern crate serde_derive;
12+
#[macro_use]
13+
extern crate structopt;
14+
#[macro_use]
15+
extern crate prettytable;
916

1017
use graphql_client::*;
18+
use structopt::StructOpt;
1119

1220
#[derive(GraphQLQuery)]
1321
#[gql(schema_path = "src/schema.graphql", query_path = "src/query_1.graphql")]
1422
struct Query1;
1523

24+
#[derive(StructOpt)]
25+
struct Command {
26+
#[structopt(name = "repository")]
27+
repo: String,
28+
}
29+
30+
#[derive(Deserialize, Debug)]
31+
struct Env {
32+
github_api_token: String,
33+
}
34+
35+
fn parse_repo_name(repo_name: &str) -> Result<(&str, &str), failure::Error> {
36+
let mut parts = repo_name.split("/");
37+
match (parts.next(), parts.next()) {
38+
(Some(owner), Some(name)) => Ok((owner, name)),
39+
_ => Err(format_err!("wrong format for the repository name param (we expect something like facebook/graphql)"))
40+
}
41+
}
42+
1643
fn main() -> Result<(), failure::Error> {
17-
let _q = Query1::build_query(query1::Variables);
44+
dotenv::dotenv().ok();
45+
46+
let config: Env = envy::from_env()?;
47+
48+
let args = Command::from_args();
49+
50+
let repo = args.repo;
51+
let (owner, name) = parse_repo_name(&repo).unwrap_or(("tomhoule", "graphql-client"));
52+
53+
let q = Query1::build_query(query1::Variables {
54+
owner: owner.to_string(),
55+
name: name.to_string(),
56+
});
57+
58+
let client = reqwest::Client::new();
59+
60+
let mut res = client
61+
.post("https://api.github.com/graphql")
62+
.header(reqwest::header::Authorization(format!(
63+
"bearer {}",
64+
config.github_api_token
65+
)))
66+
.json(&q)
67+
.send()?;
68+
69+
let response_body: GraphQLResponse<query1::ResponseData> = res.json()?;
70+
let response_data: query1::ResponseData = response_body.data.expect("missing response data");
71+
72+
let stars: Option<i64> = response_data
73+
.repository
74+
.as_ref()
75+
.map(|repo| repo.stargazers.total_count);
76+
77+
println!("{}/{} - 🌟 {}", owner, name, stars.unwrap_or(0),);
78+
79+
let mut table = prettytable::Table::new();
80+
81+
table.add_row(row!(b => "issue", "comments"));
82+
83+
for issue in &response_data
84+
.repository
85+
.expect("missing repository")
86+
.issues
87+
.nodes
88+
.expect("issue nodes is null")
89+
{
90+
if let Some(issue) = issue {
91+
table.add_row(row!(issue.title, issue.comments.total_count));
92+
}
93+
}
94+
95+
table.printstd();
1896
Ok(())
1997
}
98+
99+
#[cfg(test)]
100+
mod tests {
101+
use super::*;
102+
103+
#[test]
104+
fn parse_repo_name_works() {
105+
assert_eq!(
106+
parse_repo_name("tomhoule/graphql-client").unwrap(),
107+
("tomhoule", "graphql-client")
108+
);
109+
assert!(parse_repo_name("abcd").is_err());
110+
}
111+
}

examples/github/src/query_1.graphql

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,21 @@
1-
query OctocatRepos {
2-
repository(owner: "octocat", name: "Hello-World") {
3-
issues(last: 20, states: CLOSED) {
4-
edges {
5-
node {
6-
title
7-
url
8-
labels(first: 5) {
9-
edges {
10-
node {
11-
name
12-
}
13-
}
14-
}
1+
query RepoView($owner: String!, $name: String!) {
2+
repository(owner: $owner, name: $name) {
3+
stargazers {
4+
totalCount
5+
}
6+
issues(first: 20, states: OPEN) {
7+
nodes {
8+
title
9+
comments {
10+
totalCount
11+
}
12+
}
13+
}
14+
pullRequests(first: 20, states: OPEN) {
15+
nodes {
16+
title
17+
commits {
18+
totalCount
1519
}
1620
}
1721
}

0 commit comments

Comments
 (0)