avm: Optimize `avm list` when GitHub API rate limits are reached (#2962)

This commit is contained in:
zeroc 2024-05-14 21:07:30 +08:00 committed by GitHub
parent 460869bf10
commit 470731b24c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 27 additions and 9 deletions

View File

@ -14,6 +14,7 @@ The minor version will be incremented upon a breaking change and the patch versi
- idl: Allow overriding the idl build toolchain with the `RUSTUP_TOOLCHAIN` environment variable ([#2941](https://github.com/coral-xyz/anchor/pull/2941])).
- avm: Support customizing the installation location using `AVM_HOME` environment variable ([#2917](https://github.com/coral-xyz/anchor/pull/2917)).
- avm: Optimize `avm list` when GitHub API rate limits are reached ([#2962](https://github.com/coral-xyz/anchor/pull/2962))
- idl, ts: Add accounts resolution for associated token accounts ([#2927](https://github.com/coral-xyz/anchor/pull/2927)).
- cli: Add `--no-install` option to the `init` command ([#2945](https://github.com/coral-xyz/anchor/pull/2945)).

1
Cargo.lock generated
View File

@ -668,6 +668,7 @@ dependencies = [
"anyhow",
"cargo_toml",
"cfg-if",
"chrono",
"clap 4.4.6",
"dirs",
"once_cell",

View File

@ -23,3 +23,4 @@ reqwest = { version = "0.11.9", default-features = false, features = ["blocking"
semver = "1.0.4"
serde = { version = "1.0.136", features = ["derive"] }
tempfile = "3.3.0"
chrono = "0.4"

View File

@ -1,5 +1,6 @@
use anyhow::{anyhow, Result};
use anyhow::{anyhow, Error, Result};
use cargo_toml::Manifest;
use chrono::{TimeZone, Utc};
use once_cell::sync::Lazy;
use reqwest::header::USER_AGENT;
use reqwest::StatusCode;
@ -244,7 +245,7 @@ pub fn read_anchorversion_file() -> Result<Version> {
/// Retrieve a list of installable versions of anchor-cli using the GitHub API and tags on the Anchor
/// repository.
pub fn fetch_versions() -> Result<Vec<Version>> {
pub fn fetch_versions() -> Result<Vec<Version>, Error> {
#[derive(Deserialize)]
struct Release {
#[serde(rename = "name", deserialize_with = "version_deserializer")]
@ -259,16 +260,30 @@ pub fn fetch_versions() -> Result<Vec<Version>> {
Version::parse(s.trim_start_matches('v')).map_err(de::Error::custom)
}
let versions = reqwest::blocking::Client::new()
let response = reqwest::blocking::Client::new()
.get("https://api.github.com/repos/coral-xyz/anchor/tags")
.header(USER_AGENT, "avm https://github.com/coral-xyz/anchor")
.send()?
.json::<Vec<Release>>()?
.into_iter()
.map(|release| release.version)
.collect();
.send()?;
Ok(versions)
if response.status().is_success() {
let releases: Vec<Release> = response.json()?;
let versions = releases.into_iter().map(|r| r.version).collect();
Ok(versions)
} else {
let reset_time_header = response
.headers()
.get("X-RateLimit-Reset")
.map_or("unknown", |v| v.to_str().unwrap());
let t = Utc.timestamp_opt(reset_time_header.parse::<i64>().unwrap(), 0);
let reset_time = t
.single()
.map(|t| t.format("%Y-%m-%d %H:%M:%S").to_string())
.unwrap_or_else(|| "unknown".to_string());
Err(anyhow!(
"GitHub API rate limit exceeded. Try again after {} UTC.",
reset_time
))
}
}
/// Print available versions and flags indicating installed, current and latest