download package (badly)

This commit is contained in:
nora 2022-05-15 14:07:52 +02:00
parent b4bc82f7e4
commit f9c5a18720
6 changed files with 327 additions and 97 deletions

79
src/resolve.rs Normal file
View file

@ -0,0 +1,79 @@
use std::{
collections::HashMap,
sync::{Arc, RwLock},
};
use color_eyre::{eyre::bail, Result};
use node_semver::Range;
use tracing::{debug, info};
use crate::{download::PackageMeta, NpmClient, WrapErr};
pub struct ResolveContext {
meta_cache: Arc<RwLock<HashMap<String, Arc<PackageMeta>>>>,
client: NpmClient,
}
impl ResolveContext {
pub fn new() -> Self {
Self {
meta_cache: Arc::new(Default::default()),
client: NpmClient::default(),
}
}
async fn get_meta(&self, name: &str) -> Result<Arc<PackageMeta>> {
{
let cache_read = self.meta_cache.read().unwrap();
if let Some(meta) = cache_read.get(name) {
return Ok(Arc::clone(meta));
}
}
debug!("Fetching package info..");
// two futures might race here - who cares
let meta = self
.client
.fetch_package_meta(name)
.await
.wrap_err("fetching package metadata")?;
let meta = Arc::new(meta);
let mut cache_write = self.meta_cache.write().unwrap();
cache_write.insert(name.to_owned(), Arc::clone(&meta));
Ok(meta)
}
#[tracing::instrument(skip(self, requested_version), fields(requested_version = %requested_version))]
pub async fn download_package_and_deps(
&self,
name: &str,
requested_version: &Range,
) -> Result<()> {
let meta = self.get_meta(name).await?;
info!(versions = ?meta.versions.keys().map(ToString::to_string).collect::<Vec<_>>());
let chosen = meta
.versions
.keys()
.filter(|version| version.satisfies(requested_version))
.max();
match chosen {
Some(version) => {
info!(%version, "Found version");
self.client
.download_package(name, &meta.versions[version].dist.tarball)
.await
.wrap_err("downloading package")?;
}
None => bail!("could not find matching version for '{requested_version}'"),
}
Ok(())
}
}