Rust 2024 edition (#497)

* build: Bump rust edition and msrv

* style: Format code

* feat: Add unsafe blocks

* feat: Add unsafe blocks for Windows
This commit is contained in:
Sergio Gasquez Arcos 2025-04-29 09:50:59 +02:00 committed by GitHub
parent edc9d64134
commit 1b09495209
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 62 additions and 40 deletions

View File

@ -74,7 +74,7 @@ jobs:
- name: Setup Rust toolchain - name: Setup Rust toolchain
uses: dtolnay/rust-toolchain@stable uses: dtolnay/rust-toolchain@stable
with: with:
toolchain: 1.81.0 toolchain: 1.85.0
- name: Enable caching - name: Enable caching
uses: Swatinem/rust-cache@v2 uses: Swatinem/rust-cache@v2
- name: Cargo check - name: Cargo check

View File

@ -2,7 +2,7 @@
name = "espup" name = "espup"
version = "0.15.0" version = "0.15.0"
authors = ["Sergio Gasquez Arcos <sergio.gasquez@gmail.com>"] authors = ["Sergio Gasquez Arcos <sergio.gasquez@gmail.com>"]
edition = "2021" edition = "2024"
license = "MIT OR Apache-2.0" license = "MIT OR Apache-2.0"
readme = "README.md" readme = "README.md"
repository = "https://github.com/esp-rs/espup" repository = "https://github.com/esp-rs/espup"
@ -11,7 +11,7 @@ Tool for installing and maintaining Espressif Rust ecosystem.
""" """
keywords = ["cli", "embedded", "esp", "esp-rs", "xtensa"] keywords = ["cli", "embedded", "esp", "esp-rs", "xtensa"]
categories = ["command-line-utilities", "development-tools", "embedded"] categories = ["command-line-utilities", "development-tools", "embedded"]
rust-version = "1.81.0" rust-version = "1.85.0"
[dependencies] [dependencies]
async-trait = "0.1.88" async-trait = "0.1.88"

View File

@ -1,7 +1,7 @@
# espup # espup
[![Crates.io](https://img.shields.io/crates/v/espup.svg)](https://crates.io/crates/espup) [![Crates.io](https://img.shields.io/crates/v/espup.svg)](https://crates.io/crates/espup)
![MSRV](https://img.shields.io/badge/MSRV-1.81.0-blue?labelColor=1C2C2E&logo=Rust&style=flat-square) ![MSRV](https://img.shields.io/badge/MSRV-1.85.0-blue?labelColor=1C2C2E&logo=Rust&style=flat-square)
[![Continuous Integration](https://github.com/esp-rs/espup/actions/workflows/ci.yaml/badge.svg)](https://github.com/esp-rs/espup/actions/workflows/ci.yaml) [![Continuous Integration](https://github.com/esp-rs/espup/actions/workflows/ci.yaml/badge.svg)](https://github.com/esp-rs/espup/actions/workflows/ci.yaml)
[![Security audit](https://github.com/esp-rs/espup/actions/workflows/audit.yaml/badge.svg)](https://github.com/esp-rs/espup/actions/workflows/audit.yaml) [![Security audit](https://github.com/esp-rs/espup/actions/workflows/audit.yaml/badge.svg)](https://github.com/esp-rs/espup/actions/workflows/audit.yaml)
[![Matrix](https://img.shields.io/matrix/esp-rs:matrix.org?label=join%20matrix&color=BEC5C9&labelColor=1C2C2E&logo=matrix&style=flat-square)](https://matrix.to/#/#esp-rs:matrix.org) [![Matrix](https://img.shields.io/matrix/esp-rs:matrix.org?label=join%20matrix&color=BEC5C9&labelColor=1C2C2E&logo=matrix&style=flat-square)](https://matrix.to/#/#esp-rs:matrix.org)

View File

@ -1,6 +1,6 @@
//! Command line interface. //! Command line interface.
use crate::targets::{parse_targets, Target}; use crate::targets::{Target, parse_targets};
use clap::Parser; use clap::Parser;
use clap_complete::Shell; use clap_complete::Shell;
use std::{collections::HashSet, path::PathBuf}; use std::{collections::HashSet, path::PathBuf};

View File

@ -11,8 +11,8 @@ use std::{
}; };
#[cfg(windows)] #[cfg(windows)]
use winreg::{ use winreg::{
enums::{HKEY_CURRENT_USER, KEY_READ, KEY_WRITE},
RegKey, RegKey,
enums::{HKEY_CURRENT_USER, KEY_READ, KEY_WRITE},
}; };
#[cfg(windows)] #[cfg(windows)]
@ -26,7 +26,7 @@ pub fn set_env_variable(key: &str, value: &str) -> Result<(), Error> {
use std::ptr; use std::ptr;
use winapi::shared::minwindef::*; use winapi::shared::minwindef::*;
use winapi::um::winuser::{ use winapi::um::winuser::{
SendMessageTimeoutA, HWND_BROADCAST, SMTO_ABORTIFHUNG, WM_SETTINGCHANGE, HWND_BROADCAST, SMTO_ABORTIFHUNG, SendMessageTimeoutA, WM_SETTINGCHANGE,
}; };
let hkcu = RegKey::predef(HKEY_CURRENT_USER); let hkcu = RegKey::predef(HKEY_CURRENT_USER);
@ -61,7 +61,9 @@ pub fn delete_env_variable(key: &str) -> Result<(), Error> {
return Ok(()); return Ok(());
} }
env::remove_var(key); unsafe {
env::remove_var(key);
}
let hkcu = RegKey::predef(HKEY_CURRENT_USER); let hkcu = RegKey::predef(HKEY_CURRENT_USER);
let environment_key = hkcu.open_subkey_with_flags("Environment", KEY_READ | KEY_WRITE)?; let environment_key = hkcu.open_subkey_with_flags("Environment", KEY_READ | KEY_WRITE)?;
@ -164,7 +166,9 @@ pub fn print_post_install_msg(export_file: &Path) -> Result<(), Error> {
"\tA file was created at '{}' showing the injected environment variables", "\tA file was created at '{}' showing the injected environment variables",
export_file.display() export_file.display()
); );
println!("\tIf you get still get errors, try manually adding the environment variables by running '{}'", export_file.display() println!(
"\tIf you get still get errors, try manually adding the environment variables by running '{}'",
export_file.display()
); );
} }
#[cfg(unix)] #[cfg(unix)]
@ -182,7 +186,7 @@ pub fn print_post_install_msg(export_file: &Path) -> Result<(), Error> {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::env::{create_export_file, get_export_file, DEFAULT_EXPORT_FILE}; use crate::env::{DEFAULT_EXPORT_FILE, create_export_file, get_export_file};
use directories::BaseDirs; use directories::BaseDirs;
use std::{ use std::{
env::current_dir, env::current_dir,

View File

@ -24,12 +24,14 @@ pub enum Error {
#[diagnostic(code(espup::ivalid_destination))] #[diagnostic(code(espup::ivalid_destination))]
#[error( #[error(
"Invalid export file destination: '{0}'. Please, use an absolute or releative path (including the file and its extension)")] "Invalid export file destination: '{0}'. Please, use an absolute or releative path (including the file and its extension)"
)]
InvalidDestination(String), InvalidDestination(String),
#[diagnostic(code(espup::toolchain::rust::invalid_version))] #[diagnostic(code(espup::toolchain::rust::invalid_version))]
#[error( #[error(
"Invalid toolchain version '{0}'. Verify that the format is correct: '<major>.<minor>.<patch>.<subpatch>' or '<major>.<minor>.<patch>', and that the release exists in https://github.com/esp-rs/rust-build/releases")] "Invalid toolchain version '{0}'. Verify that the format is correct: '<major>.<minor>.<patch>.<subpatch>' or '<major>.<minor>.<patch>', and that the release exists in https://github.com/esp-rs/rust-build/releases"
)]
InvalidVersion(String), InvalidVersion(String),
#[error(transparent)] #[error(transparent)]

View File

@ -42,7 +42,7 @@ pub fn get_host_triple(host_triple_arg: Option<String>) -> Result<HostTriple, Er
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::host_triple::{get_host_triple, HostTriple}; use crate::host_triple::{HostTriple, get_host_triple};
#[test] #[test]
fn test_get_host_triple() { fn test_get_host_triple() {

View File

@ -36,7 +36,7 @@ pub mod logging {
pub mod update { pub mod update {
use log::warn; use log::warn;
use std::time::Duration; use std::time::Duration;
use update_informer::{registry, Check}; use update_informer::{Check, registry};
/// Check crates.io for a new version of the application /// Check crates.io for a new version of the application
pub fn check_for_update(name: &str, version: &str) { pub fn check_for_update(name: &str, version: &str) {

View File

@ -3,12 +3,12 @@ use espup::{
cli::{CompletionsOpts, InstallOpts, UninstallOpts}, cli::{CompletionsOpts, InstallOpts, UninstallOpts},
logging::initialize_logger, logging::initialize_logger,
toolchain::{ toolchain::{
InstallMode,
gcc::uninstall_gcc_toolchains, gcc::uninstall_gcc_toolchains,
install as toolchain_install, install as toolchain_install,
llvm::Llvm, llvm::Llvm,
remove_dir, remove_dir,
rust::{get_rustup_home, XtensaRust}, rust::{XtensaRust, get_rustup_home},
InstallMode,
}, },
update::check_for_update, update::check_for_update,
}; };

View File

@ -65,7 +65,7 @@ pub fn parse_targets(targets_str: &str) -> Result<HashSet<Target>, Error> {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::targets::{parse_targets, Target}; use crate::targets::{Target, parse_targets};
use std::collections::HashSet; use std::collections::HashSet;
#[test] #[test]

View File

@ -5,7 +5,7 @@ use crate::env::{get_windows_path_var, set_env_variable};
use crate::{ use crate::{
error::Error, error::Error,
host_triple::HostTriple, host_triple::HostTriple,
toolchain::{download_file, Installable}, toolchain::{Installable, download_file},
}; };
use async_trait::async_trait; use async_trait::async_trait;
use log::{debug, info, warn}; use log::{debug, info, warn};
@ -110,9 +110,13 @@ impl Installable for Gcc {
&self.get_bin_path() &self.get_bin_path()
)); ));
if self.arch == RISCV_GCC { if self.arch == RISCV_GCC {
env::set_var("RISCV_GCC", self.get_bin_path()); unsafe {
env::set_var("RISCV_GCC", self.get_bin_path());
}
} else { } else {
env::set_var("XTENSA_GCC", self.get_bin_path()); unsafe {
env::set_var("XTENSA_GCC", self.get_bin_path());
}
} }
} }
#[cfg(unix)] #[cfg(unix)]

View File

@ -5,7 +5,7 @@ use crate::env::{delete_env_variable, get_windows_path_var, set_env_variable};
use crate::{ use crate::{
error::Error, error::Error,
host_triple::HostTriple, host_triple::HostTriple,
toolchain::{download_file, rust::RE_EXTENDED_SEMANTIC_VERSION, Installable}, toolchain::{Installable, download_file, rust::RE_EXTENDED_SEMANTIC_VERSION},
}; };
use async_trait::async_trait; use async_trait::async_trait;
#[cfg(unix)] #[cfg(unix)]
@ -335,8 +335,10 @@ impl Installable for Llvm {
"$Env:PATH = \"{};\" + $Env:PATH", "$Env:PATH = \"{};\" + $Env:PATH",
self.get_lib_path() self.get_lib_path()
)); ));
env::set_var("LIBCLANG_BIN_PATH", self.get_lib_path()); unsafe {
env::set_var("LIBCLANG_PATH", libclang_dll); env::set_var("LIBCLANG_BIN_PATH", self.get_lib_path());
env::set_var("LIBCLANG_PATH", libclang_dll);
}
} }
#[cfg(unix)] #[cfg(unix)]
if cfg!(unix) { if cfg!(unix) {
@ -365,7 +367,9 @@ impl Installable for Llvm {
#[cfg(windows)] #[cfg(windows)]
if cfg!(windows) { if cfg!(windows) {
exports.push(format!("$Env:CLANG_PATH = \"{}\"", self.get_bin_path())); exports.push(format!("$Env:CLANG_PATH = \"{}\"", self.get_bin_path()));
env::set_var("CLANG_PATH", self.get_bin_path()); unsafe {
env::set_var("CLANG_PATH", self.get_bin_path());
}
} }
#[cfg(unix)] #[cfg(unix)]
exports.push(format!("export CLANG_PATH=\"{}\"", self.get_bin_path())); exports.push(format!("export CLANG_PATH=\"{}\"", self.get_bin_path()));

View File

@ -11,7 +11,7 @@ use crate::{
toolchain::{ toolchain::{
gcc::{Gcc, RISCV_GCC, XTENSA_GCC}, gcc::{Gcc, RISCV_GCC, XTENSA_GCC},
llvm::Llvm, llvm::Llvm,
rust::{check_rust_installation, get_rustup_home, RiscVTarget, XtensaRust}, rust::{RiscVTarget, XtensaRust, check_rust_installation, get_rustup_home},
}, },
}; };
use async_trait::async_trait; use async_trait::async_trait;
@ -22,14 +22,14 @@ use reqwest::{blocking::Client, header};
use retry::{delay::Fixed, retry}; use retry::{delay::Fixed, retry};
use std::{ use std::{
env, env,
fs::{create_dir_all, remove_file, File}, fs::{File, create_dir_all, remove_file},
io::{copy, Write}, io::{Write, copy},
path::{Path, PathBuf}, path::{Path, PathBuf},
sync::atomic::{self, AtomicUsize}, sync::atomic::{self, AtomicUsize},
}; };
use tar::Archive; use tar::Archive;
use tokio::{fs::remove_dir_all, sync::mpsc}; use tokio::{fs::remove_dir_all, sync::mpsc};
use tokio_retry::{strategy::FixedInterval, Retry}; use tokio_retry::{Retry, strategy::FixedInterval};
use tokio_stream::StreamExt; use tokio_stream::StreamExt;
use xz2::read::XzDecoder; use xz2::read::XzDecoder;
use zip::ZipArchive; use zip::ZipArchive;

View File

@ -4,11 +4,10 @@ use crate::{
error::Error, error::Error,
host_triple::HostTriple, host_triple::HostTriple,
toolchain::{ toolchain::{
download_file, Installable, download_file,
gcc::{RISCV_GCC, XTENSA_GCC}, gcc::{RISCV_GCC, XTENSA_GCC},
github_query, github_query,
llvm::CLANG_NAME, llvm::CLANG_NAME,
Installable,
}, },
}; };
use async_trait::async_trait; use async_trait::async_trait;
@ -208,10 +207,10 @@ impl Installable for XtensaRust {
let output = String::from_utf8_lossy(&rustc_version.stdout); let output = String::from_utf8_lossy(&rustc_version.stdout);
if rustc_version.status.success() && output.contains(&self.version) { if rustc_version.status.success() && output.contains(&self.version) {
warn!( warn!(
"Previous installation of Xtensa Rust {} exists in: '{}'. Reusing this installation", "Previous installation of Xtensa Rust {} exists in: '{}'. Reusing this installation",
&self.version, &self.version,
&self.toolchain_destination.display() &self.toolchain_destination.display()
); );
return Ok(vec![]); return Ok(vec![]);
} else { } else {
if !rustc_version.status.success() { if !rustc_version.status.success() {
@ -359,7 +358,8 @@ impl RiscVTarget {
impl Installable for RiscVTarget { impl Installable for RiscVTarget {
async fn install(&self) -> Result<Vec<String>, Error> { async fn install(&self) -> Result<Vec<String>, Error> {
info!( info!(
"Installing RISC-V Rust targets ('riscv32imc-unknown-none-elf', 'riscv32imac-unknown-none-elf' and 'riscv32imafc-unknown-none-elf') for '{}' toolchain", &self.stable_version "Installing RISC-V Rust targets ('riscv32imc-unknown-none-elf', 'riscv32imac-unknown-none-elf' and 'riscv32imafc-unknown-none-elf') for '{}' toolchain",
&self.stable_version
); );
if !Command::new("rustup") if !Command::new("rustup")
@ -449,7 +449,7 @@ pub async fn check_rust_installation() -> Result<(), Error> {
mod tests { mod tests {
use crate::{ use crate::{
logging::initialize_logger, logging::initialize_logger,
toolchain::rust::{get_cargo_home, get_rustup_home, XtensaRust}, toolchain::rust::{XtensaRust, get_cargo_home, get_rustup_home},
}; };
use directories::BaseDirs; use directories::BaseDirs;
use std::env; use std::env;
@ -475,7 +475,9 @@ mod tests {
#[test] #[test]
fn test_get_cargo_home() { fn test_get_cargo_home() {
// No CARGO_HOME set // No CARGO_HOME set
env::remove_var("CARGO_HOME"); unsafe {
env::remove_var("CARGO_HOME");
}
assert_eq!( assert_eq!(
get_cargo_home(), get_cargo_home(),
BaseDirs::new().unwrap().home_dir().join(".cargo") BaseDirs::new().unwrap().home_dir().join(".cargo")
@ -483,14 +485,18 @@ mod tests {
// CARGO_HOME set // CARGO_HOME set
let temp_dir = TempDir::new().unwrap(); let temp_dir = TempDir::new().unwrap();
let cargo_home = temp_dir.path().to_path_buf(); let cargo_home = temp_dir.path().to_path_buf();
env::set_var("CARGO_HOME", cargo_home.to_str().unwrap()); unsafe {
env::set_var("CARGO_HOME", cargo_home.to_str().unwrap());
}
assert_eq!(get_cargo_home(), cargo_home); assert_eq!(get_cargo_home(), cargo_home);
} }
#[test] #[test]
fn test_get_rustup_home() { fn test_get_rustup_home() {
// No RUSTUP_HOME set // No RUSTUP_HOME set
env::remove_var("RUSTUP_HOME"); unsafe {
env::remove_var("RUSTUP_HOME");
}
assert_eq!( assert_eq!(
get_rustup_home(), get_rustup_home(),
BaseDirs::new().unwrap().home_dir().join(".rustup") BaseDirs::new().unwrap().home_dir().join(".rustup")
@ -498,7 +504,9 @@ mod tests {
// RUSTUP_HOME set // RUSTUP_HOME set
let temp_dir = TempDir::new().unwrap(); let temp_dir = TempDir::new().unwrap();
let rustup_home = temp_dir.path().to_path_buf(); let rustup_home = temp_dir.path().to_path_buf();
env::set_var("RUSTUP_HOME", rustup_home.to_str().unwrap()); unsafe {
env::set_var("RUSTUP_HOME", rustup_home.to_str().unwrap());
}
assert_eq!(get_rustup_home(), rustup_home); assert_eq!(get_rustup_home(), rustup_home);
} }
} }