mirror of
https://github.com/cargo-bins/cargo-binstall.git
synced 2025-06-17 08:06:38 +00:00
Impl new API GhApiClient::get_repo_info
Signed-off-by: Jiahao XU <Jiahao_XU@outlook.com>
This commit is contained in:
parent
f824ebbd9c
commit
0bc4231b65
2 changed files with 110 additions and 13 deletions
|
@ -186,6 +186,21 @@ impl GhApiClient {
|
||||||
.map_err(|err| err.context("Restful API"))
|
.map_err(|err| err.context("Restful API"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn get_repo_info(&self, repo: &GhRepo) -> Result<Option<RepoInfo>, GhApiError> {
|
||||||
|
match self
|
||||||
|
.do_fetch(
|
||||||
|
repo_info::fetch_repo_info_graphql_api,
|
||||||
|
repo_info::fetch_repo_info_restful_api,
|
||||||
|
repo,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
Ok(repo_info) => Ok(repo_info),
|
||||||
|
Err(GhApiError::NotFound) => Ok(None),
|
||||||
|
Err(err) => Err(err),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Return `Ok(Some(api_artifact_url))` if exists.
|
/// Return `Ok(Some(api_artifact_url))` if exists.
|
||||||
///
|
///
|
||||||
/// The returned future is guaranteed to be pointer size.
|
/// The returned future is guaranteed to be pointer size.
|
||||||
|
@ -350,17 +365,21 @@ mod test {
|
||||||
let _ = set_global_default(subscriber);
|
let _ = set_global_default(subscriber);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Mark this as an async fn so that you won't accidentally use it in
|
fn create_remote_client() -> remote::Client {
|
||||||
/// sync context.
|
remote::Client::new(
|
||||||
async fn create_client() -> Vec<GhApiClient> {
|
|
||||||
let client = remote::Client::new(
|
|
||||||
concat!(env!("CARGO_PKG_NAME"), "/", env!("CARGO_PKG_VERSION")),
|
concat!(env!("CARGO_PKG_NAME"), "/", env!("CARGO_PKG_VERSION")),
|
||||||
None,
|
None,
|
||||||
NonZeroU16::new(10).unwrap(),
|
NonZeroU16::new(10).unwrap(),
|
||||||
1.try_into().unwrap(),
|
1.try_into().unwrap(),
|
||||||
[],
|
[],
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Mark this as an async fn so that you won't accidentally use it in
|
||||||
|
/// sync context.
|
||||||
|
async fn create_client() -> Vec<GhApiClient> {
|
||||||
|
let client = create_remote_client();
|
||||||
|
|
||||||
let mut gh_clients = vec![GhApiClient::new(client.clone(), None)];
|
let mut gh_clients = vec![GhApiClient::new(client.clone(), None)];
|
||||||
|
|
||||||
|
@ -371,6 +390,42 @@ mod test {
|
||||||
gh_clients
|
gh_clients
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn test_repo_info_public(repo: GhRepo, repo_info: Option<RepoInfo>) {
|
||||||
|
init_logger();
|
||||||
|
|
||||||
|
for client in create_client().await {
|
||||||
|
eprintln!("In client {client:?}");
|
||||||
|
|
||||||
|
let res = client.get_repo_info(&repo).await;
|
||||||
|
|
||||||
|
if matches!(res, Err(GhApiError::RateLimit { .. })) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_eq!(res.unwrap(), repo_info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn test_repo_info_private(repo: GhRepo) {
|
||||||
|
init_logger();
|
||||||
|
|
||||||
|
let Ok(token) = env::var("GITHUB_TOKEN") else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
let client = GhApiClient::new(create_remote_client(), Some(token.into()));
|
||||||
|
|
||||||
|
eprintln!("In client {client:?}");
|
||||||
|
|
||||||
|
let res = client.get_repo_info(&repo).await;
|
||||||
|
|
||||||
|
if matches!(res, Err(GhApiError::RateLimit { .. })) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_eq!(res.unwrap(), Some(RepoInfo::new(repo, true)));
|
||||||
|
}
|
||||||
|
|
||||||
async fn test_specific_release(release: &GhRelease, artifacts: &[&str]) {
|
async fn test_specific_release(release: &GhRelease, artifacts: &[&str]) {
|
||||||
init_logger();
|
init_logger();
|
||||||
|
|
||||||
|
@ -407,6 +462,33 @@ mod test {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_gh_api_client_cargo_binstall() {
|
||||||
|
let repo = GhRepo {
|
||||||
|
owner: "cargo-bins".to_compact_string(),
|
||||||
|
repo: "cargo-binstall".to_compact_string(),
|
||||||
|
};
|
||||||
|
test_repo_info_public(repo.clone(), Some(RepoInfo::new(repo, false))).await
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_gh_api_client_non_existent_repo() {
|
||||||
|
let repo = GhRepo {
|
||||||
|
owner: "cargo-bins".to_compact_string(),
|
||||||
|
repo: "ttt".to_compact_string(),
|
||||||
|
};
|
||||||
|
test_repo_info_public(repo.clone(), None).await
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_gh_api_client_private_repo() {
|
||||||
|
let repo = GhRepo {
|
||||||
|
owner: "cargo-bins".to_compact_string(),
|
||||||
|
repo: "private-repo-for-testing".to_compact_string(),
|
||||||
|
};
|
||||||
|
test_repo_info_private(repo.clone()).await
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn test_gh_api_client_cargo_binstall_v0_20_1() {
|
async fn test_gh_api_client_cargo_binstall_v0_20_1() {
|
||||||
test_specific_release(
|
test_specific_release(
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
use std::future::Future;
|
||||||
|
|
||||||
use compact_str::CompactString;
|
use compact_str::CompactString;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
|
@ -6,12 +8,12 @@ use super::{
|
||||||
remote, GhApiError, GhRepo,
|
remote, GhApiError, GhRepo,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Clone, Eq, PartialEq, Hash, Debug, Deserialize)]
|
||||||
struct Owner {
|
struct Owner {
|
||||||
login: CompactString,
|
login: CompactString,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Clone, Eq, PartialEq, Hash, Debug, Deserialize)]
|
||||||
pub struct RepoInfo {
|
pub struct RepoInfo {
|
||||||
owner: Owner,
|
owner: Owner,
|
||||||
name: CompactString,
|
name: CompactString,
|
||||||
|
@ -19,6 +21,14 @@ pub struct RepoInfo {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RepoInfo {
|
impl RepoInfo {
|
||||||
|
#[cfg(test)]
|
||||||
|
pub(crate) fn new(GhRepo { owner, repo }: GhRepo, private: bool) -> Self {
|
||||||
|
Self {
|
||||||
|
owner: Owner { login: owner },
|
||||||
|
name: repo,
|
||||||
|
private,
|
||||||
|
}
|
||||||
|
}
|
||||||
pub fn repo(&self) -> GhRepo {
|
pub fn repo(&self) -> GhRepo {
|
||||||
GhRepo {
|
GhRepo {
|
||||||
owner: self.owner.login.clone(),
|
owner: self.owner.login.clone(),
|
||||||
|
@ -31,11 +41,11 @@ impl RepoInfo {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) async fn fetch_repo_info_restful_api(
|
pub(super) fn fetch_repo_info_restful_api(
|
||||||
client: &remote::Client,
|
client: &remote::Client,
|
||||||
GhRepo { owner, repo }: &GhRepo,
|
GhRepo { owner, repo }: &GhRepo,
|
||||||
) -> Result<RepoInfo, GhApiError> {
|
) -> impl Future<Output = Result<Option<RepoInfo>, GhApiError>> + Send + Sync + 'static {
|
||||||
issue_restful_api(client, &["repos", owner, repo]).await
|
issue_restful_api(client, &["repos", owner, repo])
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
|
@ -43,11 +53,11 @@ struct GraphQLData {
|
||||||
repository: Option<RepoInfo>,
|
repository: Option<RepoInfo>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) async fn fetch_repo_info_graphql_api(
|
pub(super) fn fetch_repo_info_graphql_api(
|
||||||
client: &remote::Client,
|
client: &remote::Client,
|
||||||
GhRepo { owner, repo }: &GhRepo,
|
GhRepo { owner, repo }: &GhRepo,
|
||||||
auth_token: &str,
|
auth_token: &str,
|
||||||
) -> Result<RepoInfo, GhApiError> {
|
) -> impl Future<Output = Result<Option<RepoInfo>, GhApiError>> + Send + Sync + 'static {
|
||||||
let query = format!(
|
let query = format!(
|
||||||
r#"
|
r#"
|
||||||
query {{
|
query {{
|
||||||
|
@ -61,5 +71,10 @@ query {{
|
||||||
}}"#
|
}}"#
|
||||||
);
|
);
|
||||||
|
|
||||||
issue_graphql_query(client, query, auth_token).await
|
let future = issue_graphql_query(client, query, auth_token);
|
||||||
|
|
||||||
|
async move {
|
||||||
|
let data: GraphQLData = future.await?;
|
||||||
|
Ok(data.repository)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue