1use anyhow::{Context, Result};
2
3pub fn get_bytes(url: &str, token: Option<&str>) -> Result<Vec<u8>> {
5 let mut req = ureq::get(url);
6 if let Some(t) = token {
7 req = req.header("Authorization", &format!("Bearer {}", t));
8 }
9 let response = req.call().with_context(|| format!("GET {}", url))?;
10 let buf = response
11 .into_body()
12 .read_to_vec()
13 .context("reading response body")?;
14 Ok(buf)
15}
16
17pub fn github_latest_tag(owner: &str, repo: &str, token: Option<&str>) -> Result<String> {
19 let url = format!("https://api.github.com/repos/{}/{}/releases/latest", owner, repo);
20 let bytes = get_bytes(&url, token)?;
21 let json: serde_json::Value =
22 serde_json::from_slice(&bytes).context("parsing GitHub release JSON")?;
23 json["tag_name"]
24 .as_str()
25 .map(str::to_string)
26 .with_context(|| "tag_name missing from GitHub release response")
27}
28
29pub fn gitlab_latest_tag(host: &str, project: &str, token: Option<&str>) -> Result<String> {
31 let encoded = urlencoding(project);
32 let url = format!("https://{}/api/v4/projects/{}/releases?per_page=1", host, encoded);
33 let bytes = get_bytes(&url, token)?;
34 let json: serde_json::Value =
35 serde_json::from_slice(&bytes).context("parsing GitLab release JSON")?;
36 json[0]["tag_name"]
37 .as_str()
38 .map(str::to_string)
39 .with_context(|| "tag_name missing from GitLab release response")
40}
41
42fn urlencoding(s: &str) -> String {
43 s.replace('/', "%2F")
44}