diff --git a/rust/src/chrome.rs b/rust/src/chrome.rs index 6a1fe5822ac9f..80601856e41c5 100644 --- a/rust/src/chrome.rs +++ b/rust/src/chrome.rs @@ -26,7 +26,7 @@ use std::path::PathBuf; use crate::config::ARCH::{ARM64, X32}; use crate::config::OS::{LINUX, MACOS, WINDOWS}; use crate::downloads::{parse_json_from_url, read_version_from_link}; -use crate::files::{compose_driver_path_in_cache, path_buf_to_string, BrowserPath}; +use crate::files::{compose_driver_path_in_cache, path_to_string, BrowserPath}; use crate::logger::Logger; use crate::metadata::{ create_driver_metadata, get_driver_version_from_metadata, get_metadata, write_metadata, @@ -277,7 +277,8 @@ impl SeleniumManager for ChromeManager { fn request_driver_version(&mut self) -> Result> { let major_browser_version_binding = self.get_major_browser_version(); let major_browser_version = major_browser_version_binding.as_str(); - let mut metadata = get_metadata(self.get_logger(), self.get_cache_path()?); + let cache_path = self.get_cache_path()?; + let mut metadata = get_metadata(self.get_logger(), &cache_path); match get_driver_version_from_metadata( &metadata.drivers, @@ -326,7 +327,7 @@ impl SeleniumManager for ChromeManager { &driver_version, driver_ttl, )); - write_metadata(&metadata, self.get_logger(), self.get_cache_path()?); + write_metadata(&metadata, self.get_logger(), cache_path); } Ok(driver_version) } @@ -381,7 +382,7 @@ impl SeleniumManager for ChromeManager { fn get_driver_path_in_cache(&self) -> Result> { Ok(compose_driver_path_in_cache( - self.get_cache_path()?, + self.get_cache_path()?.unwrap_or_default(), self.driver_name, self.get_os(), self.get_platform_label(), @@ -412,7 +413,8 @@ impl SeleniumManager for ChromeManager { fn download_browser(&mut self) -> Result, Box> { let browser_version; let browser_name = self.browser_name; - let mut metadata = get_metadata(self.get_logger(), self.get_cache_path()?); + let cache_path = self.get_cache_path()?; + let mut metadata = get_metadata(self.get_logger(), &cache_path); let major_browser_version = self.get_major_browser_version(); let major_browser_version_int = major_browser_version.parse::().unwrap_or_default(); @@ -465,7 +467,7 @@ impl SeleniumManager for ChromeManager { &browser_version, browser_ttl, )); - write_metadata(&metadata, self.get_logger(), self.get_cache_path()?); + write_metadata(&metadata, self.get_logger(), cache_path); } } } @@ -513,7 +515,7 @@ impl SeleniumManager for ChromeManager { )?; } if browser_binary_path.exists() { - self.set_browser_path(path_buf_to_string(browser_binary_path.clone())); + self.set_browser_path(path_to_string(&browser_binary_path)); Ok(Some(browser_binary_path)) } else { Ok(None) diff --git a/rust/src/config.rs b/rust/src/config.rs index b4d8918f2ab88..5b217b6c426d6 100644 --- a/rust/src/config.rs +++ b/rust/src/config.rs @@ -18,7 +18,7 @@ use crate::config::OS::{LINUX, MACOS, WINDOWS}; use crate::shell::run_shell_command_by_os; use crate::{ - default_cache_folder, format_one_arg, path_buf_to_string, Command, REQUEST_TIMEOUT_SEC, + default_cache_folder, format_one_arg, path_to_string, Command, REQUEST_TIMEOUT_SEC, UNAME_COMMAND, }; use crate::{ARCH_AMD64, ARCH_ARM64, ARCH_X86, TTL_SEC, WMIC_COMMAND_OS}; @@ -30,7 +30,7 @@ use std::fs::read_to_string; use std::path::Path; use toml::Table; -thread_local!(static CACHE_PATH: RefCell = RefCell::new(path_buf_to_string(default_cache_folder()))); +thread_local!(static CACHE_PATH: RefCell = RefCell::new(path_to_string(&default_cache_folder()))); pub const CONFIG_FILE: &str = "se-config.toml"; pub const ENV_PREFIX: &str = "SE_"; @@ -263,7 +263,7 @@ fn write_cache_path(cache_path: String) { } fn read_cache_path() -> String { - let mut cache_path: String = path_buf_to_string(default_cache_folder()); + let mut cache_path: String = path_to_string(&default_cache_folder()); CACHE_PATH.with(|value| { let path: String = (&*value.borrow().to_string()).into(); if !path.is_empty() { diff --git a/rust/src/edge.rs b/rust/src/edge.rs index dbfe49ace8b90..26ac93d2da7f1 100644 --- a/rust/src/edge.rs +++ b/rust/src/edge.rs @@ -134,7 +134,8 @@ impl SeleniumManager for EdgeManager { fn request_driver_version(&mut self) -> Result> { let mut major_browser_version = self.get_major_browser_version(); - let mut metadata = get_metadata(self.get_logger(), self.get_cache_path()?); + let cache_path = self.get_cache_path()?; + let mut metadata = get_metadata(self.get_logger(), &cache_path); match get_driver_version_from_metadata( &metadata.drivers, @@ -194,7 +195,7 @@ impl SeleniumManager for EdgeManager { &driver_version, driver_ttl, )); - write_metadata(&metadata, self.get_logger(), self.get_cache_path()?); + write_metadata(&metadata, self.get_logger(), cache_path); } Ok(driver_version) @@ -235,7 +236,7 @@ impl SeleniumManager for EdgeManager { fn get_driver_path_in_cache(&self) -> Result> { Ok(compose_driver_path_in_cache( - self.get_cache_path()?, + self.get_cache_path()?.unwrap_or_default(), self.driver_name, self.get_os(), self.get_platform_label(), diff --git a/rust/src/files.rs b/rust/src/files.rs index b71240647a617..06fb9b4bd290a 100644 --- a/rust/src/files.rs +++ b/rust/src/files.rs @@ -170,8 +170,8 @@ pub fn uncompress_sfx( let file_reader = Cursor::new(&file_bytes[index_7z..]); sevenz_rust::decompress(file_reader, zip_parent).unwrap(); - let zip_parent_str = path_buf_to_string(zip_parent.to_path_buf()); - let target_str = path_buf_to_string(target.to_path_buf()); + let zip_parent_str = path_to_string(zip_parent); + let target_str = path_to_string(target); let core_str = format!(r#"{}\core"#, zip_parent_str); log.trace(format!( "Moving extracted files and folders from {} to {}", @@ -191,11 +191,7 @@ pub fn uncompress_pkg( major_browser_version: i32, ) -> Result<(), Box> { let tmp_dir = Builder::new().prefix(PKG).tempdir()?; - let out_folder = format!( - "{}/{}", - path_buf_to_string(tmp_dir.path().to_path_buf()), - PKG - ); + let out_folder = format!("{}/{}", path_to_string(tmp_dir.path()), PKG); let mut command = Command::new_single(format_two_args( PKGUTIL_COMMAND, compressed_file, @@ -205,7 +201,7 @@ pub fn uncompress_pkg( run_shell_command_by_os(os, command)?; fs::create_dir_all(target)?; - let target_folder = path_buf_to_string(target.to_path_buf()); + let target_folder = path_to_string(target); command = if major_browser_version == 0 || major_browser_version > 84 { Command::new_single(format_three_args( MV_PAYLOAD_COMMAND, @@ -246,7 +242,7 @@ pub fn uncompress_dmg( run_shell_command_by_os(os, command)?; fs::create_dir_all(target)?; - let target_folder = path_buf_to_string(target.to_path_buf()); + let target_folder = path_to_string(target); command = Command::new_single(format_three_args( CP_VOLUME_COMMAND, volume, @@ -497,8 +493,11 @@ pub fn parse_version(version_text: String, log: &Logger) -> Result String { - path_buf.into_os_string().into_string().unwrap_or_default() +pub fn path_to_string(path: &Path) -> String { + path.to_path_buf() + .into_os_string() + .into_string() + .unwrap_or_default() } pub fn read_bytes_from_file(file_path: &str) -> Result, Box> { diff --git a/rust/src/firefox.rs b/rust/src/firefox.rs index a4e850ab11dd1..276ecde8bb6f6 100644 --- a/rust/src/firefox.rs +++ b/rust/src/firefox.rs @@ -33,7 +33,7 @@ use crate::metadata::{ }; use crate::{ create_browser_metadata, create_http_client, download_to_tmp_folder, format_three_args, - format_two_args, get_browser_version_from_metadata, path_buf_to_string, uncompress, Logger, + format_two_args, get_browser_version_from_metadata, path_to_string, uncompress, Logger, SeleniumManager, BETA, CANARY, DASH_VERSION, DEV, NIGHTLY, OFFLINE_REQUEST_ERR_MSG, REG_CURRENT_VERSION_ARG, STABLE, }; @@ -274,7 +274,8 @@ impl SeleniumManager for FirefoxManager { fn request_driver_version(&mut self) -> Result> { let major_browser_version_binding = self.get_major_browser_version(); let major_browser_version = major_browser_version_binding.as_str(); - let mut metadata = get_metadata(self.get_logger(), self.get_cache_path()?); + let cache_path = self.get_cache_path()?; + let mut metadata = get_metadata(self.get_logger(), &cache_path); match get_driver_version_from_metadata( &metadata.drivers, @@ -303,7 +304,7 @@ impl SeleniumManager for FirefoxManager { &driver_version, driver_ttl, )); - write_metadata(&metadata, self.get_logger(), self.get_cache_path()?); + write_metadata(&metadata, self.get_logger(), cache_path); } Ok(driver_version) @@ -355,7 +356,7 @@ impl SeleniumManager for FirefoxManager { fn get_driver_path_in_cache(&self) -> Result> { Ok(compose_driver_path_in_cache( - self.get_cache_path()?, + self.get_cache_path()?.unwrap_or_default(), self.driver_name, self.get_os(), self.get_platform_label(), @@ -387,7 +388,8 @@ impl SeleniumManager for FirefoxManager { let browser_version; let browser_name = self.browser_name; let original_browser_version = self.get_config().browser_version.clone(); - let mut metadata = get_metadata(self.get_logger(), self.get_cache_path()?); + let cache_path = self.get_cache_path()?; + let mut metadata = get_metadata(self.get_logger(), &cache_path); let major_browser_version = self.get_major_browser_version(); let is_browser_version_nightly = original_browser_version.eq_ignore_ascii_case(NIGHTLY) || original_browser_version.eq_ignore_ascii_case(CANARY); @@ -426,7 +428,7 @@ impl SeleniumManager for FirefoxManager { &browser_version, browser_ttl, )); - write_metadata(&metadata, self.get_logger(), self.get_cache_path()?); + write_metadata(&metadata, self.get_logger(), cache_path); } } } @@ -474,7 +476,7 @@ impl SeleniumManager for FirefoxManager { )?; } if browser_binary_path.exists() { - self.set_browser_path(path_buf_to_string(browser_binary_path.clone())); + self.set_browser_path(path_to_string(&browser_binary_path)); Ok(Some(browser_binary_path)) } else { Ok(None) diff --git a/rust/src/grid.rs b/rust/src/grid.rs index 65e942260bb63..295cc9ba3ae57 100644 --- a/rust/src/grid.rs +++ b/rust/src/grid.rs @@ -97,7 +97,8 @@ impl SeleniumManager for GridManager { fn request_driver_version(&mut self) -> Result> { let major_browser_version_binding = self.get_major_browser_version(); let major_browser_version = major_browser_version_binding.as_str(); - let mut metadata = get_metadata(self.get_logger(), self.get_cache_path()?); + let cache_path = self.get_cache_path()?; + let mut metadata = get_metadata(self.get_logger(), &cache_path); match get_driver_version_from_metadata( &metadata.drivers, @@ -156,7 +157,7 @@ impl SeleniumManager for GridManager { &driver_version, driver_ttl, )); - write_metadata(&metadata, self.get_logger(), self.get_cache_path()?); + write_metadata(&metadata, self.get_logger(), cache_path); } Ok(driver_version) @@ -193,6 +194,7 @@ impl SeleniumManager for GridManager { let driver_version = self.get_driver_version(); Ok(self .get_cache_path()? + .unwrap_or_default() .join(browser_name) .join(driver_version) .join(format!("{driver_name}-{driver_version}.{GRID_EXTENSION}"))) diff --git a/rust/src/iexplorer.rs b/rust/src/iexplorer.rs index 25fce196b3a00..829ac849b1e99 100644 --- a/rust/src/iexplorer.rs +++ b/rust/src/iexplorer.rs @@ -109,7 +109,8 @@ impl SeleniumManager for IExplorerManager { fn request_driver_version(&mut self) -> Result> { let major_browser_version_binding = self.get_major_browser_version(); let major_browser_version = major_browser_version_binding.as_str(); - let mut metadata = get_metadata(self.get_logger(), self.get_cache_path()?); + let cache_path = self.get_cache_path()?; + let mut metadata = get_metadata(self.get_logger(), &cache_path); match get_driver_version_from_metadata( &metadata.drivers, @@ -164,7 +165,7 @@ impl SeleniumManager for IExplorerManager { &driver_version, driver_ttl, )); - write_metadata(&metadata, self.get_logger(), self.get_cache_path()?); + write_metadata(&metadata, self.get_logger(), cache_path); } Ok(driver_version) @@ -196,7 +197,7 @@ impl SeleniumManager for IExplorerManager { fn get_driver_path_in_cache(&self) -> Result> { Ok(compose_driver_path_in_cache( - self.get_cache_path()?, + self.get_cache_path()?.unwrap_or_default(), self.driver_name, "Windows", self.get_platform_label(), diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 9d1a12bfecaf3..7684a43f477b4 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -19,7 +19,7 @@ use crate::chrome::{ChromeManager, CHROMEDRIVER_NAME, CHROME_NAME}; use crate::edge::{EdgeManager, EDGEDRIVER_NAME, EDGE_NAMES}; use crate::files::{ create_parent_path_if_not_exists, create_path_if_not_exists, default_cache_folder, - get_binary_extension, path_buf_to_string, + get_binary_extension, path_to_string, }; use crate::firefox::{FirefoxManager, FIREFOX_NAME, GECKODRIVER_NAME}; use crate::iexplorer::{IExplorerManager, IEDRIVER_NAME, IE_NAMES}; @@ -281,7 +281,7 @@ pub trait SeleniumManager { browser_version } - fn discover_or_download_browser_and_driver_version( + fn discover_driver_version_and_download_browser_if_necessary( &mut self, ) -> Result> { let mut download_browser = self.is_force_browser_download(); @@ -530,21 +530,21 @@ pub trait SeleniumManager { // Discover browser version (or download it, if not available and possible). // With the found browser version, discover the proper driver version using online endpoints - match self.discover_or_download_browser_and_driver_version() { - Ok(driver_version) => { - if self.get_driver_version().is_empty() { + if self.get_driver_version().is_empty() { + match self.discover_driver_version_and_download_browser_if_necessary() { + Ok(driver_version) => { self.set_driver_version(driver_version); } - } - Err(err) => { - if driver_in_path_version.is_some() && driver_in_path.is_some() { - self.get_logger().warn(format!( - "Exception managing {}: {}", - self.get_browser_name(), - err - )); - } else { - return Err(err); + Err(err) => { + if driver_in_path_version.is_some() && driver_in_path.is_some() { + self.get_logger().warn(format!( + "Exception managing {}: {}", + self.get_browser_name(), + err + )); + } else { + return Err(err); + } } } } @@ -553,8 +553,9 @@ pub trait SeleniumManager { if let (Some(version), Some(path)) = (&driver_in_path_version, &driver_in_path) { // If proper driver version is not the same as the driver in path, display warning let major_version = self.get_major_version(version)?; - if (self.is_firefox() && !version.eq(self.get_driver_version())) - || !major_version.eq(&self.get_major_browser_version()) + if !self.get_driver_version().is_empty() + && (self.is_firefox() && !version.eq(self.get_driver_version())) + || (!self.is_firefox() && !major_version.eq(&self.get_major_browser_version())) { self.get_logger().warn(format!( "The {} version ({}) detected in PATH at {} might not be compatible with \ @@ -628,7 +629,7 @@ pub trait SeleniumManager { } fn find_best_driver_from_cache(&self) -> Result, Box> { - let cache_path = self.get_cache_path()?; + let cache_path = self.get_cache_path()?.unwrap_or_default(); let drivers_in_cache_matching_version: Vec = WalkDir::new(&cache_path) .into_iter() .filter_map(|entry| entry.ok()) @@ -719,7 +720,8 @@ pub trait SeleniumManager { ) -> Result, Box> { let browser_version; let major_browser_version = self.get_major_browser_version(); - let mut metadata = get_metadata(self.get_logger(), self.get_cache_path()?); + let cache_path = self.get_cache_path()?; + let mut metadata = get_metadata(self.get_logger(), &cache_path); // Browser version is checked in the local metadata match get_browser_version_from_metadata( @@ -752,7 +754,7 @@ pub trait SeleniumManager { &browser_version, browser_ttl, )); - write_metadata(&metadata, self.get_logger(), self.get_cache_path()?); + write_metadata(&metadata, self.get_logger(), cache_path); } } } @@ -770,7 +772,7 @@ pub trait SeleniumManager { let mut escaped_browser_path = self.get_escaped_path(browser_path.to_string()); if browser_path.is_empty() { if let Some(path) = self.detect_browser_path() { - browser_path = path_buf_to_string(path); + browser_path = path_to_string(&path); escaped_browser_path = self.get_escaped_path(browser_path.to_string()); } } @@ -827,7 +829,7 @@ pub trait SeleniumManager { if browser_path.is_empty() { match self.detect_browser_path() { Some(path) => { - browser_path = self.get_escaped_path(path_buf_to_string(path)); + browser_path = self.get_escaped_path(path_to_string(&path)); } _ => return Ok(None), } @@ -845,6 +847,7 @@ pub trait SeleniumManager { fn get_browser_path_in_cache(&self) -> Result> { Ok(self .get_cache_path()? + .unwrap_or_default() .join(self.get_browser_name()) .join(self.get_platform_label()) .join(self.get_browser_version())) @@ -934,16 +937,17 @@ pub trait SeleniumManager { } fn canonicalize_path(&self, path_buf: PathBuf) -> String { - let mut canon_path = path_buf_to_string( - path_buf - .as_path() - .canonicalize() - .unwrap_or(path_buf.clone()), - ); + let mut canon_path = path_to_string(&path_buf); if WINDOWS.is(self.get_os()) || canon_path.starts_with(UNC_PREFIX) { - canon_path = canon_path.replace(UNC_PREFIX, "") + canon_path = path_to_string( + &path_buf + .as_path() + .canonicalize() + .unwrap_or(path_buf.clone()), + ) + .replace(UNC_PREFIX, "") } - if !path_buf_to_string(path_buf.clone()).eq(&canon_path) { + if !path_to_string(&path_buf).eq(&canon_path) { self.get_logger().trace(format!( "Path {} has been canonicalized to {}", path_buf.display(), @@ -1054,11 +1058,22 @@ pub trait SeleniumManager { } } - fn get_cache_path(&self) -> Result> { + fn get_cache_path(&self) -> Result, Box> { let path = Path::new(&self.get_config().cache_path); - create_path_if_not_exists(path)?; - let canon_path = self.canonicalize_path(path.to_path_buf()); - Ok(Path::new(&canon_path).to_path_buf()) + match create_path_if_not_exists(path) { + Ok(_) => { + let canon_path = self.canonicalize_path(path.to_path_buf()); + Ok(Some(Path::new(&canon_path).to_path_buf())) + } + Err(err) => { + self.get_logger().warn(format!( + "Cache folder ({}) cannot be created: {}", + path.display(), + err + )); + Ok(None) + } + } } fn set_cache_path(&mut self, cache_path: String) { diff --git a/rust/src/metadata.rs b/rust/src/metadata.rs index f65dcbad0c4b4..90ebdeb8929fd 100644 --- a/rust/src/metadata.rs +++ b/rust/src/metadata.rs @@ -73,25 +73,26 @@ fn new_metadata(log: &Logger) -> Metadata { } } -pub fn get_metadata(log: &Logger, cache_path: PathBuf) -> Metadata { - let metadata_path = get_metadata_path(cache_path); - log.trace(format!("Reading metadata from {}", metadata_path.display())); - - if metadata_path.exists() { - let metadata_file = File::open(&metadata_path).unwrap(); - let metadata: Metadata = match serde_json::from_reader(&metadata_file) { - Ok::(mut meta) => { - let now = now_unix_timestamp(); - meta.browsers.retain(|b| b.browser_ttl > now); - meta.drivers.retain(|d| d.driver_ttl > now); - meta - } - Err(_e) => new_metadata(log), - }; - metadata - } else { - new_metadata(log) +pub fn get_metadata(log: &Logger, cache_path: &Option) -> Metadata { + if let Some(cache) = cache_path { + let metadata_path = get_metadata_path(cache.clone()); + log.trace(format!("Reading metadata from {}", metadata_path.display())); + + if metadata_path.exists() { + let metadata_file = File::open(&metadata_path).unwrap(); + let metadata: Metadata = match serde_json::from_reader(&metadata_file) { + Ok::(mut meta) => { + let now = now_unix_timestamp(); + meta.browsers.retain(|b| b.browser_ttl > now); + meta.drivers.retain(|d| d.driver_ttl > now); + meta + } + Err(_e) => new_metadata(log), // Empty metadata + }; + return metadata; + } } + new_metadata(log) // Empty metadata } pub fn get_browser_version_from_metadata( @@ -158,14 +159,22 @@ pub fn create_driver_metadata( } } -pub fn write_metadata(metadata: &Metadata, log: &Logger, cache_path: PathBuf) { - let metadata_path = get_metadata_path(cache_path); - log.trace(format!("Writing metadata to {}", metadata_path.display())); - fs::write( - metadata_path, - serde_json::to_string_pretty(metadata).unwrap(), - ) - .unwrap(); +pub fn write_metadata(metadata: &Metadata, log: &Logger, cache_path: Option) { + if let Some(cache) = cache_path { + let metadata_path = get_metadata_path(cache.clone()); + log.trace(format!("Writing metadata to {}", metadata_path.display())); + fs::write( + metadata_path, + serde_json::to_string_pretty(metadata).unwrap(), + ) + .unwrap_or_else(|err| { + log.warn(format!( + "Metadata cannot be written in cache ({}): {}", + cache.display(), + err + )); + }); + } } pub fn clear_metadata(log: &Logger, path: &str) { diff --git a/rust/tests/common.rs b/rust/tests/common.rs index 4e53f72d0d581..3db8572bdf93c 100644 --- a/rust/tests/common.rs +++ b/rust/tests/common.rs @@ -22,7 +22,7 @@ use std::env::consts::OS; use std::path::Path; use is_executable::is_executable; -use selenium_manager::files::path_buf_to_string; +use selenium_manager::files::path_to_string; use selenium_manager::logger::JsonOutput; use selenium_manager::shell; use selenium_manager::shell::run_shell_command_by_os; @@ -54,7 +54,7 @@ pub fn get_driver_path(cmd: &mut Command) -> String { let stdout = &cmd.unwrap().stdout; let output = std::str::from_utf8(stdout).unwrap(); let json: JsonOutput = serde_json::from_str(output).unwrap(); - path_buf_to_string(Path::new(&json.result.driver_path).to_path_buf()) + path_to_string(Path::new(&json.result.driver_path)) } #[allow(dead_code)]