Skip to content

Commit

Permalink
fix: zig on windows
Browse files Browse the repository at this point in the history
  • Loading branch information
jdx committed Dec 20, 2024
1 parent 1221a2f commit d14152a
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 87 deletions.
9 changes: 8 additions & 1 deletion src/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -591,7 +591,7 @@ pub fn un_bz2(input: &Path, dest: &Path) -> Result<()> {
Ok(())
}

#[derive(Default, Clone, Copy, strum::EnumString, strum::Display)]
#[derive(Default, Clone, Copy, PartialEq, strum::EnumString, strum::Display)]
pub enum TarFormat {
#[default]
Auto,
Expand All @@ -603,6 +603,8 @@ pub enum TarFormat {
TarBz2,
#[strum(serialize = "tar.zst")]
TarZst,
#[strum(serialize = "zip")]
Zip,
}

#[derive(Default)]
Expand All @@ -620,6 +622,9 @@ pub fn untar(archive: &Path, dest: &Path, opts: &TarOptions) -> Result<()> {
archive.file_name().unwrap().to_string_lossy()
));
}
if opts.format == TarFormat::Zip {
return unzip(archive, dest);
}
let tar = open_tar(opts.format, archive)?;
let err = || {
let archive = display_path(archive);
Expand Down Expand Up @@ -671,10 +676,12 @@ fn open_tar(format: TarFormat, archive: &Path) -> Result<Box<dyn std::io::Read>>
TarFormat::TarXz => Box::new(xz2::read::XzDecoder::new(f)),
TarFormat::TarBz2 => Box::new(bzip2::read::BzDecoder::new(f)),
TarFormat::TarZst => Box::new(zstd::stream::read::Decoder::new(f)?),
TarFormat::Zip => return Err("zip format not supported".into()),
TarFormat::Auto => match archive.extension().and_then(|s| s.to_str()) {
Some("xz") => open_tar(TarFormat::TarXz, archive)?,
Some("bz2") => open_tar(TarFormat::TarBz2, archive)?,
Some("zst") => open_tar(TarFormat::TarZst, archive)?,
Some("zip") => return Err("zip format not supported".into()),
_ => open_tar(TarFormat::TarGz, archive)?,
},
})
Expand Down
64 changes: 24 additions & 40 deletions src/plugins/core/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,11 @@ use std::ffi::OsString;
use std::sync::Arc;
use std::sync::LazyLock as Lazy;

pub use python::PythonPlugin;

use crate::backend::{Backend, BackendMap};
use crate::cli::args::BackendArg;
use crate::config::SETTINGS;
use crate::env;
use crate::env::PATH_KEY;
use crate::plugins::core::bun::BunPlugin;
use crate::plugins::core::deno::DenoPlugin;
use crate::plugins::core::elixir::ElixirPlugin;
#[cfg(unix)]
use crate::plugins::core::erlang::ErlangPlugin;
use crate::plugins::core::go::GoPlugin;
use crate::plugins::core::java::JavaPlugin;
use crate::plugins::core::node::NodePlugin;
use crate::plugins::core::ruby::RubyPlugin;
use crate::plugins::core::rust::RustPlugin;
use crate::plugins::core::swift::SwiftPlugin;
#[cfg(unix)]
use crate::plugins::core::zig::ZigPlugin;
use crate::timeout::run_with_timeout;
use crate::toolset::ToolVersion;

Expand All @@ -39,39 +24,38 @@ mod python;
mod ruby;
mod rust;
mod swift;
#[cfg(unix)]
mod zig;

pub static CORE_PLUGINS: Lazy<BackendMap> = Lazy::new(|| {
#[cfg(unix)]
let plugins: Vec<Arc<dyn Backend>> = vec![
Arc::new(BunPlugin::new()),
Arc::new(DenoPlugin::new()),
Arc::new(ElixirPlugin::new()),
Arc::new(ErlangPlugin::new()),
Arc::new(GoPlugin::new()),
Arc::new(JavaPlugin::new()),
Arc::new(NodePlugin::new()),
Arc::new(PythonPlugin::new()),
Arc::new(RubyPlugin::new()),
Arc::new(RustPlugin::new()),
Arc::new(SwiftPlugin::new()),
Arc::new(ZigPlugin::new()),
Arc::new(bun::BunPlugin::new()),
Arc::new(deno::DenoPlugin::new()),
Arc::new(elixir::ElixirPlugin::new()),
Arc::new(erlang::ErlangPlugin::new()),
Arc::new(go::GoPlugin::new()),
Arc::new(java::JavaPlugin::new()),
Arc::new(node::NodePlugin::new()),
Arc::new(python::PythonPlugin::new()),
Arc::new(ruby::RubyPlugin::new()),
Arc::new(rust::RustPlugin::new()),
Arc::new(swift::SwiftPlugin::new()),
Arc::new(zig::ZigPlugin::new()),
];
#[cfg(windows)]
let plugins: Vec<Arc<dyn Backend>> = vec![
Arc::new(BunPlugin::new()),
Arc::new(DenoPlugin::new()),
// Arc::new(ErlangPlugin::new()),
Arc::new(ElixirPlugin::new()),
Arc::new(GoPlugin::new()),
Arc::new(JavaPlugin::new()),
Arc::new(NodePlugin::new()),
Arc::new(PythonPlugin::new()),
Arc::new(RubyPlugin::new()),
Arc::new(RustPlugin::new()),
Arc::new(SwiftPlugin::new()),
// Arc::new(ZigPlugin::new()),
Arc::new(bun::BunPlugin::new()),
Arc::new(deno::DenoPlugin::new()),
Arc::new(elixir::ElixirPlugin::new()),
// Arc::new(erlang::ErlangPlugin::new()),
Arc::new(go::GoPlugin::new()),
Arc::new(java::JavaPlugin::new()),
Arc::new(node::NodePlugin::new()),
Arc::new(python::PythonPlugin::new()),
Arc::new(ruby::RubyPlugin::new()),
Arc::new(rust::RustPlugin::new()),
Arc::new(swift::SwiftPlugin::new()),
Arc::new(zig::ZigPlugin::new()),
];
plugins
.into_iter()
Expand Down
82 changes: 36 additions & 46 deletions src/plugins/core/zig.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use eyre::Result;
use itertools::Itertools;
use versions::Versioning;
use xx::regex;
use crate::file::TarOptions;

#[derive(Debug)]
pub struct ZigPlugin {
Expand All @@ -29,7 +30,12 @@ impl ZigPlugin {
}

fn zig_bin(&self, tv: &ToolVersion) -> PathBuf {
tv.install_path().join("zig")
panic!("X");
if cfg!(windows) {
tv.install_path().join("zig.exe")
} else {
tv.install_path().join("bin").join("zig")
}
}

fn test_zig(&self, ctx: &InstallContext, tv: &ToolVersion) -> Result<()> {
Expand All @@ -41,23 +47,28 @@ impl ZigPlugin {
}

fn download(&self, tv: &ToolVersion, pr: &dyn SingleReport) -> Result<PathBuf> {
let archive_ext = if cfg!(target_os = "windows") {
"zip"
} else {
"tar.xz"
};
let url = if tv.version == "ref:master" {
format!(
"https://ziglang.org/builds/zig-{}-{}-{}.tar.xz",
"https://ziglang.org/builds/zig-{}-{}-{}.{archive_ext}",
os(),
arch(),
self.get_master_version()?
)
} else if regex!(r"^[0-9]+\.[0-9]+\.[0-9]+-dev.[0-9]+\+[0-9a-f]+$").is_match(&tv.version) {
format!(
"https://ziglang.org/builds/zig-{}-{}-{}.tar.xz",
"https://ziglang.org/builds/zig-{}-{}-{}.{archive_ext}",
os(),
arch(),
tv.version
)
} else {
format!(
"https://ziglang.org/download/{}/zig-{}-{}-{}.tar.xz",
"https://ziglang.org/download/{}/zig-{}-{}-{}.{archive_ext}",
tv.version,
os(),
arch(),
Expand All @@ -78,25 +89,19 @@ impl ZigPlugin {
let filename = tarball_path.file_name().unwrap().to_string_lossy();
ctx.pr.set_message(format!("extract {filename}"));
file::remove_all(tv.install_path())?;
untar_xy(tarball_path, &tv.download_path())?;
file::rename(
tv.download_path().join(format!(
"zig-{}-{}-{}",
os(),
arch(),
if tv.version == "ref:master" {
self.get_master_version()?
} else {
tv.version.clone()
}
)),
tv.install_path(),
)?;
file::create_dir_all(tv.install_path().join("bin"))?;
file::make_symlink(
self.zig_bin(tv).as_path(),
&tv.install_path().join("bin/zig"),
)?;
file::untar(tarball_path, &tv.download_path(), &TarOptions{
strip_components: 1,
pr: Some(ctx.pr.as_ref()),
..Default::default()
})?;

if cfg!(unix) {
file::create_dir_all(tv.install_path().join("bin"))?;
file::make_symlink(
self.zig_bin(tv).as_path(),
&tv.install_path().join("bin/zig"),
)?;
}

Ok(())
}
Expand Down Expand Up @@ -131,6 +136,14 @@ impl Backend for ZigPlugin {
Ok(versions)
}

fn list_bin_paths(&self, tv: &ToolVersion) -> Result<Vec<PathBuf>> {
if cfg!(windows) {
Ok(vec![tv.install_path()])
} else {
Ok(vec![tv.install_path().join("bin")])
}
}

fn idiomatic_filenames(&self) -> Result<Vec<String>> {
Ok(vec![".zig-version".into()])
}
Expand Down Expand Up @@ -171,26 +184,3 @@ fn arch() -> &'static str {
arch
}
}

pub fn untar_xy(archive: &Path, dest: &Path) -> Result<()> {
let archive = archive
.to_str()
.ok_or(eyre::eyre!("Failed to read archive path"))?;
let dest = dest
.to_str()
.ok_or(eyre::eyre!("Failed to read destination path"))?;

let output = std::process::Command::new("tar")
.arg("-xf")
.arg(archive)
.arg("-C")
.arg(dest)
.output()?;

if !output.status.success() {
let err = String::from_utf8_lossy(&output.stderr);
return Err(eyre::eyre!("Failed to extract tar: {}", err));
}

Ok(())
}

0 comments on commit d14152a

Please sign in to comment.