1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-11-21 15:04:11 -05:00
denoland-deno/cli/download_deno_binary.rs
Bartek Iwańczuk 01de331742
perf(upgrade): cache downloaded binaries in DENO_DIR (#26108)
Co-authored-by: Divy Srivastava <dj.srivastava23@gmail.com>
2024-11-09 15:19:46 +00:00

97 lines
2.7 KiB
Rust

// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
use std::path::Path;
use std::path::PathBuf;
use crate::http_util::HttpClient;
use crate::http_util::HttpClientProvider;
use crate::util::progress_bar::ProgressBar;
use crate::util::progress_bar::ProgressBarStyle;
use deno_core::anyhow::bail;
use deno_core::error::AnyError;
use crate::cache::DenoDir;
use crate::shared::ReleaseChannel;
#[derive(Clone, Copy, Debug)]
pub enum BinaryKind {
Deno,
Denort,
}
impl BinaryKind {
pub fn name(&self) -> &str {
match self {
BinaryKind::Deno => "deno",
BinaryKind::Denort => "denort",
}
}
}
pub async fn download_deno_binary(
http_client_provider: &HttpClientProvider,
deno_dir: &DenoDir,
binary_kind: BinaryKind,
target: &str,
version_or_git_hash: &str,
release_channel: ReleaseChannel,
) -> Result<PathBuf, AnyError> {
let binary_name = archive_name(binary_kind, target);
let binary_path_suffix = match release_channel {
ReleaseChannel::Canary => {
format!("canary/{}/{}", version_or_git_hash, binary_name,)
}
_ => {
format!("release/v{}/{}", version_or_git_hash, binary_name)
}
};
let download_directory = deno_dir.dl_folder_path();
let binary_path = download_directory.join(&binary_path_suffix);
if !binary_path.exists() {
let http_client = http_client_provider.get_or_create()?;
download_base_binary(
&http_client,
&download_directory,
&binary_path_suffix,
)
.await?;
}
Ok(binary_path)
}
pub fn archive_name(binary_kind: BinaryKind, target: &str) -> String {
format!("{}-{}.zip", binary_kind.name(), target)
}
async fn download_base_binary(
http_client: &HttpClient,
output_directory: &Path,
binary_path_suffix: &str,
) -> Result<(), AnyError> {
let download_url = format!("https://dl.deno.land/{binary_path_suffix}");
let maybe_bytes = {
let progress_bars = ProgressBar::new(ProgressBarStyle::DownloadBars);
// provide an empty string here in order to prefer the downloading
// text above which will stay alive after the progress bars are complete
let progress = progress_bars.update("");
http_client
.download_with_progress_and_retries(
download_url.parse()?,
None,
&progress,
)
.await?
};
let Some(bytes) = maybe_bytes else {
bail!("Failed downloading {download_url}. The version you requested may not have been built for the current architecture.");
};
std::fs::create_dir_all(output_directory)?;
let output_path = output_directory.join(binary_path_suffix);
std::fs::create_dir_all(output_path.parent().unwrap())?;
tokio::fs::write(output_path, bytes).await?;
Ok(())
}