mirror of
https://github.com/cargo-bins/cargo-binstall.git
synced 2025-04-22 05:28:42 +00:00

* Bump simple-git to v0.2.10 Signed-off-by: Jiahao XU <Jiahao_XU@outlook.com> * Fix v1 manifest format for git and local path Fixed #1815 Signed-off-by: Jiahao XU <Jiahao_XU@outlook.com> * Fix v1 format for custom registry Signed-off-by: Jiahao XU <Jiahao_XU@outlook.com> * Remove unused functions Signed-off-by: Jiahao XU <Jiahao_XU@outlook.com> * Fix compilation Signed-off-by: Jiahao XU <Jiahao_XU@outlook.com> * Update git.sh Signed-off-by: Jiahao XU <30436523+NobodyXu@users.noreply.github.com> * Fixed git.sh for windows Signed-off-by: Jiahao XU <30436523+NobodyXu@users.noreply.github.com> * fixx git.sh for win Signed-off-by: Jiahao XU <30436523+NobodyXu@users.noreply.github.com> * Update git.sh Signed-off-by: Jiahao XU <30436523+NobodyXu@users.noreply.github.com> * fix git.sh Signed-off-by: Jiahao XU <30436523+NobodyXu@users.noreply.github.com> --------- Signed-off-by: Jiahao XU <Jiahao_XU@outlook.com> Signed-off-by: Jiahao XU <30436523+NobodyXu@users.noreply.github.com>
119 lines
3.3 KiB
Rust
119 lines
3.3 KiB
Rust
use std::fmt::Display;
|
|
|
|
use binstalk_downloader::remote::{Client, Error as RemoteError};
|
|
use binstalk_types::cargo_toml_binstall::Meta;
|
|
use cargo_toml_workspace::cargo_toml::Manifest;
|
|
use compact_str::CompactString;
|
|
use semver::VersionReq;
|
|
use serde_json::Deserializer as JsonDeserializer;
|
|
use tokio::sync::OnceCell;
|
|
use tracing::instrument;
|
|
use url::Url;
|
|
|
|
use crate::{
|
|
crate_prefix_components, parse_manifest, render_dl_template, MatchedVersion, RegistryConfig,
|
|
RegistryError,
|
|
};
|
|
|
|
#[derive(Debug)]
|
|
pub struct SparseRegistry {
|
|
url: Url,
|
|
dl_template: OnceCell<CompactString>,
|
|
}
|
|
|
|
impl SparseRegistry {
|
|
/// * `url` - `url.cannot_be_a_base()` must be `false`
|
|
pub fn new(url: Url) -> Self {
|
|
Self {
|
|
url,
|
|
dl_template: Default::default(),
|
|
}
|
|
}
|
|
|
|
pub fn url(&self) -> impl Display + '_ {
|
|
&self.url
|
|
}
|
|
|
|
async fn get_dl_template(&self, client: &Client) -> Result<&str, RegistryError> {
|
|
self.dl_template
|
|
.get_or_try_init(|| {
|
|
Box::pin(async {
|
|
let mut url = self.url.clone();
|
|
url.path_segments_mut().unwrap().push("config.json");
|
|
let config: RegistryConfig = client.get(url).send(true).await?.json().await?;
|
|
Ok(config.dl)
|
|
})
|
|
})
|
|
.await
|
|
.map(AsRef::as_ref)
|
|
}
|
|
|
|
/// `url` must be a valid http(s) url.
|
|
async fn find_crate_matched_ver(
|
|
client: &Client,
|
|
mut url: Url,
|
|
crate_name: &str,
|
|
(c1, c2): &(CompactString, Option<CompactString>),
|
|
version_req: &VersionReq,
|
|
) -> Result<MatchedVersion, RegistryError> {
|
|
{
|
|
let mut path = url.path_segments_mut().unwrap();
|
|
|
|
path.push(c1);
|
|
if let Some(c2) = c2 {
|
|
path.push(c2);
|
|
}
|
|
|
|
path.push(&crate_name.to_lowercase());
|
|
}
|
|
|
|
let body = client
|
|
.get(url)
|
|
.send(true)
|
|
.await
|
|
.map_err(|e| match e {
|
|
RemoteError::Http(e) if e.is_status() => RegistryError::NotFound(crate_name.into()),
|
|
e => e.into(),
|
|
})?
|
|
.bytes()
|
|
.await
|
|
.map_err(RegistryError::from)?;
|
|
MatchedVersion::find(
|
|
&mut JsonDeserializer::from_slice(&body).into_iter(),
|
|
version_req,
|
|
)
|
|
}
|
|
|
|
#[instrument(
|
|
skip(self, client, version_req),
|
|
fields(
|
|
registry_url = format_args!("{}", self.url),
|
|
version_req = format_args!("{version_req}"),
|
|
)
|
|
)]
|
|
pub async fn fetch_crate_matched(
|
|
&self,
|
|
client: Client,
|
|
crate_name: &str,
|
|
version_req: &VersionReq,
|
|
) -> Result<Manifest<Meta>, RegistryError> {
|
|
let crate_prefix = crate_prefix_components(crate_name)?;
|
|
let dl_template = self.get_dl_template(&client).await?;
|
|
let matched_version = Self::find_crate_matched_ver(
|
|
&client,
|
|
self.url.clone(),
|
|
crate_name,
|
|
&crate_prefix,
|
|
version_req,
|
|
)
|
|
.await?;
|
|
let dl_url = Url::parse(&render_dl_template(
|
|
dl_template,
|
|
crate_name,
|
|
&crate_prefix,
|
|
&matched_version,
|
|
)?)?;
|
|
|
|
parse_manifest(client, crate_name, dl_url, matched_version).await
|
|
}
|
|
}
|