From 711b7a7a5e6117da2a70ecc860c24f0e30dfdcce Mon Sep 17 00:00:00 2001 From: zhom <2717306+zhom@users.noreply.github.com> Date: Mon, 28 Jul 2025 02:11:31 +0400 Subject: [PATCH] chore: linting --- .github/workflows/test.yml | 8 +-- .gitignore | 24 ++++++- build.rs | 4 +- scripts/format.sh | 3 + src/bundler.rs | 62 +++++++++---------- src/executable.rs | 16 ++--- src/main.rs | 3 +- src/node_downloader.rs | 10 +-- src/node_version_manager.rs | 8 ++- src/platform.rs | 14 ++--- tests/common/mod.rs | 34 +++++----- .../concurrent_execution_integration_test.rs | 51 ++++++--------- tests/integration_test.rs | 40 ++++++------ tests/workspace_integration_test.rs | 2 +- tests/workspace_version_integration_test.rs | 14 ++--- 15 files changed, 152 insertions(+), 141 deletions(-) create mode 100755 scripts/format.sh diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index c0959d5..267c136 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -63,16 +63,16 @@ jobs: run: cargo fmt --all -- --check - name: Run Clippy - run: cargo clippy --target ${{ matrix.target }} --all-targets --all-features -- -D warnings + run: cargo clippy --all-targets --all-features -- -D warnings - name: Build - run: cargo build --target ${{ matrix.target }} --verbose + run: cargo build --verbose - name: Run tests - run: cargo test --target ${{ matrix.target }} --verbose + run: cargo test --verbose - name: Build release - run: cargo build --target ${{ matrix.target }} --release --verbose + run: cargo build --release --verbose # Test installation from crates.io simulation install-test: diff --git a/.gitignore b/.gitignore index ea8c4bf..9e69566 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,23 @@ -/target +# Generated by Cargo +# will have compiled files and executables +debug +target + +# These are backup files generated by rustfmt +**/*.rs.bk + +# MSVC Windows builds of rustc generate these, which store debugging information +*.pdb + +# Generated by cargo mutants +# Contains mutation testing data +**/mutants.out*/ + +# RustRover +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +#.idea/ + +.DS_Store \ No newline at end of file diff --git a/build.rs b/build.rs index 91f9002..b86daf7 100644 --- a/build.rs +++ b/build.rs @@ -9,7 +9,7 @@ fn main() { // Write platform info for runtime use fs::write(Path::new(&out_dir).join("platform"), platform.to_string()).unwrap(); - println!("cargo:rustc-env=NODE_VERSION={}", NODE_VERSION); + println!("cargo:rustc-env=NODE_VERSION={NODE_VERSION}"); println!("cargo:rerun-if-changed=build.rs"); } @@ -47,6 +47,6 @@ fn get_platform() -> Platform { ("macos", "aarch64") => Platform::MacosArm64, ("windows", "x86_64") => Platform::WindowsX64, ("windows", "aarch64") => Platform::WindowsArm64, - _ => panic!("Unsupported platform: {}-{}", os, arch), + _ => panic!("Unsupported platform: {os}-{arch}"), } } diff --git a/scripts/format.sh b/scripts/format.sh new file mode 100755 index 0000000..218e728 --- /dev/null +++ b/scripts/format.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +cargo clippy --fix --allow-dirty --all-targets --all-features -- -D warnings -D clippy::all && cargo fmt --all \ No newline at end of file diff --git a/src/bundler.rs b/src/bundler.rs index 40d7749..972cc75 100644 --- a/src/bundler.rs +++ b/src/bundler.rs @@ -49,9 +49,10 @@ pub async fn bundle_project( let source_dir = determine_source_directory(&project_path, &package_value)?; - let node_version = detect_node_version_with_workspace_support(&project_path, ignore_cached_versions) - .await - .unwrap_or_else(|_| "22.17.1".into()); + let node_version = + detect_node_version_with_workspace_support(&project_path, ignore_cached_versions) + .await + .unwrap_or_else(|_| "22.17.1".into()); println!( "Bundling {app_name} v{app_version} using Node.js v{node_version} for {plat}", @@ -120,7 +121,7 @@ where if let Some(main) = package_value["main"].as_str() { let main_path = project_path.join(main); - if let Ok(relative_to_source) = main_path.strip_prefix(&source_dir) { + if let Ok(relative_to_source) = main_path.strip_prefix(source_dir) { package_value["main"] = Value::String(relative_to_source.to_string_lossy().to_string()); } @@ -141,7 +142,7 @@ where } for warning in &deps_result.warnings { - println!("Warning: {}", warning); + println!("Warning: {warning}"); } Ok(()) @@ -172,7 +173,7 @@ where let is_pnpm_workspace = if package_manager == PackageManager::Pnpm { if let Ok(entries) = fs::read_dir(&project_node_modules) { entries.flatten().any(|entry| { - if entry.file_type().ok().map_or(false, |ft| ft.is_symlink()) { + if entry.file_type().ok().is_some_and(|ft| ft.is_symlink()) { if let Ok(target) = fs::read_link(entry.path()) { let target_str = target.to_string_lossy(); target_str.contains("/.pnpm/") && target_str.starts_with("../") @@ -324,7 +325,7 @@ fn detect_package_manager(node_modules_path: &Path, project_path: &Path) -> Pack if node_modules_path.exists() { if let Ok(entries) = fs::read_dir(node_modules_path) { for entry in entries.flatten() { - if entry.file_type().ok().map_or(false, |ft| ft.is_symlink()) { + if entry.file_type().ok().is_some_and(|ft| ft.is_symlink()) { if let Ok(target) = fs::read_link(entry.path()) { let target_str = target.to_string_lossy(); if target_str.contains("/.pnpm/") { @@ -407,7 +408,7 @@ where if let Err(e) = copy_pnpm_package_comprehensive(zip, &node_modules_path, &pnpm_dir, package_name, opts) { - println!("Warning: Failed to copy package {}: {}", package_name, e); + println!("Warning: Failed to copy package {package_name}: {e}"); } } @@ -704,7 +705,7 @@ where package_name, opts, ) { - println!("Warning: Failed to copy package {}: {}", package_name, e); + println!("Warning: Failed to copy package {package_name}: {e}"); } } } else { @@ -727,7 +728,7 @@ where for package_name in &resolved_packages { if let Err(e) = copy_workspace_package(zip, node_modules_path, package_name, opts) { - println!("Warning: Failed to copy package {}: {}", package_name, e); + println!("Warning: Failed to copy package {package_name}: {e}"); } } } @@ -804,7 +805,7 @@ where for package_name in &resolved_packages { if let Err(e) = copy_workspace_package(zip, node_modules_path, package_name, opts) { - println!("Warning: Failed to copy package {}: {}", package_name, e); + println!("Warning: Failed to copy package {package_name}: {e}"); } } @@ -887,7 +888,7 @@ where package_name, opts, ) { - println!("Warning: Failed to copy package {}: {}", package_name, e); + println!("Warning: Failed to copy package {package_name}: {e}"); } } @@ -917,15 +918,17 @@ async fn detect_node_version_with_workspace_support( ) -> Result { let version_manager = NodeVersionManager::new(); let version_spec = find_node_version_spec(project_path)?; - - version_manager.resolve_version(&version_spec, ignore_cached_versions).await + + version_manager + .resolve_version(&version_spec, ignore_cached_versions) + .await } /// Find Node version specification from .nvmrc or .node-version files, /// supporting workspace packages (parent/package, parent/packages/package patterns) fn find_node_version_spec(project_path: &Path) -> Result { let mut current_path = project_path; - + loop { for file in [".nvmrc", ".node-version"] { let version_file = current_path.join(file); @@ -938,32 +941,27 @@ fn find_node_version_spec(project_path: &Path) -> Result { } } } - + if is_workspace_root(current_path) || current_path.parent().is_none() { break; } - + current_path = current_path.parent().unwrap(); } - + anyhow::bail!("Node version specification not found in project or workspace hierarchy") } /// Check if a directory is a workspace root (contains workspace configuration) fn is_workspace_root(path: &Path) -> bool { - let workspace_files = [ - "pnpm-workspace.yaml", - "lerna.json", - "rush.json", - "nx.json", - ]; - + let workspace_files = ["pnpm-workspace.yaml", "lerna.json", "rush.json", "nx.json"]; + for file in workspace_files { if path.join(file).exists() { return true; } } - + if let Ok(package_json_content) = fs::read_to_string(path.join("package.json")) { if let Ok(package_json) = serde_json::from_str::(&package_json_content) { if package_json.get("workspaces").is_some() { @@ -971,7 +969,7 @@ fn is_workspace_root(path: &Path) -> bool { } } } - + false } @@ -1011,10 +1009,11 @@ fn determine_source_directory(project_path: &Path, package_json: &Value) -> Resu for dir_name in ["dist", "build", "lib", "out"] { let dir_path = project_path.join(dir_name); - if dir_path.exists() && dir_path.is_dir() { - if contains_js_files(&dir_path) || dir_path.join("package.json").exists() { - return Ok(dir_path); - } + if dir_path.exists() + && dir_path.is_dir() + && (contains_js_files(&dir_path) || dir_path.join("package.json").exists()) + { + return Ok(dir_path); } } @@ -1119,7 +1118,6 @@ fn resolve_output_path( // Self-extracting executable generation using a more reliable approach // ──────────────────────────────────────────────────────────────────────────── - // ──────────────────────────────────────────────────────────────────────────── // Utility helpers // ──────────────────────────────────────────────────────────────────────────── diff --git a/src/executable.rs b/src/executable.rs index 4458963..fd5e32a 100644 --- a/src/executable.rs +++ b/src/executable.rs @@ -7,7 +7,11 @@ use std::path::Path; use uuid::Uuid; /// Create a self-extracting executable for the current platform -pub fn create_self_extracting_executable(out: &Path, zip_data: Vec, _app_name: &str) -> Result<()> { +pub fn create_self_extracting_executable( + out: &Path, + zip_data: Vec, + _app_name: &str, +) -> Result<()> { let build_id = Uuid::new_v4(); if Platform::current().is_windows() { @@ -36,7 +40,7 @@ else CACHE_DIR="/tmp/banderole-cache" fi -APP_DIR="$CACHE_DIR/{}" +APP_DIR="$CACHE_DIR/{build_id}" READY_FILE="$APP_DIR/.ready" run_app() {{ @@ -112,8 +116,7 @@ echo "Error: Failed to extract or run application after $MAX_ATTEMPTS attempts" exit 1 __DATA__ -"#, - build_id +"# ); file.write_all(script.as_bytes())?; @@ -141,7 +144,7 @@ fn create_windows_executable(out: &Path, zip_data: Vec, build_id: &str) -> R setlocal enabledelayedexpansion set "CACHE_DIR=%LOCALAPPDATA%\banderole" -set "APP_DIR=!CACHE_DIR!\{}" +set "APP_DIR=!CACHE_DIR!\{build_id}" set "LOCK_FILE=!APP_DIR!\.lock" set "READY_FILE=!APP_DIR!\.ready" set "QUEUE_DIR=!APP_DIR!\.queue" @@ -267,8 +270,7 @@ rmdir "!LOCK_FILE!" 2>nul goto run_app __DATA__ -"#, - build_id +"# ); file.write_all(script.as_bytes())?; diff --git a/src/main.rs b/src/main.rs index 0505a22..f6ccdce 100644 --- a/src/main.rs +++ b/src/main.rs @@ -52,7 +52,8 @@ async fn main() -> anyhow::Result<()> { no_compression, ignore_cached_versions, } => { - bundler::bundle_project(path, output, name, no_compression, ignore_cached_versions).await?; + bundler::bundle_project(path, output, name, no_compression, ignore_cached_versions) + .await?; } } diff --git a/src/node_downloader.rs b/src/node_downloader.rs index 5ccd5ed..85837e7 100644 --- a/src/node_downloader.rs +++ b/src/node_downloader.rs @@ -29,14 +29,10 @@ impl NodeDownloader { .resolve_version(version_spec, false) .await .context(format!( - "Failed to resolve Node.js version '{}'", - version_spec + "Failed to resolve Node.js version '{version_spec}'" ))?; - println!( - "Resolved '{}' to Node.js version {}", - version_spec, resolved_version - ); + println!("Resolved '{version_spec}' to Node.js version {resolved_version}"); Ok(Self { platform: Platform::current(), @@ -236,7 +232,7 @@ impl NodeDownloader { async fn extract_tar_gz(&self, archive_path: &Path, target_dir: &Path) -> Result<()> { let output = tokio::process::Command::new("tar") - .args(&[ + .args([ "-xzf", archive_path.to_str().unwrap(), "-C", diff --git a/src/node_version_manager.rs b/src/node_version_manager.rs index 785cf12..1caa953 100644 --- a/src/node_version_manager.rs +++ b/src/node_version_manager.rs @@ -135,7 +135,11 @@ impl NodeVersionManager { } /// Resolve a version specification like "23", "23.5", "v22.1.0" to a complete version - pub async fn resolve_version(&self, version_spec: &str, ignore_cached_versions: bool) -> Result { + pub async fn resolve_version( + &self, + version_spec: &str, + ignore_cached_versions: bool, + ) -> Result { let versions = self.fetch_versions(ignore_cached_versions).await?; let parsed_spec = self.parse_version_spec(version_spec)?; @@ -332,7 +336,7 @@ mod tests { // This test requires internet connection if let Ok(version) = resolver.resolve_version("18", false).await { assert!(version.starts_with("18.")); - println!("Resolved '18' to: {}", version); + println!("Resolved '18' to: {version}"); } } } diff --git a/src/platform.rs b/src/platform.rs index e0e2860..f1faae2 100644 --- a/src/platform.rs +++ b/src/platform.rs @@ -23,18 +23,18 @@ impl Platform { ("macos", "aarch64") => Platform::MacosArm64, ("windows", "x86_64") => Platform::WindowsX64, ("windows", "aarch64") => Platform::WindowsArm64, - _ => panic!("Unsupported platform: {}-{}", os, arch), + _ => panic!("Unsupported platform: {os}-{arch}"), } } pub fn node_archive_name(&self, version: &str) -> String { match self { - Platform::LinuxX64 => format!("node-v{}-linux-x64.tar.gz", version), - Platform::LinuxArm64 => format!("node-v{}-linux-arm64.tar.gz", version), - Platform::MacosX64 => format!("node-v{}-darwin-x64.tar.gz", version), - Platform::MacosArm64 => format!("node-v{}-darwin-arm64.tar.gz", version), - Platform::WindowsX64 => format!("node-v{}-win-x64.zip", version), - Platform::WindowsArm64 => format!("node-v{}-win-arm64.zip", version), + Platform::LinuxX64 => format!("node-v{version}-linux-x64.tar.gz"), + Platform::LinuxArm64 => format!("node-v{version}-linux-arm64.tar.gz"), + Platform::MacosX64 => format!("node-v{version}-darwin-x64.tar.gz"), + Platform::MacosArm64 => format!("node-v{version}-darwin-arm64.tar.gz"), + Platform::WindowsX64 => format!("node-v{version}-win-x64.zip"), + Platform::WindowsArm64 => format!("node-v{version}-win-arm64.zip"), } } diff --git a/tests/common/mod.rs b/tests/common/mod.rs index 32093f2..3d291ed 100644 --- a/tests/common/mod.rs +++ b/tests/common/mod.rs @@ -265,7 +265,7 @@ process.exit(0);"#; let mut package_json = self.generate_package_json(config)?; // Update main to point to compiled output let mut package_obj: serde_json::Value = serde_json::from_str(&package_json)?; - package_obj["main"] = serde_json::Value::String(format!("{}/index.js", out_dir)); + package_obj["main"] = serde_json::Value::String(format!("{out_dir}/index.js")); package_json = serde_json::to_string_pretty(&package_obj)?; fs::write(self.project_path.join("package.json"), package_json)?; @@ -315,7 +315,7 @@ try { )?; // Create a marker file to verify correct source directory is used - let marker_js = format!(r#"module.exports = {{ source: "{}" }};"#, out_dir); + let marker_js = format!(r#"module.exports = {{ source: "{out_dir}" }};"#); fs::write(self.project_path.join(out_dir).join("marker.js"), marker_js)?; Ok(()) @@ -468,12 +468,12 @@ process.exit(0);"#; if deps.is_empty() { String::new() } else { - format!(",\n \"dependencies\": {{\n{}\n }}", deps) + format!(",\n \"dependencies\": {{\n{deps}\n }}") }, if dev_deps.is_empty() { String::new() } else { - format!(",\n \"devDependencies\": {{\n{}\n }}", dev_deps) + format!(",\n \"devDependencies\": {{\n{dev_deps}\n }}") } ); @@ -482,7 +482,7 @@ process.exit(0);"#; fn format_dependencies(&self, deps: &[(String, String)]) -> String { deps.iter() - .map(|(name, version)| format!(" \"{}\": \"{}\"", name, version)) + .map(|(name, version)| format!(" \"{name}\": \"{version}\"")) .collect::>() .join(",\n") } @@ -556,7 +556,7 @@ impl BundlerTestHelper { // Find the created executable let executable_name = custom_name.unwrap_or("test-project"); let executable_path = output_dir.join(if cfg!(windows) { - format!("{}.exe", executable_name) + format!("{executable_name}.exe") } else { executable_name.to_string() }); @@ -564,9 +564,9 @@ impl BundlerTestHelper { // Check if collision avoidance was used if !executable_path.exists() || !executable_path.is_file() { let bundle_executable_path = output_dir.join(if cfg!(windows) { - format!("{}-bundle.exe", executable_name) + format!("{executable_name}-bundle.exe") } else { - format!("{}-bundle", executable_name) + format!("{executable_name}-bundle") }); if bundle_executable_path.exists() { @@ -634,7 +634,7 @@ impl BundlerTestHelper { #[cfg(unix)] { let _ = std::process::Command::new("kill") - .args(&["-9", &child_id.to_string()]) + .args(["-9", &child_id.to_string()]) .output(); } #[cfg(windows)] @@ -663,16 +663,14 @@ impl TestCacheManager { } else { return Ok(()); // Can't determine cache dir, skip cleanup } + } else if let Some(xdg_cache) = std::env::var_os("XDG_CACHE_HOME") { + std::path::PathBuf::from(xdg_cache).join("banderole") + } else if let Some(home) = std::env::var_os("HOME") { + std::path::PathBuf::from(home) + .join(".cache") + .join("banderole") } else { - if let Some(xdg_cache) = std::env::var_os("XDG_CACHE_HOME") { - std::path::PathBuf::from(xdg_cache).join("banderole") - } else if let Some(home) = std::env::var_os("HOME") { - std::path::PathBuf::from(home) - .join(".cache") - .join("banderole") - } else { - std::path::PathBuf::from("/tmp").join("banderole-cache") - } + std::path::PathBuf::from("/tmp").join("banderole-cache") }; if cache_dir.exists() { diff --git a/tests/concurrent_execution_integration_test.rs b/tests/concurrent_execution_integration_test.rs index ea92415..e0fec59 100644 --- a/tests/concurrent_execution_integration_test.rs +++ b/tests/concurrent_execution_integration_test.rs @@ -54,8 +54,8 @@ async fn test_concurrent_first_launch() -> Result<()> { // Execute the binary let output = Command::new(executable_path.as_ref()) - .env("TEST_VAR", format!("thread_{}", i)) - .args(&[format!("--thread-id={}", i)]) + .env("TEST_VAR", format!("thread_{i}")) + .args(&[format!("--thread-id={i}")]) .output() .map_err(|e| anyhow::anyhow!("Failed to execute binary: {}", e))?; @@ -87,7 +87,7 @@ async fn test_concurrent_first_launch() -> Result<()> { } let total_time = start_time.elapsed(); - println!("Total concurrent execution time: {:?}", total_time); + println!("Total concurrent execution time: {total_time:?}"); // Verify all executions succeeded assert_eq!( @@ -98,28 +98,22 @@ async fn test_concurrent_first_launch() -> Result<()> { // Verify each execution produced expected output for (thread_id, duration, stdout) in &results { - println!("Thread {} completed in {:?}", thread_id, duration); + println!("Thread {thread_id} completed in {duration:?}"); // Check for expected output assert!( stdout.contains("Hello from test project!"), - "Thread {} missing expected greeting in output: {}", - thread_id, - stdout + "Thread {thread_id} missing expected greeting in output: {stdout}" ); assert!( - stdout.contains(&format!("thread_{}", thread_id)), - "Thread {} missing environment variable in output: {}", - thread_id, - stdout + stdout.contains(&format!("thread_{thread_id}")), + "Thread {thread_id} missing environment variable in output: {stdout}" ); assert!( - stdout.contains(&format!("--thread-id={}", thread_id)), - "Thread {} missing argument in output: {}", - thread_id, - stdout + stdout.contains(&format!("--thread-id={thread_id}")), + "Thread {thread_id} missing argument in output: {stdout}" ); } @@ -135,7 +129,7 @@ async fn test_concurrent_first_launch() -> Result<()> { .min() .unwrap(); - println!("Duration range: {:?} - {:?}", min_duration, max_duration); + println!("Duration range: {min_duration:?} - {max_duration:?}"); // The difference shouldn't be too extreme if queueing is working properly // Allow up to 30 seconds difference for extraction + queue processing @@ -201,7 +195,7 @@ async fn test_cached_concurrent_execution() -> Result<()> { let thread_start = Instant::now(); let output = Command::new(executable_path.as_ref()) - .env("TEST_VAR", format!("cached_{}", i)) + .env("TEST_VAR", format!("cached_{i}")) .output() .map_err(|e| anyhow::anyhow!("Failed to execute binary: {}", e))?; @@ -230,21 +224,19 @@ async fn test_cached_concurrent_execution() -> Result<()> { } let total_time = start_time.elapsed(); - println!("Total cached concurrent execution time: {:?}", total_time); + println!("Total cached concurrent execution time: {total_time:?}"); // Verify all executions succeeded assert_eq!(results.len(), NUM_CONCURRENT); // With cache populated, all executions should be relatively fast for (thread_id, duration) in &results { - println!("Cached thread {} completed in {:?}", thread_id, duration); + println!("Cached thread {thread_id} completed in {duration:?}"); // Each execution should be fast since cache is populated assert!( *duration < Duration::from_secs(10), - "Cached execution took too long: {:?} for thread {}", - duration, - thread_id + "Cached execution took too long: {duration:?} for thread {thread_id}" ); } @@ -316,7 +308,7 @@ process.exit(0); thread::sleep(Duration::from_millis(i as u64 * 10)); let output = Command::new(executable_path.as_ref()) - .args(&[format!("--thread-id={}", i)]) + .args(&[format!("--thread-id={i}")]) .output() .map_err(|e| anyhow::anyhow!("Failed to execute binary: {}", e))?; @@ -354,15 +346,13 @@ process.exit(0); ); assert!( - stdout.contains(&format!("Thread {} started", thread_id)), - "Thread {} missing start message", - thread_id + stdout.contains(&format!("Thread {thread_id} started")), + "Thread {thread_id} missing start message" ); assert!( - stdout.contains(&format!("Thread {} completed", thread_id)), - "Thread {} missing completion message", - thread_id + stdout.contains(&format!("Thread {thread_id} completed")), + "Thread {thread_id} missing completion message" ); } @@ -405,8 +395,7 @@ async fn test_extraction_failure_recovery() -> Result<()> { let stdout = String::from_utf8_lossy(&output.stdout); assert!( stdout.contains("Hello from test project!"), - "Recovery test missing expected output: {}", - stdout + "Recovery test missing expected output: {stdout}" ); println!("✅ Extraction failure recovery test passed!"); diff --git a/tests/integration_test.rs b/tests/integration_test.rs index 7685136..51588b4 100644 --- a/tests/integration_test.rs +++ b/tests/integration_test.rs @@ -162,8 +162,8 @@ process.exit(0);"#; let stderr = String::from_utf8_lossy(&output.stderr); println!("Test 1 - Exit status: {}", output.status); - println!("Test 1 - Stdout: {}", stdout); - println!("Test 1 - Stderr: {}", stderr); + println!("Test 1 - Stdout: {stdout}"); + println!("Test 1 - Stderr: {stderr}"); // Check for expected output assert!(output.status.success(), "First run failed"); @@ -193,7 +193,7 @@ process.exit(0);"#; let stdout = String::from_utf8_lossy(&output.stdout); println!("Test 2 - Exit status: {}", output.status); - println!("Test 2 - Output: {}", stdout); + println!("Test 2 - Output: {stdout}"); assert!(output.status.success(), "Cached run failed"); assert!( @@ -236,7 +236,7 @@ process.exit(0);"#; // Build banderole println!("Building banderole for Node version test..."); let output = Command::new("cargo") - .args(&["build", "--release"]) + .args(["build", "--release"]) .output() .expect("Failed to build banderole"); @@ -254,7 +254,7 @@ process.exit(0);"#; println!("Bundling test app with .nvmrc..."); let mut bundle_cmd = Command::new(&banderole_path); bundle_cmd - .args(&["bundle", test_app_path.to_str().unwrap()]) + .args(["bundle", test_app_path.to_str().unwrap()]) .current_dir(temp_dir.path()); let bundle_output = bundle_cmd.output().expect("Failed to bundle test app"); @@ -279,13 +279,12 @@ process.exit(0);"#; // Check that the output mentions the correct Node.js version let stdout = String::from_utf8_lossy(&bundle_output.stdout); let stderr = String::from_utf8_lossy(&bundle_output.stderr); - let combined_output = format!("{}{}", stdout, stderr); - println!("Bundle output: {}", combined_output); + let combined_output = format!("{stdout}{stderr}"); + println!("Bundle output: {combined_output}"); assert!( combined_output.contains("Node.js v20.18.1"), - "Expected Node.js version not found in output: {}", - combined_output + "Expected Node.js version not found in output: {combined_output}" ); // Find and run the created executable to verify it uses the correct Node version @@ -338,12 +337,11 @@ process.exit(0);"#; ); let stdout = String::from_utf8_lossy(&run_output.stdout); - println!("Executable output: {}", stdout); + println!("Executable output: {stdout}"); assert!( stdout.contains("v20.18.1"), - "Expected Node.js version not found in executable output: {}", - stdout + "Expected Node.js version not found in executable output: {stdout}" ); } @@ -435,7 +433,7 @@ async fn test_output_path_collision_handling() -> Result<(), Box std::io::Result Result<()> { println!("Successfully installed pnpm workspace dependencies"); } Err(e) => { - println!("Pnpm installation failed, falling back to npm: {}", e); + println!("Pnpm installation failed, falling back to npm: {e}"); manager.install_workspace_dependencies()?; } } diff --git a/tests/workspace_version_integration_test.rs b/tests/workspace_version_integration_test.rs index 866e319..6ebe93f 100644 --- a/tests/workspace_version_integration_test.rs +++ b/tests/workspace_version_integration_test.rs @@ -153,9 +153,9 @@ async fn test_version_format_compatibility() -> Result<()> { ]; for (version_spec, test_name) in test_cases { - println!("Testing version format: {} ({})", version_spec, test_name); + println!("Testing version format: {version_spec} ({test_name})"); - let project = TestProject::new(&format!("version-format-{}", test_name)) + let project = TestProject::new(&format!("version-format-{test_name}")) .workspace() .with_dependency("fs-extra", "^11.1.1"); @@ -172,7 +172,7 @@ async fn test_version_format_compatibility() -> Result<()> { let executable_path = BundlerTestHelper::bundle_project_with_compression( manager.project_path(), manager.temp_dir(), - Some(&format!("version-format-{}-test", test_name)), + Some(&format!("version-format-{test_name}-test")), false, )?; @@ -188,7 +188,7 @@ async fn test_version_format_compatibility() -> Result<()> { &[], )?; - println!("✅ version format {} test passed!", version_spec); + println!("✅ version format {version_spec} test passed!"); } println!("✅ all version format compatibility tests passed!"); @@ -209,14 +209,14 @@ async fn test_nested_workspace_package_version_resolution() -> Result<()> { // Create version files at different levels let workspace_root = manager.workspace_root().unwrap(); - + // Workspace root has Node 20 fs::write(workspace_root.join(".nvmrc"), "20")?; - + // Create an intermediate directory (simulating packages/ directory) let packages_dir = workspace_root.join("packages"); fs::create_dir_all(&packages_dir)?; - + // Packages directory has Node 18 (should be ignored since project is deeper) fs::write(packages_dir.join(".node-version"), "18")?;