mirror of
https://github.com/denoland/deno.git
synced 2024-11-24 15:19:26 -05:00
perf(upgrade): cache downloaded binaries in DENO_DIR (#26108)
Co-authored-by: Divy Srivastava <dj.srivastava23@gmail.com>
This commit is contained in:
parent
73fbd61bd0
commit
01de331742
8 changed files with 128 additions and 117 deletions
97
cli/download_deno_binary.rs
Normal file
97
cli/download_deno_binary.rs
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
// 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(())
|
||||||
|
}
|
|
@ -4,6 +4,7 @@ mod args;
|
||||||
mod auth_tokens;
|
mod auth_tokens;
|
||||||
mod cache;
|
mod cache;
|
||||||
mod cdp;
|
mod cdp;
|
||||||
|
mod download_deno_binary;
|
||||||
mod emit;
|
mod emit;
|
||||||
mod errors;
|
mod errors;
|
||||||
mod factory;
|
mod factory;
|
||||||
|
|
|
@ -10,6 +10,7 @@ mod standalone;
|
||||||
mod args;
|
mod args;
|
||||||
mod auth_tokens;
|
mod auth_tokens;
|
||||||
mod cache;
|
mod cache;
|
||||||
|
mod download_deno_binary;
|
||||||
mod emit;
|
mod emit;
|
||||||
mod errors;
|
mod errors;
|
||||||
mod file_fetcher;
|
mod file_fetcher;
|
||||||
|
|
|
@ -63,6 +63,9 @@ use crate::args::NpmInstallDepsProvider;
|
||||||
use crate::args::PermissionFlags;
|
use crate::args::PermissionFlags;
|
||||||
use crate::args::UnstableConfig;
|
use crate::args::UnstableConfig;
|
||||||
use crate::cache::DenoDir;
|
use crate::cache::DenoDir;
|
||||||
|
use crate::download_deno_binary::archive_name;
|
||||||
|
use crate::download_deno_binary::download_deno_binary;
|
||||||
|
use crate::download_deno_binary::BinaryKind;
|
||||||
use crate::emit::Emitter;
|
use crate::emit::Emitter;
|
||||||
use crate::file_fetcher::FileFetcher;
|
use crate::file_fetcher::FileFetcher;
|
||||||
use crate::http_util::HttpClientProvider;
|
use crate::http_util::HttpClientProvider;
|
||||||
|
@ -452,36 +455,24 @@ impl<'a> DenoCompileBinaryWriter<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
let target = compile_flags.resolve_target();
|
let target = compile_flags.resolve_target();
|
||||||
let binary_name = format!("denort-{target}.zip");
|
|
||||||
|
|
||||||
let binary_path_suffix =
|
let archive_name = archive_name(BinaryKind::Denort, &target);
|
||||||
match crate::version::DENO_VERSION_INFO.release_channel {
|
|
||||||
ReleaseChannel::Canary => {
|
|
||||||
format!(
|
|
||||||
"canary/{}/{}",
|
|
||||||
crate::version::DENO_VERSION_INFO.git_hash,
|
|
||||||
binary_name
|
|
||||||
)
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
format!("release/v{}/{}", env!("CARGO_PKG_VERSION"), binary_name)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let download_directory = self.deno_dir.dl_folder_path();
|
let binary_path = download_deno_binary(
|
||||||
let binary_path = download_directory.join(&binary_path_suffix);
|
self.http_client_provider,
|
||||||
|
self.deno_dir,
|
||||||
if !binary_path.exists() {
|
BinaryKind::Denort,
|
||||||
self
|
&target,
|
||||||
.download_base_binary(&download_directory, &binary_path_suffix)
|
crate::version::DENO_VERSION_INFO.version_or_git_hash(),
|
||||||
.await?;
|
crate::version::DENO_VERSION_INFO.release_channel,
|
||||||
}
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
let archive_data = std::fs::read(binary_path)?;
|
let archive_data = std::fs::read(binary_path)?;
|
||||||
let temp_dir = tempfile::TempDir::new()?;
|
let temp_dir = tempfile::TempDir::new()?;
|
||||||
let base_binary_path = archive::unpack_into_dir(archive::UnpackArgs {
|
let base_binary_path = archive::unpack_into_dir(archive::UnpackArgs {
|
||||||
exe_name: "denort",
|
exe_name: BinaryKind::Denort.name(),
|
||||||
archive_name: &binary_name,
|
archive_name: &archive_name,
|
||||||
archive_data: &archive_data,
|
archive_data: &archive_data,
|
||||||
is_windows: target.contains("windows"),
|
is_windows: target.contains("windows"),
|
||||||
dest_path: temp_dir.path(),
|
dest_path: temp_dir.path(),
|
||||||
|
@ -491,41 +482,6 @@ impl<'a> DenoCompileBinaryWriter<'a> {
|
||||||
Ok(base_binary)
|
Ok(base_binary)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn download_base_binary(
|
|
||||||
&self,
|
|
||||||
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);
|
|
||||||
let progress = progress_bars.update(&download_url);
|
|
||||||
|
|
||||||
self
|
|
||||||
.http_client_provider
|
|
||||||
.get_or_create()?
|
|
||||||
.download_with_progress_and_retries(
|
|
||||||
download_url.parse()?,
|
|
||||||
None,
|
|
||||||
&progress,
|
|
||||||
)
|
|
||||||
.await?
|
|
||||||
};
|
|
||||||
let bytes = match maybe_bytes {
|
|
||||||
Some(bytes) => bytes,
|
|
||||||
None => {
|
|
||||||
log::info!("Download could not be found, aborting");
|
|
||||||
std::process::exit(1)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
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(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// This functions creates a standalone deno binary by appending a bundle
|
/// This functions creates a standalone deno binary by appending a bundle
|
||||||
/// and magic trailer to the currently executing binary.
|
/// and magic trailer to the currently executing binary.
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
|
|
|
@ -6,13 +6,14 @@ use crate::args::Flags;
|
||||||
use crate::args::UpgradeFlags;
|
use crate::args::UpgradeFlags;
|
||||||
use crate::args::UPGRADE_USAGE;
|
use crate::args::UPGRADE_USAGE;
|
||||||
use crate::colors;
|
use crate::colors;
|
||||||
|
use crate::download_deno_binary::archive_name;
|
||||||
|
use crate::download_deno_binary::download_deno_binary;
|
||||||
|
use crate::download_deno_binary::BinaryKind;
|
||||||
use crate::factory::CliFactory;
|
use crate::factory::CliFactory;
|
||||||
use crate::http_util::HttpClient;
|
use crate::http_util::HttpClient;
|
||||||
use crate::http_util::HttpClientProvider;
|
use crate::http_util::HttpClientProvider;
|
||||||
use crate::shared::ReleaseChannel;
|
use crate::shared::ReleaseChannel;
|
||||||
use crate::util::archive;
|
use crate::util::archive;
|
||||||
use crate::util::progress_bar::ProgressBar;
|
|
||||||
use crate::util::progress_bar::ProgressBarStyle;
|
|
||||||
use crate::version;
|
use crate::version;
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
|
@ -34,12 +35,8 @@ use std::process::Command;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
const RELEASE_URL: &str = "https://github.com/denoland/deno/releases";
|
static ARCHIVE_NAME: Lazy<String> =
|
||||||
const CANARY_URL: &str = "https://dl.deno.land/canary";
|
Lazy::new(|| archive_name(BinaryKind::Deno, env!("TARGET")));
|
||||||
const DL_RELEASE_URL: &str = "https://dl.deno.land/release";
|
|
||||||
|
|
||||||
pub static ARCHIVE_NAME: Lazy<String> =
|
|
||||||
Lazy::new(|| format!("deno-{}.zip", env!("TARGET")));
|
|
||||||
|
|
||||||
// How often query server for new version. In hours.
|
// How often query server for new version. In hours.
|
||||||
const UPGRADE_CHECK_INTERVAL: i64 = 24;
|
const UPGRADE_CHECK_INTERVAL: i64 = 24;
|
||||||
|
@ -532,13 +529,17 @@ pub async fn upgrade(
|
||||||
return Ok(());
|
return Ok(());
|
||||||
};
|
};
|
||||||
|
|
||||||
let download_url = get_download_url(
|
let binary_path = download_deno_binary(
|
||||||
|
http_client_provider,
|
||||||
|
factory.deno_dir()?,
|
||||||
|
BinaryKind::Deno,
|
||||||
|
env!("TARGET"),
|
||||||
&selected_version_to_upgrade.version_or_hash,
|
&selected_version_to_upgrade.version_or_hash,
|
||||||
requested_version.release_channel(),
|
requested_version.release_channel(),
|
||||||
)?;
|
)
|
||||||
log::info!("{}", colors::gray(format!("Downloading {}", &download_url)));
|
.await?;
|
||||||
let Some(archive_data) = download_package(&client, download_url).await?
|
|
||||||
else {
|
let Ok(archive_data) = tokio::fs::read(&binary_path).await else {
|
||||||
log::error!("Download could not be found, aborting");
|
log::error!("Download could not be found, aborting");
|
||||||
std::process::exit(1)
|
std::process::exit(1)
|
||||||
};
|
};
|
||||||
|
@ -881,48 +882,6 @@ fn base_upgrade_url() -> Cow<'static, str> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_download_url(
|
|
||||||
version: &str,
|
|
||||||
release_channel: ReleaseChannel,
|
|
||||||
) -> Result<Url, AnyError> {
|
|
||||||
let download_url = match release_channel {
|
|
||||||
ReleaseChannel::Stable => {
|
|
||||||
format!("{}/download/v{}/{}", RELEASE_URL, version, *ARCHIVE_NAME)
|
|
||||||
}
|
|
||||||
ReleaseChannel::Rc => {
|
|
||||||
format!("{}/v{}/{}", DL_RELEASE_URL, version, *ARCHIVE_NAME)
|
|
||||||
}
|
|
||||||
ReleaseChannel::Canary => {
|
|
||||||
format!("{}/{}/{}", CANARY_URL, version, *ARCHIVE_NAME)
|
|
||||||
}
|
|
||||||
ReleaseChannel::Lts => {
|
|
||||||
format!("{}/v{}/{}", DL_RELEASE_URL, version, *ARCHIVE_NAME)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Url::parse(&download_url).with_context(|| {
|
|
||||||
format!(
|
|
||||||
"Failed to parse URL to download new release: {}",
|
|
||||||
download_url
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn download_package(
|
|
||||||
client: &HttpClient,
|
|
||||||
download_url: Url,
|
|
||||||
) -> Result<Option<Vec<u8>>, AnyError> {
|
|
||||||
let progress_bar = 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_bar.update("");
|
|
||||||
let maybe_bytes = client
|
|
||||||
.download_with_progress_and_retries(download_url.clone(), None, &progress)
|
|
||||||
.await
|
|
||||||
.with_context(|| format!("Failed downloading {download_url}. The version you requested may not have been built for the current architecture."))?;
|
|
||||||
Ok(maybe_bytes)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn replace_exe(from: &Path, to: &Path) -> Result<(), std::io::Error> {
|
fn replace_exe(from: &Path, to: &Path) -> Result<(), std::io::Error> {
|
||||||
if cfg!(windows) {
|
if cfg!(windows) {
|
||||||
// On windows you cannot replace the currently running executable.
|
// On windows you cannot replace the currently running executable.
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
Current Deno version: [WILDCARD]
|
Current Deno version: [WILDCARD]
|
||||||
Downloading https://github.com/denoland/deno/releases/download/v1.43.2/deno-[WILDCARD].zip
|
|
||||||
Deno is upgrading to version 1.43.2
|
Deno is upgrading to version 1.43.2
|
||||||
|
|
||||||
Upgraded successfully to Deno v1.43.2 (stable)
|
Upgraded successfully to Deno v1.43.2 (stable)
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
Current Deno version: [WILDCARD]
|
Current Deno version: [WILDCARD]
|
||||||
Downloading https://github.com/denoland/deno/releases/download/v1.43.2/deno-[WILDCARD].zip
|
|
||||||
Deno is upgrading to version 1.43.2
|
Deno is upgrading to version 1.43.2
|
||||||
|
|
||||||
Upgraded successfully to Deno v1.43.2 (stable)
|
Upgraded successfully to Deno v1.43.2 (stable)
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
Current Deno version: [WILDCARD]
|
Current Deno version: [WILDCARD]
|
||||||
Downloading https://github.com/denoland/deno/releases/download/v1.43.2/deno-[WILDCARD].zip
|
|
||||||
Deno is upgrading to version 1.43.2
|
Deno is upgrading to version 1.43.2
|
||||||
|
|
||||||
Upgraded successfully to Deno v1.43.2 (stable)
|
Upgraded successfully to Deno v1.43.2 (stable)
|
||||||
|
|
Loading…
Reference in a new issue