mirror of
https://github.com/astral-sh/uv.git
synced 2025-07-07 13:25:00 +00:00
Add an HTTP cache (and --no-cache
argument) (#14)
Closes https://github.com/astral-sh/puffin/issues/3.
This commit is contained in:
parent
1063d8c150
commit
2d6266b167
6 changed files with 31 additions and 23 deletions
|
@ -10,5 +10,3 @@ documentation = "https://astral.sh"
|
|||
repository = "https://github.com/astral-sh/puffin"
|
||||
authors = ["Astral Software Inc. <hey@astral.sh>"]
|
||||
license = "MIT OR Apache-2.0"
|
||||
|
||||
[workspace.dependencies]
|
||||
|
|
|
@ -23,3 +23,4 @@ pep440_rs = { version = "0.3.12" }
|
|||
tracing = { version = "0.1.37" }
|
||||
tracing-tree = { version = "0.2.5" }
|
||||
tracing-subscriber = { version = "0.3.17", features = ["env-filter"] }
|
||||
directories = "5.0.1"
|
||||
|
|
|
@ -29,7 +29,7 @@ enum Response {
|
|||
Version(Metadata21, Requirement),
|
||||
}
|
||||
|
||||
pub(crate) async fn install(src: &Path) -> Result<ExitStatus> {
|
||||
pub(crate) async fn install(src: &Path, cache: Option<&Path>) -> Result<ExitStatus> {
|
||||
// Read the `requirements.txt` from disk.
|
||||
let requirements_txt = std::fs::read_to_string(src)?;
|
||||
|
||||
|
@ -44,8 +44,13 @@ pub(crate) async fn install(src: &Path) -> Result<ExitStatus> {
|
|||
);
|
||||
|
||||
// Instantiate a client.
|
||||
let pypi_client = PypiClientBuilder::default().build();
|
||||
let proxy_client = PypiClientBuilder::default().build();
|
||||
let pypi_client = {
|
||||
let mut pypi_client = PypiClientBuilder::default();
|
||||
if let Some(cache) = cache {
|
||||
pypi_client = pypi_client.cache(cache);
|
||||
}
|
||||
pypi_client.build()
|
||||
};
|
||||
|
||||
// A channel to fetch package metadata (e.g., given `flask`, fetch all versions) and version
|
||||
// metadata (e.g., given `flask==1.0.0`, fetch the metadata for that version).
|
||||
|
@ -60,7 +65,7 @@ pub(crate) async fn install(src: &Path) -> Result<ExitStatus> {
|
|||
.map_ok(move |metadata| Response::Package(metadata, requirement)),
|
||||
),
|
||||
Request::Version(requirement, file) => Either::Right(
|
||||
proxy_client
|
||||
pypi_client
|
||||
.file(file)
|
||||
.map_ok(move |metadata| Response::Version(metadata, requirement)),
|
||||
),
|
||||
|
|
|
@ -3,6 +3,7 @@ use std::process::ExitCode;
|
|||
|
||||
use clap::{Args, Parser, Subcommand};
|
||||
use colored::Colorize;
|
||||
use directories::ProjectDirs;
|
||||
|
||||
use crate::commands::ExitStatus;
|
||||
|
||||
|
@ -27,6 +28,10 @@ enum Commands {
|
|||
struct InstallArgs {
|
||||
/// Path to the `requirements.text` file to install.
|
||||
src: PathBuf,
|
||||
|
||||
/// Avoid reading from or writing to the cache.
|
||||
#[arg(long)]
|
||||
no_cache: bool,
|
||||
}
|
||||
|
||||
#[async_std::main]
|
||||
|
@ -35,8 +40,18 @@ async fn main() -> ExitCode {
|
|||
|
||||
let _ = logging::setup_logging();
|
||||
|
||||
let dirs = ProjectDirs::from("", "", "puffin");
|
||||
|
||||
let result = match &cli.command {
|
||||
Commands::Install(install) => commands::install(&install.src).await,
|
||||
Commands::Install(install) => {
|
||||
commands::install(
|
||||
&install.src,
|
||||
dirs.as_ref()
|
||||
.map(directories::ProjectDirs::cache_dir)
|
||||
.filter(|_| !install.no_cache),
|
||||
)
|
||||
.await
|
||||
}
|
||||
};
|
||||
|
||||
match result {
|
||||
|
|
|
@ -16,8 +16,6 @@ impl PypiClient {
|
|||
&self,
|
||||
package_name: impl AsRef<str>,
|
||||
) -> Result<SimpleJson, PypiClientError> {
|
||||
let start = std::time::Instant::now();
|
||||
|
||||
// Format the URL for PyPI.
|
||||
let mut url = self.registry.join("simple")?;
|
||||
url.path_segments_mut()
|
||||
|
@ -34,12 +32,8 @@ impl PypiClient {
|
|||
|
||||
// Fetch from the registry.
|
||||
let text = self.simple_impl(&package_name, &url).await?;
|
||||
let payload = serde_json::from_str(&text)
|
||||
.map_err(move |e| PypiClientError::from_json_err(e, String::new()));
|
||||
|
||||
trace!("fetched metadata for {} in {:?}", url, start.elapsed());
|
||||
|
||||
payload
|
||||
serde_json::from_str(&text)
|
||||
.map_err(move |e| PypiClientError::from_json_err(e, String::new()))
|
||||
}
|
||||
|
||||
async fn simple_impl(
|
||||
|
@ -69,8 +63,6 @@ impl PypiClient {
|
|||
}
|
||||
|
||||
pub async fn file(&self, file: File) -> Result<Metadata21, PypiClientError> {
|
||||
let start = std::time::Instant::now();
|
||||
|
||||
// Send to the proxy.
|
||||
let url = self.proxy.join(
|
||||
file.url
|
||||
|
@ -82,11 +74,7 @@ impl PypiClient {
|
|||
|
||||
// Fetch from the registry.
|
||||
let text = self.file_impl(&file.filename, &url).await?;
|
||||
let payload = Metadata21::parse(text.as_bytes()).map_err(std::convert::Into::into);
|
||||
|
||||
trace!("fetched file {} in {:?}", url, start.elapsed());
|
||||
|
||||
payload
|
||||
Metadata21::parse(text.as_bytes()).map_err(std::convert::Into::into)
|
||||
}
|
||||
|
||||
async fn file_impl(
|
||||
|
|
|
@ -16,7 +16,8 @@ serde = { version = "1.0.188" }
|
|||
thiserror = { version = "1.0.49" }
|
||||
|
||||
[dev-dependencies]
|
||||
criterion = "0.5.1"
|
||||
criterion = { version = "0.5.1" }
|
||||
insta = { version = "1.33.0" }
|
||||
|
||||
[[bench]]
|
||||
name = "parser"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue