Skip to content

Commit

Permalink
feat: allow listing all versions from github (#2844)
Browse files Browse the repository at this point in the history
  • Loading branch information
jdx authored Oct 27, 2024
1 parent 81a5a10 commit c70eb16
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 5 deletions.
1 change: 1 addition & 0 deletions src/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ pub static MISE_GLOBAL_CONFIG_FILE: Lazy<PathBuf> = Lazy::new(|| {
.unwrap_or_else(|| MISE_CONFIG_DIR.join("config.toml"))
});
pub static MISE_USE_TOML: Lazy<bool> = Lazy::new(|| var_is_true("MISE_USE_TOML"));
pub static MISE_LIST_ALL_VERSIONS: Lazy<bool> = Lazy::new(|| var_is_true("MISE_LIST_ALL_VERSIONS"));
pub static ARGV0: Lazy<String> = Lazy::new(|| ARGS.read().unwrap()[0].to_string());
pub static MISE_BIN_NAME: Lazy<&str> = Lazy::new(|| filename(&ARGV0));
pub static MISE_LOG_FILE: Lazy<Option<PathBuf>> = Lazy::new(|| var_path("MISE_LOG_FILE"));
Expand Down
26 changes: 25 additions & 1 deletion src/github.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
use crate::env;
use reqwest::header::HeaderMap;
use serde_derive::Deserialize;
use xx::regex;

#[derive(Debug, Deserialize)]
pub struct GithubRelease {
Expand All @@ -12,7 +15,18 @@ pub struct GithubRelease {

pub fn list_releases(repo: &str) -> eyre::Result<Vec<GithubRelease>> {
let url = format!("https://api.github.com/repos/{}/releases", repo);
crate::http::HTTP_FETCH.json(url)
let (mut releases, mut headers) =
crate::http::HTTP_FETCH.json_headers::<Vec<GithubRelease>, _>(url)?;

if *env::MISE_LIST_ALL_VERSIONS {
while let Some(next) = next_page(&headers) {
let (more, h) = crate::http::HTTP_FETCH.json_headers::<Vec<GithubRelease>, _>(next)?;
releases.extend(more);
headers = h;
}
}

Ok(releases)
}

pub fn get_release(repo: &str, tag: &str) -> eyre::Result<GithubRelease> {
Expand All @@ -22,3 +36,13 @@ pub fn get_release(repo: &str, tag: &str) -> eyre::Result<GithubRelease> {
);
crate::http::HTTP_FETCH.json(url)
}

fn next_page(headers: &HeaderMap) -> Option<String> {
let link = headers
.get("link")
.map(|l| l.to_str().unwrap_or_default().to_string())
.unwrap_or_default();
regex!(r#"<([^>]+)>; rel="next""#)
.captures(&link)
.map(|c| c.get(1).unwrap().as_str().to_string())
}
17 changes: 13 additions & 4 deletions src/http.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use std::time::Duration;

use eyre::{bail, Report, Result};
use once_cell::sync::Lazy;
use reqwest::header::HeaderMap;
use reqwest::{ClientBuilder, IntoUrl, Response};
use tokio::runtime::Runtime;
use url::Url;
Expand Down Expand Up @@ -98,17 +99,25 @@ impl Client {
Ok(text)
}

pub fn json<T, U: IntoUrl>(&self, url: U) -> Result<T>
pub fn json_headers<T, U: IntoUrl>(&self, url: U) -> Result<(T, HeaderMap)>
where
T: serde::de::DeserializeOwned,
{
let url = url.into_url().unwrap();
let rt = self.runtime()?;
let json = rt.block_on(async {
let (json, headers) = rt.block_on(async {
let resp = self.get(url).await?;
Ok::<T, eyre::Error>(resp.json().await?)
let headers = resp.headers().clone();
Ok::<(T, HeaderMap), eyre::Error>((resp.json().await?, headers))
})?;
Ok(json)
Ok((json, headers))
}

pub fn json<T, U: IntoUrl>(&self, url: U) -> Result<T>
where
T: serde::de::DeserializeOwned,
{
self.json_headers(url).map(|(json, _)| json)
}

pub fn download_file<U: IntoUrl>(
Expand Down

0 comments on commit c70eb16

Please sign in to comment.