mirror of
https://github.com/cargo-bins/cargo-binstall.git
synced 2025-06-15 15:16:37 +00:00
report to new stats server, with status
This commit is contained in:
parent
ae13308dec
commit
3b58930c4a
4 changed files with 61 additions and 8 deletions
|
@ -25,7 +25,7 @@ static WARN_RATE_LIMIT_ONCE: Once = Once::new();
|
||||||
static WARN_UNAUTHORIZED_ONCE: Once = Once::new();
|
static WARN_UNAUTHORIZED_ONCE: Once = Once::new();
|
||||||
|
|
||||||
/// Return Ok(Some(api_artifact_url)) if exists, or Ok(None) if it doesn't.
|
/// Return Ok(Some(api_artifact_url)) if exists, or Ok(None) if it doesn't.
|
||||||
///
|
///
|
||||||
/// Caches info on all artifacts matching (repo, tag).
|
/// Caches info on all artifacts matching (repo, tag).
|
||||||
pub(super) async fn get_gh_release_artifact_url(
|
pub(super) async fn get_gh_release_artifact_url(
|
||||||
gh_api_client: GhApiClient,
|
gh_api_client: GhApiClient,
|
||||||
|
@ -58,7 +58,7 @@ pub(super) async fn get_gh_release_artifact_url(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check if the URL exists by querying the GitHub API.
|
/// Check if the URL exists by querying the GitHub API.
|
||||||
///
|
///
|
||||||
/// Caches info on all artifacts matching (repo, tag).
|
/// Caches info on all artifacts matching (repo, tag).
|
||||||
///
|
///
|
||||||
/// This function returns a future where its size should be at most size of
|
/// This function returns a future where its size should be at most size of
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use std::{
|
use std::{
|
||||||
borrow::Cow,
|
borrow::Cow,
|
||||||
path::Path,
|
path::Path,
|
||||||
sync::{Arc, OnceLock},
|
sync::{Arc, Mutex, OnceLock},
|
||||||
};
|
};
|
||||||
|
|
||||||
use binstalk_downloader::remote::Method;
|
use binstalk_downloader::remote::Method;
|
||||||
|
@ -16,7 +16,8 @@ use crate::{
|
||||||
};
|
};
|
||||||
|
|
||||||
const BASE_URL: &str = "https://github.com/cargo-bins/cargo-quickinstall/releases/download";
|
const BASE_URL: &str = "https://github.com/cargo-bins/cargo-quickinstall/releases/download";
|
||||||
pub const QUICK_INSTALL_STATS_URL: &str = "https://warehouse-clerk-tmp.vercel.app/api/crate";
|
pub const QUICK_INSTALL_STATS_URL: &str =
|
||||||
|
"https://cargo-quickinstall-stats-server.fly.dev/record-install";
|
||||||
|
|
||||||
const QUICKINSTALL_SIGN_KEY: Cow<'static, str> =
|
const QUICKINSTALL_SIGN_KEY: Cow<'static, str> =
|
||||||
Cow::Borrowed("RWTdnnab2pAka9OdwgCMYyOE66M/BlQoFWaJ/JjwcPV+f3n24IRTj97t");
|
Cow::Borrowed("RWTdnnab2pAka9OdwgCMYyOE66M/BlQoFWaJ/JjwcPV+f3n24IRTj97t");
|
||||||
|
@ -58,6 +59,7 @@ pub struct QuickInstall {
|
||||||
gh_api_client: GhApiClient,
|
gh_api_client: GhApiClient,
|
||||||
is_supported_v: OnceCell<bool>,
|
is_supported_v: OnceCell<bool>,
|
||||||
|
|
||||||
|
data: Arc<Data>,
|
||||||
package: String,
|
package: String,
|
||||||
package_url: Url,
|
package_url: Url,
|
||||||
signature_url: Url,
|
signature_url: Url,
|
||||||
|
@ -67,6 +69,30 @@ pub struct QuickInstall {
|
||||||
target_data: Arc<TargetDataErased>,
|
target_data: Arc<TargetDataErased>,
|
||||||
|
|
||||||
signature_verifier: OnceLock<SignatureVerifier>,
|
signature_verifier: OnceLock<SignatureVerifier>,
|
||||||
|
status: Mutex<Status>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
enum Status {
|
||||||
|
Start,
|
||||||
|
NotFound,
|
||||||
|
Found,
|
||||||
|
AttemptingInstall,
|
||||||
|
InvalidSignature,
|
||||||
|
InstalledFromTarball,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Status {
|
||||||
|
fn as_str(&self) -> &'static str {
|
||||||
|
match self {
|
||||||
|
Status::Start => "start",
|
||||||
|
Status::NotFound => "not-found",
|
||||||
|
Status::Found => "found",
|
||||||
|
Status::AttemptingInstall => "attempting-install",
|
||||||
|
Status::InvalidSignature => "invalid-signature",
|
||||||
|
Status::InstalledFromTarball => "installed-from-tarball",
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl QuickInstall {
|
impl QuickInstall {
|
||||||
|
@ -116,6 +142,14 @@ impl QuickInstall {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_status(&self) -> Status {
|
||||||
|
*self.status.lock().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_status(&self, status: Status) {
|
||||||
|
*self.status.lock().unwrap() = status;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait::async_trait]
|
#[async_trait::async_trait]
|
||||||
|
@ -137,6 +171,7 @@ impl super::Fetcher for QuickInstall {
|
||||||
|
|
||||||
Arc::new(Self {
|
Arc::new(Self {
|
||||||
client,
|
client,
|
||||||
|
data,
|
||||||
gh_api_client,
|
gh_api_client,
|
||||||
is_supported_v: OnceCell::new(),
|
is_supported_v: OnceCell::new(),
|
||||||
|
|
||||||
|
@ -144,7 +179,7 @@ impl super::Fetcher for QuickInstall {
|
||||||
.expect("package_url is pre-generated and should never be invalid url"),
|
.expect("package_url is pre-generated and should never be invalid url"),
|
||||||
signature_url: Url::parse(&format!("{url}.sig"))
|
signature_url: Url::parse(&format!("{url}.sig"))
|
||||||
.expect("signature_url is pre-generated and should never be invalid url"),
|
.expect("signature_url is pre-generated and should never be invalid url"),
|
||||||
stats_url: Url::parse(&format!("{QUICK_INSTALL_STATS_URL}/{package}.tar.gz",))
|
stats_url: Url::parse("{QUICK_INSTALL_STATS_URL}")
|
||||||
.expect("stats_url is pre-generated and should never be invalid url"),
|
.expect("stats_url is pre-generated and should never be invalid url"),
|
||||||
package,
|
package,
|
||||||
signature_policy,
|
signature_policy,
|
||||||
|
@ -152,6 +187,7 @@ impl super::Fetcher for QuickInstall {
|
||||||
target_data,
|
target_data,
|
||||||
|
|
||||||
signature_verifier: OnceLock::new(),
|
signature_verifier: OnceLock::new(),
|
||||||
|
status: Mutex::new(Status::Start),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,6 +207,7 @@ impl super::Fetcher for QuickInstall {
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
if !is_found {
|
if !is_found {
|
||||||
|
self.set_status(Status::NotFound);
|
||||||
return Ok(false);
|
return Ok(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -182,6 +219,7 @@ impl super::Fetcher for QuickInstall {
|
||||||
panic!("<QuickInstall as Fetcher>::find is run twice");
|
panic!("<QuickInstall as Fetcher>::find is run twice");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.set_status(Status::Found);
|
||||||
Ok(true)
|
Ok(true)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -209,6 +247,7 @@ by rust officially."#,
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn fetch_and_extract(&self, dst: &Path) -> Result<ExtractedFiles, FetchError> {
|
async fn fetch_and_extract(&self, dst: &Path) -> Result<ExtractedFiles, FetchError> {
|
||||||
|
self.set_status(Status::AttemptingInstall);
|
||||||
let Some(verifier) = self.signature_verifier.get() else {
|
let Some(verifier) = self.signature_verifier.get() else {
|
||||||
panic!("<QuickInstall as Fetcher>::find has not been called yet!")
|
panic!("<QuickInstall as Fetcher>::find has not been called yet!")
|
||||||
};
|
};
|
||||||
|
@ -227,8 +266,10 @@ by rust officially."#,
|
||||||
if let Some(info) = verifier.info() {
|
if let Some(info) = verifier.info() {
|
||||||
info!("Verified signature for package '{}': {info}", self.package);
|
info!("Verified signature for package '{}': {info}", self.package);
|
||||||
}
|
}
|
||||||
|
self.set_status(Status::InstalledFromTarball);
|
||||||
Ok(files)
|
Ok(files)
|
||||||
} else {
|
} else {
|
||||||
|
self.set_status(Status::InvalidSignature);
|
||||||
Err(FetchError::InvalidSignature)
|
Err(FetchError::InvalidSignature)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -280,10 +321,19 @@ impl QuickInstall {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
let url = self.stats_url.clone();
|
let mut url = self.stats_url.clone();
|
||||||
|
url.query_pairs_mut()
|
||||||
|
.append_pair("crate", &self.data.name)
|
||||||
|
.append_pair("version", &self.data.version)
|
||||||
|
.append_pair("target", &self.target_data.target)
|
||||||
|
.append_pair(
|
||||||
|
"agent",
|
||||||
|
concat!(env!("CARGO_PKG_NAME"), "/", env!("CARGO_PKG_VERSION")),
|
||||||
|
)
|
||||||
|
.append_pair("status", self.get_status().as_str());
|
||||||
debug!("Sending installation report to quickinstall ({url})");
|
debug!("Sending installation report to quickinstall ({url})");
|
||||||
|
|
||||||
self.client.request(Method::HEAD, url).send(true).await?;
|
self.client.request(Method::POST, url).send(true).await?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -247,7 +247,7 @@ pub struct GhReleaseArtifactUrl(Url);
|
||||||
|
|
||||||
impl GhApiClient {
|
impl GhApiClient {
|
||||||
/// Return `Ok(Some(api_artifact_url))` if exists.
|
/// Return `Ok(Some(api_artifact_url))` if exists.
|
||||||
///
|
///
|
||||||
/// Caches info on all artifacts matching (repo, tag).
|
/// Caches info on all artifacts matching (repo, tag).
|
||||||
///
|
///
|
||||||
/// The returned future is guaranteed to be pointer size.
|
/// The returned future is guaranteed to be pointer size.
|
||||||
|
|
|
@ -203,6 +203,7 @@ async fn resolve_inner(
|
||||||
{
|
{
|
||||||
Ok(bin_files) => {
|
Ok(bin_files) => {
|
||||||
if !bin_files.is_empty() {
|
if !bin_files.is_empty() {
|
||||||
|
fetcher.report_to_upstream();
|
||||||
return Ok(Resolution::Fetch(Box::new(ResolutionFetch {
|
return Ok(Resolution::Fetch(Box::new(ResolutionFetch {
|
||||||
fetcher: fetcher.clone(),
|
fetcher: fetcher.clone(),
|
||||||
new_version: package_info.version,
|
new_version: package_info.version,
|
||||||
|
@ -250,6 +251,8 @@ async fn resolve_inner(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// At this point, we don't know whether fallback to cargo install is allowed, or whether it will
|
||||||
|
// succeed, but things start to get convoluted when try to include that data, so this will do.
|
||||||
if !opts.disable_telemetry {
|
if !opts.disable_telemetry {
|
||||||
for fetcher in handles {
|
for fetcher in handles {
|
||||||
fetcher.report_to_upstream();
|
fetcher.report_to_upstream();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue