From 1998957bddc9b2cb5944aae31a74cffefdcad539 Mon Sep 17 00:00:00 2001 From: Mike Birdgeneau Date: Wed, 29 Mar 2023 15:14:31 -0600 Subject: [PATCH 1/2] Remove dependency on sys_info (#1) Remove reliance on `sys_info` crate to determine OS in favour of std::env::consts::OS --- Cargo.toml | 1 - src/chromedriver.rs | 8 ++++---- src/geckodriver.rs | 8 ++++---- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 802ca75..77cac73 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,7 +26,6 @@ dirs-sys = "0.3" eyre = "0.6" flate2 = "1" regex = "1" -sys-info = "0.9" tar = "0.4" zip = "0.5" tracing = "0.1" diff --git a/src/chromedriver.rs b/src/chromedriver.rs index d39f6e0..20c6e45 100644 --- a/src/chromedriver.rs +++ b/src/chromedriver.rs @@ -57,10 +57,10 @@ impl Chromedriver { /// If future chromedriver releases have multiple pointer widths per platform, /// we have to change this to work like `Geckodriver::platform`. fn platform() -> Result { - match sys_info::os_type()?.as_str() { - "Linux" => Ok(String::from("linux64.zip")), - "Darwin" => Ok(String::from("mac64.zip")), - "Windows" => Ok(String::from("win32.zip")), + match std::env::consts::OS { + "linux" => Ok(String::from("linux64.zip")), + "macos" => Ok(String::from("mac64.zip")), + "windows" => Ok(String::from("win32.zip")), other => Err(eyre!( "webdriver-install doesn't support '{}' currently", other diff --git a/src/geckodriver.rs b/src/geckodriver.rs index 0ece9f0..61feca7 100644 --- a/src/geckodriver.rs +++ b/src/geckodriver.rs @@ -32,10 +32,10 @@ impl Geckodriver { } fn platform() -> Result { - match sys_info::os_type()?.as_str() { - "Linux" => Ok(format!("linux{}.tar.gz", Self::pointer_width())), - "Darwin" => Ok(String::from("macos.tar.gz")), - "Windows" => Ok(format!("win{}.zip", Self::pointer_width())), + match std::env::consts::OS { + "linux" => Ok(format!("linux{}.tar.gz", Self::pointer_width())), + "macos" => Ok(String::from("macos.tar.gz")), + "windows" => Ok(format!("win{}.zip", Self::pointer_width())), other => Err(eyre!( "webdriver-install doesn't support '{}' currently", other From bbefab85b588f838317e4bdac7a3c94d9d43436f Mon Sep 17 00:00:00 2001 From: Mike Birdgeneau Date: Fri, 26 Jul 2024 10:19:24 -0600 Subject: [PATCH 2/2] Update for latest Chromedriver URL. Currently using JSON to fetch latest. --- Cargo.toml | 3 ++- examples/latest_chromedriver.rs | 5 ++++ src/chromedriver.rs | 42 +++++++++++++++++++-------------- src/installer.rs | 10 ++++---- 4 files changed, 37 insertions(+), 23 deletions(-) create mode 100644 examples/latest_chromedriver.rs diff --git a/Cargo.toml b/Cargo.toml index 77cac73..be7e4ef 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,13 +31,14 @@ zip = "0.5" tracing = "0.1" tracing-subscriber = "0.3" url = "2.2" +serde_json = "1.0.120" [dependencies.winapi] features = ["winuser"] version = "0.3" [dependencies.reqwest] -features = ["blocking"] +features = ["blocking", "json"] version = "0.11" [dev-dependencies] diff --git a/examples/latest_chromedriver.rs b/examples/latest_chromedriver.rs new file mode 100644 index 0000000..730575c --- /dev/null +++ b/examples/latest_chromedriver.rs @@ -0,0 +1,5 @@ +use webdriver_install::Driver; + +fn main() { + Driver::Chrome.install().unwrap(); +} diff --git a/src/chromedriver.rs b/src/chromedriver.rs index 20c6e45..628b217 100644 --- a/src/chromedriver.rs +++ b/src/chromedriver.rs @@ -4,8 +4,9 @@ /// See https://chromedriver.chromium.org/downloads/version-selection use eyre::{eyre, Result}; use regex::Regex; -use tracing::debug; +use tracing::{debug}; use url::Url; +use serde_json::Value; use std::process::{Command, Stdio}; @@ -19,24 +20,29 @@ use std::path::PathBuf; pub struct Chromedriver; impl DriverFetcher for Chromedriver { - const BASE_URL: &'static str = "https://chromedriver.storage.googleapis.com"; + const BASE_URL: &'static str = "https://storage.googleapis.com/chrome-for-testing-public"; /// Returns the latest version of the driver fn latest_version(&self) -> Result { - let latest_release_url = format!( - "{}/LATEST_RELEASE_{}", - Self::BASE_URL, - Version::find()?.build_version() - ); - debug!("latest_release_url: {}", latest_release_url); - let resp = reqwest::blocking::get(&latest_release_url)?; - Ok(resp.text()?) - } + const VERSION_URL: &'static str = "https://googlechromelabs.github.io/chrome-for-testing/known-good-versions-with-downloads.json"; + let version_response = reqwest::blocking::get(VERSION_URL)?; + let data: Value = version_response.json()?; + + // Extract the last element from the `versions` array and get the `version` field + if let Some(last_version) = data["versions"].as_array().and_then(|v| v.last()) { + if let Some(version) = last_version["version"].as_str() { + debug!("Latest version: {}", version); + return Ok(version.to_string()); + } + } + + Err(eyre!("Could not find the latest version")) +} /// Returns the download url for the driver executable fn direct_download_url(&self, version: &str) -> Result { Ok(Url::parse(&format!( - "{}/{version}/chromedriver_{platform}", + "{}/{version}/{platform}/chromedriver-{platform}.zip", Self::BASE_URL, version = version, platform = Self::platform()? @@ -58,9 +64,9 @@ impl Chromedriver { /// we have to change this to work like `Geckodriver::platform`. fn platform() -> Result { match std::env::consts::OS { - "linux" => Ok(String::from("linux64.zip")), - "macos" => Ok(String::from("mac64.zip")), - "windows" => Ok(String::from("win32.zip")), + "linux" => Ok(String::from("linux64")), + "macos" => Ok(String::from("mac64")), + "windows" => Ok(String::from("win32")), other => Err(eyre!( "webdriver-install doesn't support '{}' currently", other @@ -298,7 +304,7 @@ fn version_from_output_panic_not_4_parts_test() { fn direct_download_url_test() { #[cfg(target_os = "linux")] assert_eq!( - "https://chromedriver.storage.googleapis.com/v1/chromedriver_linux64.zip", + "https://storage.googleapis.com/chrome-for-testing-public/v1/linux64/chromedriver-linux64.zip", Chromedriver::new() .direct_download_url("v1") .unwrap() @@ -306,7 +312,7 @@ fn direct_download_url_test() { ); #[cfg(target_os = "macos")] assert_eq!( - "https://chromedriver.storage.googleapis.com/v1/chromedriver_mac64.zip", + "https://storage.googleapis.com/chrome-for-testing-public/v1/mac64/chromedriver-mac64.zip", Chromedriver::new() .direct_download_url("v1") .unwrap() @@ -314,7 +320,7 @@ fn direct_download_url_test() { ); #[cfg(target_os = "windows")] assert_eq!( - "https://chromedriver.storage.googleapis.com/v1/chromedriver_win32.zip", + "https://storage.googleapis.com/chrome-for-testing-public/v1/win32/chromedriver-win32.zip", Chromedriver::new() .direct_download_url("v1") .unwrap() diff --git a/src/installer.rs b/src/installer.rs index 7f58e99..0a9d471 100644 --- a/src/installer.rs +++ b/src/installer.rs @@ -148,10 +148,12 @@ fn decompress(archive_filename: &str, bytes: &[u8], target_dir: PathBuf) -> Resu let mut filename: Option = None; for i in 0..zip.len() { let mut file = zip.by_index(i)?; - if DRIVER_EXECUTABLES.contains(&file.name()) { - filename = Some(file.name().to_string()); - file.read_to_end(&mut zip_bytes)?; - break; + if let Some(file_name) = std::path::Path::new(file.name()).file_name().and_then(|n| n.to_str()){ + if DRIVER_EXECUTABLES.contains(&file_name) { + filename = Some(file_name.to_string()); + file.read_to_end(&mut zip_bytes)?; + break; + } } } if let Some(name) = filename {