diff --git a/src/lib.rs b/src/lib.rs index b6b4f08..0b41728 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -140,7 +140,9 @@ fn rmain(config: &mut Config) -> Result<()> { if !no_message_format { cargo.arg("--message-format").arg("json-render-diagnostics"); } - for arg in args { + + let args = args.collect::>(); + for arg in args.clone() { if let Some(arg) = arg.to_str() { if arg.starts_with("--verbose") || arg.starts_with("-v") { config.set_verbose(true); @@ -178,8 +180,13 @@ fn rmain(config: &mut Config) -> Result<()> { let mut check_deps = false; match subcommand { Subcommand::DownloadToolchain => { + let version = args + .first() + .cloned() + .map(|v| v.into_string().unwrap().into()) + .unwrap_or(toolchain::ToolchainSpec::Latest); let _lock = Config::acquire_lock()?; - let chain = toolchain::install_prebuilt_toolchain(&Config::toolchain_dir()?)?; + let chain = toolchain::install_prebuilt_toolchain(&Config::toolchain_dir()?, version)?; config.info(&format!( "Toolchain {} downloaded and installed to path {}.\nThe wasix toolchain is now ready to use.", chain.name, diff --git a/src/toolchain.rs b/src/toolchain.rs index c0469f7..b0988e0 100644 --- a/src/toolchain.rs +++ b/src/toolchain.rs @@ -6,6 +6,7 @@ //! * Build the whole toolchain use std::{ + fmt::Display, path::{Path, PathBuf}, process::Command, }; @@ -530,8 +531,43 @@ struct GithubAsset { name: String, } +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum ToolchainSpec { + Latest, + Version(String), +} + +impl Display for ToolchainSpec { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + ToolchainSpec::Latest => write!(f, "latest"), + ToolchainSpec::Version(v) => write!(f, "{v}"), + } + } +} + +impl From for ToolchainSpec { + fn from(value: String) -> Self { + if value == "latest" { + ToolchainSpec::Latest + } else { + ToolchainSpec::Version(value) + } + } +} + +impl ToolchainSpec { + pub fn is_latest(&self) -> bool { + *self == ToolchainSpec::Latest + } +} + /// Download a pre-built toolchain from Github releases. -fn download_toolchain(target: &str, toolchains_root_dir: &Path) -> Result { +fn download_toolchain( + target: &str, + toolchains_root_dir: &Path, + toolchain_spec: ToolchainSpec, +) -> Result { let mut headers = HeaderMap::new(); // Use api token if specified via env var. @@ -553,9 +589,16 @@ fn download_toolchain(target: &str, toolchains_root_dir: &Path) -> Result Result Result { +pub fn install_prebuilt_toolchain( + toolchain_dir: &Path, + toolchain_spec: ToolchainSpec, +) -> Result { if let Some(target) = guess_host_target() { - match download_toolchain(target, toolchain_dir) { + match download_toolchain(target, toolchain_dir, toolchain_spec) { Ok(path) => RustupToolchain::link(RUSTUP_TOOLCHAIN_NAME, &path.join("rust")), Err(err) => { eprintln!("Could not download pre-built toolchain: {err:?}"); @@ -804,7 +850,7 @@ pub fn ensure_toolchain(config: &Config, is64bit: bool) -> Result