From 671d1cebf02826f308c721e81f73f136c9369a58 Mon Sep 17 00:00:00 2001 From: Dazor Plasma Date: Sat, 24 Jan 2026 22:18:22 +0200 Subject: [PATCH 1/3] simplified get_version_command --- src/validators/tool.rs | 59 +++++++++++++++++++++++------------------- 1 file changed, 32 insertions(+), 27 deletions(-) diff --git a/src/validators/tool.rs b/src/validators/tool.rs index 9b030fa..65ee116 100644 --- a/src/validators/tool.rs +++ b/src/validators/tool.rs @@ -13,28 +13,22 @@ impl ToolValidator { } fn get_version_command<'a>(&self, tool: &'a str) -> Option<(&'a str, Vec<&'static str>)> { - match tool { - "node" => Some(("node", vec!["--version"])), - "npm" => Some(("npm", vec!["--version"])), - "go" => Some(("go", vec!["version"])), - "rust" | "rustc" => Some(("rustc", vec!["--version"])), - "cargo" => Some(("cargo", vec!["--version"])), - "python" | "python3" => Some(("python3", vec!["--version"])), - "docker" => Some(("docker", vec!["--version"])), - "git" => Some(("git", vec!["--version"])), - "java" => Some(("java", vec!["--version"])), - "ruby" => Some(("ruby", vec!["--version"])), - _ => Some((tool, vec!["--version"])), - } + let tool = match tool { + "rust" => "rustc", + "python" => "python3", + _ => tool, + }; + + Some((tool, vec!["--version"])) } fn parse_version(&self, output: &str, _tool: &str) -> Option { let output = output.trim(); - + // Simple version extraction - find first occurrence of X.Y.Z or X.Y pattern for word in output.split_whitespace() { let cleaned = word.trim_start_matches('v').trim_start_matches('V'); - + // Check if it looks like a version number let parts: Vec<&str> = cleaned.split('.').collect(); if parts.len() >= 2 && parts.iter().all(|p| p.chars().all(|c| c.is_numeric())) { @@ -70,7 +64,7 @@ impl ToolValidator { let req_ver = requirement.trim_start_matches('=').trim(); return version == req_ver; } - + // Default: exact match version.contains(requirement) } @@ -102,21 +96,31 @@ impl Validator for ToolValidator { match Command::new(cmd).args(&args).output() { Ok(output) => { let version_output = String::from_utf8_lossy(&output.stdout); - if let Some(version) = self.parse_version(&version_output, &self.check.name) { + if let Some(version) = self.parse_version(&version_output, &self.check.name) + { if self.check_version_requirement(&version, version_req) { - results.push(ValidationResult::success( - format!("{} {} found", self.check.name, version), - )); + results.push(ValidationResult::success(format!( + "{} {} found", + self.check.name, version + ))); } else { results.push(ValidationResult::error( - format!("{} version {} does not meet requirement {}", - self.check.name, version, version_req), - Some(format!("Update {} to version {}", self.check.name, version_req)), + format!( + "{} version {} does not meet requirement {}", + self.check.name, version, version_req + ), + Some(format!( + "Update {} to version {}", + self.check.name, version_req + )), )); } } else { results.push(ValidationResult::warning( - format!("{} found but version could not be determined", self.check.name), + format!( + "{} found but version could not be determined", + self.check.name + ), None, )); } @@ -130,9 +134,10 @@ impl Validator for ToolValidator { } } } else { - results.push(ValidationResult::success( - format!("{} found", self.check.name), - )); + results.push(ValidationResult::success(format!( + "{} found", + self.check.name + ))); } Ok(results) From 7cab08772ed69de2a34b5f309aa47c1e4c87fc50 Mon Sep 17 00:00:00 2001 From: Dazor Plasma Date: Sat, 24 Jan 2026 22:37:03 +0200 Subject: [PATCH 2/3] cargo fmt --- src/config.rs | 29 ++++++++++++++++++----------- src/lib.rs | 4 ++-- src/main.rs | 4 ++-- src/reporter.rs | 8 +++++--- src/validators/env.rs | 19 ++++++++++++------- src/validators/file.rs | 7 ++++--- src/validators/mod.rs | 4 ++-- src/validators/port.rs | 12 ++++++++---- tests/integration_tests.rs | 16 +++++++++------- 9 files changed, 62 insertions(+), 41 deletions(-) diff --git a/src/config.rs b/src/config.rs index 9b51a74..d827ae5 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,7 +1,7 @@ +use anyhow::{Context, Result}; use serde::{Deserialize, Serialize}; use std::fs; use std::path::Path; -use anyhow::{Context, Result}; #[derive(Debug, Deserialize, Serialize, Clone)] pub struct Config { @@ -47,25 +47,32 @@ fn default_true() -> bool { impl Config { pub fn load>(path: P) -> Result { - let content = fs::read_to_string(path.as_ref()) - .context("Failed to read config file")?; - - let config: Config = serde_yaml::from_str(&content) - .context("Failed to parse config file")?; - + let content = fs::read_to_string(path.as_ref()).context("Failed to read config file")?; + + let config: Config = + serde_yaml::from_str(&content).context("Failed to parse config file")?; + Ok(config) } pub fn find_config() -> Result { - let config_names = [".envcheck.yaml", ".envcheck.yml", "envcheck.yaml", "envcheck.yml"]; - + let config_names = [ + ".envcheck.yaml", + ".envcheck.yml", + "envcheck.yaml", + "envcheck.yml", + ]; + for name in &config_names { if Path::new(name).exists() { return Self::load(name); } } - - anyhow::bail!("No config file found. Looking for: {}", config_names.join(", ")) + + anyhow::bail!( + "No config file found. Looking for: {}", + config_names.join(", ") + ) } } diff --git a/src/lib.rs b/src/lib.rs index 0e852d8..d2ffd86 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,7 +1,7 @@ pub mod config; -pub mod validators; pub mod reporter; +pub mod validators; pub use config::Config; -pub use validators::{ValidationResult, ValidationStatus, Validator}; pub use reporter::Reporter; +pub use validators::{ValidationResult, ValidationStatus, Validator}; diff --git a/src/main.rs b/src/main.rs index 5a2979a..68a54ff 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,10 +1,10 @@ -use clap::Parser; use anyhow::Result; +use clap::Parser; use std::process; mod config; -mod validators; mod reporter; +mod validators; use config::Config; use reporter::Reporter; diff --git a/src/reporter.rs b/src/reporter.rs index 44c02c3..063dbfb 100644 --- a/src/reporter.rs +++ b/src/reporter.rs @@ -40,7 +40,7 @@ impl Reporter { } println!(); - + if error_count > 0 { println!( "{} {} issue(s) found. Fix them to continue.", @@ -56,12 +56,14 @@ impl Reporter { } else { println!("{} All checks passed!", "✓".green().bold()); } - + println!(); } pub fn has_errors(&self) -> bool { - self.results.iter().any(|r| matches!(r.status, ValidationStatus::Error)) + self.results + .iter() + .any(|r| matches!(r.status, ValidationStatus::Error)) } pub fn exit_code(&self) -> i32 { diff --git a/src/validators/env.rs b/src/validators/env.rs index 9067042..251da77 100644 --- a/src/validators/env.rs +++ b/src/validators/env.rs @@ -22,19 +22,24 @@ impl Validator for EnvValidator { if let Some(pattern) = &self.check.pattern { // TODO: Add regex pattern matching if value.contains(pattern) { - results.push(ValidationResult::success( - format!("{} is set and matches pattern", self.check.name), - )); + results.push(ValidationResult::success(format!( + "{} is set and matches pattern", + self.check.name + ))); } else { results.push(ValidationResult::error( format!("{} is set but does not match pattern", self.check.name), - Some(format!("Ensure {} matches pattern: {}", self.check.name, pattern)), + Some(format!( + "Ensure {} matches pattern: {}", + self.check.name, pattern + )), )); } } else { - results.push(ValidationResult::success( - format!("{} is set", self.check.name), - )); + results.push(ValidationResult::success(format!( + "{} is set", + self.check.name + ))); } } Err(_) => { diff --git a/src/validators/file.rs b/src/validators/file.rs index 0896d7c..94631cc 100644 --- a/src/validators/file.rs +++ b/src/validators/file.rs @@ -19,9 +19,10 @@ impl Validator for FileValidator { let path = Path::new(&self.check.path); if path.exists() { - results.push(ValidationResult::success( - format!("{} exists", self.check.path), - )); + results.push(ValidationResult::success(format!( + "{} exists", + self.check.path + ))); } else { if self.check.required { results.push(ValidationResult::error( diff --git a/src/validators/mod.rs b/src/validators/mod.rs index 5c1fa03..a190cb7 100644 --- a/src/validators/mod.rs +++ b/src/validators/mod.rs @@ -1,10 +1,10 @@ use crate::config::Config; use anyhow::Result; -pub mod tool; pub mod env; -pub mod port; pub mod file; +pub mod port; +pub mod tool; #[derive(Debug, Clone)] pub enum ValidationStatus { diff --git a/src/validators/port.rs b/src/validators/port.rs index 0ccb369..697be71 100644 --- a/src/validators/port.rs +++ b/src/validators/port.rs @@ -18,14 +18,18 @@ impl Validator for PortValidator { match TcpListener::bind(format!("127.0.0.1:{}", self.port)) { Ok(_) => { - results.push(ValidationResult::success( - format!("Port {} is available", self.port), - )); + results.push(ValidationResult::success(format!( + "Port {} is available", + self.port + ))); } Err(_) => { results.push(ValidationResult::error( format!("Port {} is already in use", self.port), - Some(format!("Free up port {} or change the port in your config", self.port)), + Some(format!( + "Free up port {} or change the port in your config", + self.port + )), )); } } diff --git a/tests/integration_tests.rs b/tests/integration_tests.rs index 6b41c88..78e3e14 100644 --- a/tests/integration_tests.rs +++ b/tests/integration_tests.rs @@ -1,15 +1,15 @@ use assert_cmd::Command; use predicates::prelude::*; -use tempfile::NamedTempFile; use std::io::Write; +use tempfile::NamedTempFile; #[test] fn test_cli_help() { let mut cmd = Command::cargo_bin("envcheck").unwrap(); cmd.arg("--help"); - cmd.assert() - .success() - .stdout(predicate::str::contains("Validate your development environment")); + cmd.assert().success().stdout(predicate::str::contains( + "Validate your development environment", + )); } #[test] @@ -39,11 +39,12 @@ files: required: true "#, path_str - ).unwrap(); + ) + .unwrap(); let mut cmd = Command::cargo_bin("envcheck").unwrap(); cmd.arg("--config").arg(file.path()); - + // Node check might fail if not installed in CI environment, but PATH and file should pass // We check for "Running environment checks" to ensure it started cmd.assert() @@ -59,7 +60,8 @@ fn test_cli_port_validation() { ports: - 9999 "# - ).unwrap(); + ) + .unwrap(); let mut cmd = Command::cargo_bin("envcheck").unwrap(); cmd.arg("--config").arg(file.path()); From ce169e009b33c12a5831e56cda749530efe5b251 Mon Sep 17 00:00:00 2001 From: Dazor Plasma Date: Sat, 24 Jan 2026 22:40:59 +0200 Subject: [PATCH 3/3] clippy - collapse if --- src/validators/file.rs | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/validators/file.rs b/src/validators/file.rs index 94631cc..6fbeb2f 100644 --- a/src/validators/file.rs +++ b/src/validators/file.rs @@ -23,18 +23,16 @@ impl Validator for FileValidator { "{} exists", self.check.path ))); + } else if self.check.required { + results.push(ValidationResult::error( + format!("{} does not exist", self.check.path), + Some(format!("Create {} file", self.check.path)), + )); } else { - if self.check.required { - results.push(ValidationResult::error( - format!("{} does not exist", self.check.path), - Some(format!("Create {} file", self.check.path)), - )); - } else { - results.push(ValidationResult::warning( - format!("{} does not exist (optional)", self.check.path), - None, - )); - } + results.push(ValidationResult::warning( + format!("{} does not exist (optional)", self.check.path), + None, + )); } Ok(results)