Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 26 additions & 29 deletions src/plugins/core/deno.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ use serde::Deserialize;
use versions::Versioning;

use crate::backend::Backend;
use crate::backend::platform_target::PlatformTarget;
use crate::cli::args::BackendArg;
use crate::cli::version::OS;
use crate::cmd::CmdLineRunner;
use crate::config::{Config, Settings};
use crate::config::Config;
use crate::http::{HTTP, HTTP_FETCH};
use crate::install_context::InstallContext;
use crate::toolset::{ToolRequest, ToolVersion, Toolset};
Expand Down Expand Up @@ -50,21 +50,16 @@ impl DenoPlugin {
}

async fn download(&self, tv: &ToolVersion, pr: &dyn SingleReport) -> Result<PathBuf> {
let settings = Settings::get();
let url = format!(
"https://dl.deno.land/release/v{}/deno-{}-{}.zip",
tv.version,
arch(&settings),
os()
);
let url = self
.get_tarball_url(tv, &PlatformTarget::from_current())
.await?
.ok_or_else(|| eyre::eyre!("Failed to get deno tarball URL"))?;
let filename = url.split('/').next_back().unwrap();
let tarball_path = tv.download_path().join(filename);

pr.set_message(format!("download {filename}"));
HTTP.download_file(&url, &tarball_path, Some(pr)).await?;

// TODO: hash::ensure_checksum_sha256(&tarball_path, &m.sha256)?;

Ok(tarball_path)
}

Expand Down Expand Up @@ -154,25 +149,27 @@ impl Backend for DenoPlugin {
)]);
Ok(map)
}
}

fn os() -> &'static str {
if cfg!(target_os = "macos") {
"apple-darwin"
} else if cfg!(target_os = "linux") {
"unknown-linux-gnu"
} else if cfg!(target_os = "windows") {
"pc-windows-msvc"
} else {
&OS
}
}

fn arch(settings: &Settings) -> &str {
match settings.arch() {
"x64" => "x86_64",
"arm64" => "aarch64",
other => other,
async fn get_tarball_url(
&self,
tv: &ToolVersion,
target: &PlatformTarget,
) -> Result<Option<String>> {
let arch = match target.arch_name() {
"x64" => "x86_64",
"arm64" => "aarch64",
other => other,
};
let os = match target.os_name() {
"macos" => "apple-darwin",
"linux" => "unknown-linux-gnu",
"windows" => "pc-windows-msvc",
_ => "unknown-linux-gnu",
};
Ok(Some(format!(
"https://dl.deno.land/release/v{}/deno-{}-{}.zip",
tv.version, arch, os
)))
}
}

Expand Down
64 changes: 35 additions & 29 deletions src/plugins/core/go.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ use std::{collections::BTreeMap, sync::Arc};

use crate::Result;
use crate::backend::Backend;
use crate::backend::platform_target::PlatformTarget;
use crate::cli::args::BackendArg;
use crate::cli::version::OS;
use crate::cmd::CmdLineRunner;
use crate::config::{Config, Settings};
use crate::file::{TarFormat, TarOptions};
Expand Down Expand Up @@ -96,15 +96,13 @@ impl GoPlugin {

async fn download(&self, tv: &mut ToolVersion, pr: &dyn SingleReport) -> eyre::Result<PathBuf> {
let settings = Settings::get();
let filename = format!(
"go{}.{}-{}.{}",
tv.version,
platform(),
arch(&settings),
ext()
let tarball_url = Arc::new(
self.get_tarball_url(tv, &PlatformTarget::from_current())
.await?
.ok_or_else(|| eyre::eyre!("Failed to get go tarball URL"))?,
);
let tarball_url = Arc::new(format!("{}/{}", &settings.go_download_mirror, &filename));
let tarball_path = tv.download_path().join(&filename);
let filename = tarball_url.split('/').next_back().unwrap();
let tarball_path = tv.download_path().join(filename);

let tarball_url_ = tarball_url.clone();
let checksum_handle = tokio::spawn(async move {
Expand Down Expand Up @@ -265,26 +263,34 @@ impl Backend for GoPlugin {
) -> eyre::Result<BTreeMap<String, String>> {
self._exec_env(tv)
}
}

fn platform() -> &'static str {
if cfg!(target_os = "macos") {
"darwin"
} else {
&OS
}
}

fn arch(settings: &Settings) -> &str {
match settings.arch() {
"x64" => "amd64",
"arm64" => "arm64",
"arm" => "armv6l",
"riscv64" => "riscv64",
other => other,
async fn get_tarball_url(
&self,
tv: &ToolVersion,
target: &PlatformTarget,
) -> Result<Option<String>> {
let settings = Settings::get();
let platform = match target.os_name() {
"macos" => "darwin",
"linux" => "linux",
"windows" => "windows",
_ => "linux",
};
let arch = match target.arch_name() {
"x64" => "amd64",
"arm64" => "arm64",
"arm" => "armv6l",
"riscv64" => "riscv64",
other => other,
};
let ext = if target.os_name() == "windows" {
"zip"
} else {
"tar.gz"
};
Ok(Some(format!(
"{}/go{}.{}-{}.{}",
&settings.go_download_mirror, tv.version, platform, arch, ext
)))
}
}

fn ext() -> &'static str {
if cfg!(windows) { "zip" } else { "tar.gz" }
}
100 changes: 48 additions & 52 deletions src/plugins/core/zig.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ use std::{
};

use crate::backend::Backend;
use crate::backend::platform_target::PlatformTarget;
use crate::cli::args::BackendArg;
use crate::cli::version::OS;
use crate::cmd::CmdLineRunner;
use crate::config::{Config, Settings};
use crate::duration::DAILY;
Expand Down Expand Up @@ -57,39 +57,10 @@ impl ZigPlugin {

async fn download(&self, tv: &ToolVersion, pr: &dyn SingleReport) -> Result<PathBuf> {
let settings = Settings::get();
let indexes = HashMap::from([
("zig", "https://ziglang.org/download/index.json"),
("mach", "https://machengine.org/zig/index.json"),
]);

let url = if regex!(r"^mach-|-mach$").is_match(&tv.version) {
self.get_tarball_url_from_json(
indexes["mach"],
tv.version.as_str(),
arch(&settings),
os(),
)
let url = self
.get_tarball_url(tv, &PlatformTarget::from_current())
.await?
} else {
self.get_tarball_url_from_json(
indexes["zig"],
tv.version.as_str(),
arch(&settings),
os(),
)
.await
.or_else(|err| {
// We can construct the tarball name for numbered versions without the index
if regex!(r"^\d+\.\d+\.\d+$").is_match(&tv.version) {
let (version, arch, os) = (tv.version.as_str(), arch(&settings), os());
Ok(format!(
"https://ziglang.org/download/{version}/zig-{arch}-{os}-{version}.tar.xz"
))
} else {
Err(err)
}
})?
};
.ok_or_else(|| eyre::eyre!("Failed to resolve zig tarball URL for {}", tv.version))?;

let filename = url.split('/').next_back().unwrap();
let tarball_path = tv.download_path().join(filename);
Expand Down Expand Up @@ -291,26 +262,51 @@ impl Backend for ZigPlugin {
self.verify(ctx, &tv)?;
Ok(tv)
}
}

fn os() -> &'static str {
if cfg!(target_os = "macos") {
"macos"
} else if cfg!(target_os = "linux") {
"linux"
} else if cfg!(target_os = "freebsd") {
"freebsd"
} else {
&OS
}
}
async fn get_tarball_url(
&self,
tv: &ToolVersion,
target: &PlatformTarget,
) -> Result<Option<String>> {
let indexes = HashMap::from([
("zig", "https://ziglang.org/download/index.json"),
("mach", "https://machengine.org/zig/index.json"),
]);

let arch = match target.arch_name() {
"x64" => "x86_64",
"arm64" => "aarch64",
"arm" => "armv7a",
"riscv64" => "riscv64",
other => other,
};
let os = match target.os_name() {
"macos" => "macos",
"linux" => "linux",
"freebsd" => "freebsd",
"windows" => "windows",
_ => "linux",
};

fn arch(settings: &Settings) -> &str {
match settings.arch() {
"x64" => "x86_64",
"arm64" => "aarch64",
"arm" => "armv7a",
"riscv64" => "riscv64",
other => other,
let (json_url, version) = if regex!(r"^mach-|-mach$").is_match(&tv.version) {
(indexes["mach"], tv.version.as_str())
} else {
(indexes["zig"], tv.version.as_str())
};

match self
.get_tarball_url_from_json(json_url, version, arch, os)
.await
{
Ok(url) => Ok(Some(url)),
Err(_) if regex!(r"^\d+\.\d+\.\d+$").is_match(&tv.version) => {
// Fallback: construct URL directly for numbered versions
Ok(Some(format!(
"https://ziglang.org/download/{}/zig-{}-{}-{}.tar.xz",
tv.version, os, arch, tv.version
)))
}
Err(_) => Ok(None),
}
}
}
Loading