My nixos configuration
1use std::{collections::HashMap, fmt::Debug};
2
3use anyhow::{anyhow, Result};
4use graphql_client::{reqwest::post_graphql, GraphQLQuery};
5use reqwest::{
6 header::{HeaderMap, HeaderValue},
7 Client,
8};
9use serde::Deserialize;
10use tracing::instrument;
11
12const ENDPOINT: &str = "https://api.github.com/graphql";
13
14type GitObjectID = String;
15
16#[derive(GraphQLQuery)]
17#[graphql(
18 query_path = "src/github/get_commit_sha.graphql",
19 schema_path = "src/github/schema_gh.graphql",
20 response_derives = "Debug"
21)]
22pub(crate) struct LatestCommit;
23
24#[derive(Deserialize, Clone)]
25struct GhHost {
26 // user: String,
27 oauth_token: String,
28 // git_protocoll: String,
29}
30
31#[instrument]
32pub(crate) async fn get_latest_commit(owner: &str, repo: &str, branch: &str) -> Result<String> {
33 use latest_commit::LatestCommitRepositoryRefTarget::*;
34 use latest_commit::LatestCommitRepositoryRefTargetOnCommit;
35
36 let auth = get_gh_creds();
37
38 let variables = latest_commit::Variables {
39 repo: repo.into(),
40 owner: owner.into(),
41 branch: branch.into(),
42 };
43
44 let mut headers = HeaderMap::new();
45 headers.insert(
46 "Authorization",
47 HeaderValue::from_str(&format!("bearer {}", auth.await?.oauth_token))?,
48 );
49
50 let client = Client::builder()
51 .user_agent("nobbz switcher/0.0")
52 .default_headers(headers)
53 .build()?;
54
55 let target = post_graphql::<LatestCommit, _>(&client, ENDPOINT, variables)
56 .await?
57 .data
58 .ok_or_else(|| anyhow!("missing in response: data"))?
59 .repository
60 .ok_or_else(|| anyhow!("missing in response: repository"))?
61 .ref_
62 .ok_or_else(|| anyhow!("missing in response: ref"))?
63 .target
64 .ok_or_else(|| anyhow!("missing in response: target"))?;
65
66 if let Commit(LatestCommitRepositoryRefTargetOnCommit { oid }) = target {
67 Ok(oid)
68 } else {
69 Err(anyhow!("Not a commit: {:?}", target))
70 }
71}
72
73#[instrument]
74async fn get_gh_creds() -> Result<GhHost> {
75 let home = std::env::var("HOME")?;
76 let path = std::path::Path::new(&home).join(".config/gh/hosts.yml");
77 let f = tokio::fs::File::open(path).await?;
78 let d: HashMap<String, GhHost> = serde_yaml::from_reader(f.into_std().await)?;
79
80 d.get("github.com")
81 .cloned()
82 .ok_or_else(|| anyhow!("Host not configured: github.com"))
83}