From 60110772715f3341b90d5ed7ff0d33da3aca2593 Mon Sep 17 00:00:00 2001 From: Mridankan Mandal Date: Tue, 2 Jun 2026 02:05:39 +0530 Subject: [PATCH 1/3] fix: resolve workspace compilation for plotly_static (#400) When checking out the repository fresh and running `cargo check` at the workspace root, compilation fails because `plotly_static` has no driver features enabled by default. This commit resolves the compilation error by: 1. Adding `default = ["chromedriver"]` to `plotly_static/Cargo.toml` features. 2. Making Chrome configurations conditional on `not(feature = "geckodriver")` to allow Firefox (`geckodriver`) to take priority when both features are active simultaneously (e.g. in CI pipelines). 3. Replacing the mutual exclusion compile error in `build.rs` with a compiler warning. Signed-off-by: Mridankan Mandal --- plotly_static/Cargo.toml | 99 +++++++++++++++++----------------- plotly_static/build.rs | 13 +++-- plotly_static/src/lib.rs | 21 ++++---- plotly_static/src/template.rs | 2 +- plotly_static/src/webdriver.rs | 9 ++-- 5 files changed, 71 insertions(+), 73 deletions(-) diff --git a/plotly_static/Cargo.toml b/plotly_static/Cargo.toml index 39b3b5f8..855d9541 100644 --- a/plotly_static/Cargo.toml +++ b/plotly_static/Cargo.toml @@ -1,49 +1,50 @@ -[package] -name = "plotly_static" -version = "0.1.0" -description = "Export Plotly graphs to static images using WebDriver" -authors = ["Andrei Gherghescu andrei-ng@protonmail.com"] -license = "MIT" -workspace = ".." -homepage = "https://github.com/plotly/plotly.rs" -repository = "https://github.com/plotly/plotly.rs" -edition = "2021" -keywords = ["plotly", "static", "image", "export", "webdriver"] - -exclude = ["target/*"] - -[features] -webdriver_download = [] -geckodriver = [] -chromedriver = [] -# This is used for enabling extra debugging messages and debugging functionality -debug = [] - -[dependencies] -log = "0.4" -serde = { version = "1.0", features = ["derive"] } -rand = "0.10" -serde_json = "1.0" -base64 = "0.22" -fantoccini = "0.22" -tokio = { version = "1", features = ["full"] } -anyhow = "1.0" -urlencoding = "2" -reqwest = { version = "0.13", features = ["blocking"] } - -[dev-dependencies] -plotly_static = { path = "." } -ndarray = { version = "0.17" } -env_logger = "0.11" -clap = { version = "4.0", features = ["derive"] } - -[build-dependencies] -tokio = { version = "1", features = ["full"] } -anyhow = "1.0" -dirs = "6.0" -zip = "8.0" -webdriver-downloader = "0.16" - -# Needed for docs.rs to build the documentation -[package.metadata.docs.rs] -features = ["chromedriver"] +[package] +name = "plotly_static" +version = "0.1.0" +description = "Export Plotly graphs to static images using WebDriver" +authors = ["Andrei Gherghescu andrei-ng@protonmail.com"] +license = "MIT" +workspace = ".." +homepage = "https://github.com/plotly/plotly.rs" +repository = "https://github.com/plotly/plotly.rs" +edition = "2021" +keywords = ["plotly", "static", "image", "export", "webdriver"] + +exclude = ["target/*"] + +[features] +default = ["chromedriver"] +webdriver_download = [] +geckodriver = [] +chromedriver = [] +# This is used for enabling extra debugging messages and debugging functionality +debug = [] + +[dependencies] +log = "0.4" +serde = { version = "1.0", features = ["derive"] } +rand = "0.10" +serde_json = "1.0" +base64 = "0.22" +fantoccini = "0.22" +tokio = { version = "1", features = ["full"] } +anyhow = "1.0" +urlencoding = "2" +reqwest = { version = "0.13", features = ["blocking"] } + +[dev-dependencies] +plotly_static = { path = "." } +ndarray = { version = "0.17" } +env_logger = "0.11" +clap = { version = "4.0", features = ["derive"] } + +[build-dependencies] +tokio = { version = "1", features = ["full"] } +anyhow = "1.0" +dirs = "6.0" +zip = "8.0" +webdriver-downloader = "0.16" + +# Needed for docs.rs to build the documentation +[package.metadata.docs.rs] +features = ["chromedriver"] diff --git a/plotly_static/build.rs b/plotly_static/build.rs index 49f18a50..f68971f0 100644 --- a/plotly_static/build.rs +++ b/plotly_static/build.rs @@ -8,10 +8,6 @@ use anyhow::{anyhow, Context, Result}; use tokio::time::sleep; use webdriver_downloader::prelude::*; -// Enforce that only one driver feature is enabled -#[cfg(all(feature = "geckodriver", feature = "chromedriver"))] -compile_error!("Only one of 'geckodriver' or 'chromedriver' features can be enabled at a time."); - // Enforce that at least one driver feature is enabled #[cfg(not(any(feature = "geckodriver", feature = "chromedriver")))] compile_error!("At least one of 'geckodriver' or 'chromedriver' features must be enabled."); @@ -199,7 +195,7 @@ fn setup_driver(config: &WebdriverDownloadConfig) -> Result<()> { Ok(()) } -#[cfg(feature = "chromedriver")] +#[cfg(all(feature = "chromedriver", not(feature = "geckodriver")))] fn get_chrome_path() -> Result { if let Ok(chrome_path) = env::var(BROWSER_BIN_PATH_ENV) { let path = PathBuf::from(&chrome_path); @@ -292,6 +288,9 @@ async fn download( } fn main() -> Result<()> { + #[cfg(all(feature = "geckodriver", feature = "chromedriver"))] + println!("cargo::warning=Both 'geckodriver' and 'chromedriver' features are enabled. 'geckodriver' will take priority."); + if cfg!(feature = "webdriver_download") { println!("cargo:rerun-if-changed=src/lib.rs"); let webdriver_bin_dir = user_bin_dir(); @@ -300,7 +299,7 @@ fn main() -> Result<()> { webdriver_bin_dir.to_string_lossy() ); - #[cfg(feature = "chromedriver")] + #[cfg(all(feature = "chromedriver", not(feature = "geckodriver")))] { let config = WebdriverDownloadConfig { driver_name: CHROMEDRIVER_NAME, @@ -323,7 +322,7 @@ fn main() -> Result<()> { println!("cargo::warning=No specific driver feature enabled, skipping driver setup"); } } else { - #[cfg(feature = "chromedriver")] + #[cfg(all(feature = "chromedriver", not(feature = "geckodriver")))] { let msg = format!("'webdriver_download' feature disabled. Please install a '{CHROMEDRIVER_NAME}' version manually and make the environment variable 'WEBDRIVER_PATH' point to it."); println!("cargo::warning={msg}"); diff --git a/plotly_static/src/lib.rs b/plotly_static/src/lib.rs index 804e19e9..3d9004d3 100644 --- a/plotly_static/src/lib.rs +++ b/plotly_static/src/lib.rs @@ -461,24 +461,20 @@ impl Default for StaticExporterBuilder { offline_mode: false, pdf_export_timeout: 150, webdriver_browser_caps: { - #[cfg(feature = "chromedriver")] + #[cfg(feature = "geckodriver")] { - crate::webdriver::chrome_default_caps() + crate::webdriver::firefox_default_caps() .into_iter() .map(|s| s.to_string()) .collect() } - #[cfg(feature = "geckodriver")] + #[cfg(all(feature = "chromedriver", not(feature = "geckodriver")))] { - crate::webdriver::firefox_default_caps() + crate::webdriver::chrome_default_caps() .into_iter() .map(|s| s.to_string()) .collect() } - #[cfg(not(any(feature = "chromedriver", feature = "geckodriver")))] - { - Vec::new() - } }, } } @@ -1129,7 +1125,7 @@ impl AsyncStaticExporter { browser_opts.insert("args".to_string(), serde_json::json!(browser_args)); // Add Chrome binary capability if BROWSER_PATH is set - #[cfg(feature = "chromedriver")] + #[cfg(all(feature = "chromedriver", not(feature = "geckodriver")))] if let Ok(chrome_path) = std::env::var("BROWSER_PATH") { browser_opts.insert("binary".to_string(), serde_json::json!(chrome_path)); debug!("Added Chrome binary capability: {chrome_path}"); @@ -1610,7 +1606,7 @@ mod tests { } #[test] - #[cfg(feature = "chromedriver")] + #[cfg(all(feature = "chromedriver", not(feature = "geckodriver")))] // Skip this test for geckodriver as it doesn't support multiple concurrent // sessions on the same process as gracefully as chromedriver fn test_webdriver_process_reuse() { @@ -1675,7 +1671,7 @@ mod tests { } } -#[cfg(feature = "chromedriver")] +#[cfg(all(feature = "chromedriver", not(feature = "geckodriver")))] mod chrome { /// Returns the browser name for Chrome WebDriver. /// @@ -1713,7 +1709,8 @@ mod firefox { } } -#[cfg(feature = "chromedriver")] +#[cfg(all(feature = "chromedriver", not(feature = "geckodriver")))] use chrome::{get_browser_name, get_options_key}; #[cfg(feature = "geckodriver")] use firefox::{get_browser_name, get_options_key}; + diff --git a/plotly_static/src/template.rs b/plotly_static/src/template.rs index c83c24f9..b51e1091 100644 --- a/plotly_static/src/template.rs +++ b/plotly_static/src/template.rs @@ -39,7 +39,7 @@ pub(crate) fn image_export_js_script() -> String { } pub(crate) fn pdf_export_js_script(timeout_ms: u32) -> String { - let foreign_object_rendering = if cfg!(feature = "chromedriver") { + let foreign_object_rendering = if cfg!(all(feature = "chromedriver", not(feature = "geckodriver"))) { "true" } else { "false" diff --git a/plotly_static/src/webdriver.rs b/plotly_static/src/webdriver.rs index fa6f2e1c..a8de797d 100644 --- a/plotly_static/src/webdriver.rs +++ b/plotly_static/src/webdriver.rs @@ -26,15 +26,16 @@ const WEBDRIVER_PATH_ENV: &str = "WEBDRIVER_PATH"; #[cfg(feature = "geckodriver")] const WEBDRIVER_BIN: &str = "geckodriver"; -#[cfg(feature = "chromedriver")] +#[cfg(all(feature = "chromedriver", not(feature = "geckodriver")))] const WEBDRIVER_BIN: &str = "chromedriver"; + /// Default WebDriver port pub(crate) const WEBDRIVER_PORT: u32 = 4444; /// Default WebDriver URL pub(crate) const WEBDRIVER_URL: &str = "http://127.0.0.1"; -#[cfg(all(feature = "chromedriver", not(target_os = "windows")))] +#[cfg(all(feature = "chromedriver", not(feature = "geckodriver"), not(target_os = "windows")))] pub(crate) fn chrome_default_caps() -> Vec<&'static str> { vec![ "--headless", @@ -65,7 +66,7 @@ pub(crate) fn chrome_default_caps() -> Vec<&'static str> { ] } -#[cfg(all(feature = "chromedriver", target_os = "windows"))] +#[cfg(all(feature = "chromedriver", not(feature = "geckodriver"), target_os = "windows"))] pub(crate) fn chrome_default_caps() -> Vec<&'static str> { vec![ "--headless=new", @@ -555,7 +556,7 @@ impl WebDriver { } // Check if chromedriver is in PATH (Windows-specific) - #[cfg(all(target_os = "windows", feature = "chromedriver"))] + #[cfg(all(target_os = "windows", feature = "chromedriver", not(feature = "geckodriver")))] { if let Ok(output) = std::process::Command::new("where") .arg("chromedriver") From 7ccfe35fbb890fd4c61cf859fd1d2e71cb759536 Mon Sep 17 00:00:00 2001 From: RedZapdos123 Date: Tue, 2 Jun 2026 08:51:23 +0530 Subject: [PATCH 2/3] fix: allow plotly_static to compile without drivers Allow plotly_static to compile without driver features so fresh workspace builds and no-feature plotly test builds no longer fail. Keep chromedriver/geckodriver mutually exclusive for actual export use, return a runtime error when export is attempted without a driver feature, and suppress the no-feature build-script unused warnings that trigger a rustc ICE on stable. Signed-off-by: Mridankan Mandal --- plotly_static/Cargo.toml | 9 ++- plotly_static/README.md | 1 + plotly_static/build.rs | 18 +++--- plotly_static/src/lib.rs | 107 +++++++++++++++++++-------------- plotly_static/src/template.rs | 2 +- plotly_static/src/webdriver.rs | 10 +-- 6 files changed, 84 insertions(+), 63 deletions(-) diff --git a/plotly_static/Cargo.toml b/plotly_static/Cargo.toml index 855d9541..be3285e7 100644 --- a/plotly_static/Cargo.toml +++ b/plotly_static/Cargo.toml @@ -12,11 +12,10 @@ keywords = ["plotly", "static", "image", "export", "webdriver"] exclude = ["target/*"] -[features] -default = ["chromedriver"] -webdriver_download = [] -geckodriver = [] -chromedriver = [] +[features] +webdriver_download = [] +geckodriver = [] +chromedriver = [] # This is used for enabling extra debugging messages and debugging functionality debug = [] diff --git a/plotly_static/README.md b/plotly_static/README.md index c2c20feb..46a78ae5 100644 --- a/plotly_static/README.md +++ b/plotly_static/README.md @@ -63,6 +63,7 @@ serde_json = "1.0" ### Feature Flags +- To use static export, enable exactly one of the driver features below. - `chromedriver`: Use Chromedriver and Chrome/Chromium browser for rendering and export - `geckodriver`: Use Geckodriver Firefox browser for rendering for rendering and export - `webdriver_download`: Auto-download the chosen WebDriver binary diff --git a/plotly_static/build.rs b/plotly_static/build.rs index f68971f0..a574fa8b 100644 --- a/plotly_static/build.rs +++ b/plotly_static/build.rs @@ -1,3 +1,8 @@ +#![cfg_attr( + not(any(feature = "geckodriver", feature = "chromedriver")), + allow(unused) +)] + use std::env; use std::fs; use std::path::{Path, PathBuf}; @@ -8,9 +13,9 @@ use anyhow::{anyhow, Context, Result}; use tokio::time::sleep; use webdriver_downloader::prelude::*; -// Enforce that at least one driver feature is enabled -#[cfg(not(any(feature = "geckodriver", feature = "chromedriver")))] -compile_error!("At least one of 'geckodriver' or 'chromedriver' features must be enabled."); +// Enforce that only one driver feature is enabled +#[cfg(all(feature = "geckodriver", feature = "chromedriver"))] +compile_error!("Only one of 'geckodriver' or 'chromedriver' features can be enabled at a time."); #[cfg(target_os = "windows")] const DRIVER_EXT: &str = ".exe"; @@ -288,9 +293,6 @@ async fn download( } fn main() -> Result<()> { - #[cfg(all(feature = "geckodriver", feature = "chromedriver"))] - println!("cargo::warning=Both 'geckodriver' and 'chromedriver' features are enabled. 'geckodriver' will take priority."); - if cfg!(feature = "webdriver_download") { println!("cargo:rerun-if-changed=src/lib.rs"); let webdriver_bin_dir = user_bin_dir(); @@ -299,7 +301,7 @@ fn main() -> Result<()> { webdriver_bin_dir.to_string_lossy() ); - #[cfg(all(feature = "chromedriver", not(feature = "geckodriver")))] + #[cfg(feature = "chromedriver")] { let config = WebdriverDownloadConfig { driver_name: CHROMEDRIVER_NAME, @@ -322,7 +324,7 @@ fn main() -> Result<()> { println!("cargo::warning=No specific driver feature enabled, skipping driver setup"); } } else { - #[cfg(all(feature = "chromedriver", not(feature = "geckodriver")))] + #[cfg(feature = "chromedriver")] { let msg = format!("'webdriver_download' feature disabled. Please install a '{CHROMEDRIVER_NAME}' version manually and make the environment variable 'WEBDRIVER_PATH' point to it."); println!("cargo::warning={msg}"); diff --git a/plotly_static/src/lib.rs b/plotly_static/src/lib.rs index 3d9004d3..1a51215d 100644 --- a/plotly_static/src/lib.rs +++ b/plotly_static/src/lib.rs @@ -59,9 +59,9 @@ //! //! ## Features and Dependencies //! -//! ### Required Features +//! ### Driver Features //! -//! You must enable one of the following features: +//! To use static export, enable one of the following features: //! //! - `chromedriver`: Use Chrome/Chromium for rendering //! - `geckodriver`: Use Firefox for rendering @@ -294,6 +294,7 @@ use fantoccini::{wd::Capabilities, Client, ClientBuilder}; #[cfg(not(any(test, feature = "debug")))] use log::{debug, error, warn}; use serde::Serialize; +#[cfg(any(feature = "chromedriver", feature = "geckodriver"))] use serde_json::map::Map as JsonMap; use urlencoding::encode; use webdriver::WebDriver; @@ -461,20 +462,24 @@ impl Default for StaticExporterBuilder { offline_mode: false, pdf_export_timeout: 150, webdriver_browser_caps: { - #[cfg(feature = "geckodriver")] + #[cfg(feature = "chromedriver")] { - crate::webdriver::firefox_default_caps() + crate::webdriver::chrome_default_caps() .into_iter() .map(|s| s.to_string()) .collect() } - #[cfg(all(feature = "chromedriver", not(feature = "geckodriver")))] + #[cfg(feature = "geckodriver")] { - crate::webdriver::chrome_default_caps() + crate::webdriver::firefox_default_caps() .into_iter() .map(|s| s.to_string()) .collect() } + #[cfg(not(any(feature = "chromedriver", feature = "geckodriver")))] + { + Vec::new() + } }, } } @@ -923,6 +928,10 @@ pub struct AsyncStaticExporter { pdf_export_timeout: u32, /// Browser command-line flags (e.g., "--headless", "--no-sandbox") + #[cfg_attr( + not(any(feature = "chromedriver", feature = "geckodriver")), + allow(dead_code) + )] webdriver_browser_caps: Vec, /// Cached WebDriver client for session reuse @@ -1117,46 +1126,55 @@ impl AsyncStaticExporter { } fn build_webdriver_caps(&self) -> Result { - // Define browser capabilities (copied to avoid reordering existing code) - let mut caps = JsonMap::new(); - let mut browser_opts = JsonMap::new(); - let browser_args = self.webdriver_browser_caps.clone(); - - browser_opts.insert("args".to_string(), serde_json::json!(browser_args)); - - // Add Chrome binary capability if BROWSER_PATH is set - #[cfg(all(feature = "chromedriver", not(feature = "geckodriver")))] - if let Ok(chrome_path) = std::env::var("BROWSER_PATH") { - browser_opts.insert("binary".to_string(), serde_json::json!(chrome_path)); - debug!("Added Chrome binary capability: {chrome_path}"); - } - // Add Firefox binary capability if BROWSER_PATH is set - #[cfg(feature = "geckodriver")] - if let Ok(firefox_path) = std::env::var("BROWSER_PATH") { - browser_opts.insert("binary".to_string(), serde_json::json!(firefox_path)); - debug!("Added Firefox binary capability: {firefox_path}"); - } - - // Add Firefox-specific preferences for CI environments - #[cfg(feature = "geckodriver")] + #[cfg(not(any(feature = "chromedriver", feature = "geckodriver")))] { - let prefs = common::get_firefox_ci_preferences(); - browser_opts.insert("prefs".to_string(), serde_json::json!(prefs)); - debug!("Added Firefox preferences for CI compatibility"); + Err(anyhow!( + "Static image export requires enabling either the 'chromedriver' or 'geckodriver' feature." + )) } + #[cfg(any(feature = "chromedriver", feature = "geckodriver"))] + { + // Define browser capabilities (copied to avoid reordering existing code) + let mut caps = JsonMap::new(); + let mut browser_opts = JsonMap::new(); + let browser_args = self.webdriver_browser_caps.clone(); + + browser_opts.insert("args".to_string(), serde_json::json!(browser_args)); + + // Add Chrome binary capability if BROWSER_PATH is set + #[cfg(feature = "chromedriver")] + if let Ok(chrome_path) = std::env::var("BROWSER_PATH") { + browser_opts.insert("binary".to_string(), serde_json::json!(chrome_path)); + debug!("Added Chrome binary capability: {chrome_path}"); + } + // Add Firefox binary capability if BROWSER_PATH is set + #[cfg(feature = "geckodriver")] + if let Ok(firefox_path) = std::env::var("BROWSER_PATH") { + browser_opts.insert("binary".to_string(), serde_json::json!(firefox_path)); + debug!("Added Firefox binary capability: {firefox_path}"); + } - caps.insert( - "browserName".to_string(), - serde_json::json!(get_browser_name()), - ); - caps.insert( - get_options_key().to_string(), - serde_json::json!(browser_opts), - ); + // Add Firefox-specific preferences for CI environments + #[cfg(feature = "geckodriver")] + { + let prefs = common::get_firefox_ci_preferences(); + browser_opts.insert("prefs".to_string(), serde_json::json!(prefs)); + debug!("Added Firefox preferences for CI compatibility"); + } + + caps.insert( + "browserName".to_string(), + serde_json::json!(get_browser_name()), + ); + caps.insert( + get_options_key().to_string(), + serde_json::json!(browser_opts), + ); - debug!("WebDriver capabilities: {caps:?}"); + debug!("WebDriver capabilities: {caps:?}"); - Ok(caps) + Ok(caps) + } } #[cfg(target_os = "windows")] @@ -1606,7 +1624,7 @@ mod tests { } #[test] - #[cfg(all(feature = "chromedriver", not(feature = "geckodriver")))] + #[cfg(feature = "chromedriver")] // Skip this test for geckodriver as it doesn't support multiple concurrent // sessions on the same process as gracefully as chromedriver fn test_webdriver_process_reuse() { @@ -1671,7 +1689,7 @@ mod tests { } } -#[cfg(all(feature = "chromedriver", not(feature = "geckodriver")))] +#[cfg(feature = "chromedriver")] mod chrome { /// Returns the browser name for Chrome WebDriver. /// @@ -1709,8 +1727,7 @@ mod firefox { } } -#[cfg(all(feature = "chromedriver", not(feature = "geckodriver")))] +#[cfg(feature = "chromedriver")] use chrome::{get_browser_name, get_options_key}; #[cfg(feature = "geckodriver")] use firefox::{get_browser_name, get_options_key}; - diff --git a/plotly_static/src/template.rs b/plotly_static/src/template.rs index b51e1091..c83c24f9 100644 --- a/plotly_static/src/template.rs +++ b/plotly_static/src/template.rs @@ -39,7 +39,7 @@ pub(crate) fn image_export_js_script() -> String { } pub(crate) fn pdf_export_js_script(timeout_ms: u32) -> String { - let foreign_object_rendering = if cfg!(all(feature = "chromedriver", not(feature = "geckodriver"))) { + let foreign_object_rendering = if cfg!(feature = "chromedriver") { "true" } else { "false" diff --git a/plotly_static/src/webdriver.rs b/plotly_static/src/webdriver.rs index a8de797d..20b016eb 100644 --- a/plotly_static/src/webdriver.rs +++ b/plotly_static/src/webdriver.rs @@ -26,16 +26,18 @@ const WEBDRIVER_PATH_ENV: &str = "WEBDRIVER_PATH"; #[cfg(feature = "geckodriver")] const WEBDRIVER_BIN: &str = "geckodriver"; -#[cfg(all(feature = "chromedriver", not(feature = "geckodriver")))] +#[cfg(feature = "chromedriver")] const WEBDRIVER_BIN: &str = "chromedriver"; +#[cfg(not(any(feature = "chromedriver", feature = "geckodriver")))] +const WEBDRIVER_BIN: &str = "webdriver"; /// Default WebDriver port pub(crate) const WEBDRIVER_PORT: u32 = 4444; /// Default WebDriver URL pub(crate) const WEBDRIVER_URL: &str = "http://127.0.0.1"; -#[cfg(all(feature = "chromedriver", not(feature = "geckodriver"), not(target_os = "windows")))] +#[cfg(all(feature = "chromedriver", not(target_os = "windows")))] pub(crate) fn chrome_default_caps() -> Vec<&'static str> { vec![ "--headless", @@ -66,7 +68,7 @@ pub(crate) fn chrome_default_caps() -> Vec<&'static str> { ] } -#[cfg(all(feature = "chromedriver", not(feature = "geckodriver"), target_os = "windows"))] +#[cfg(all(feature = "chromedriver", target_os = "windows"))] pub(crate) fn chrome_default_caps() -> Vec<&'static str> { vec![ "--headless=new", @@ -556,7 +558,7 @@ impl WebDriver { } // Check if chromedriver is in PATH (Windows-specific) - #[cfg(all(target_os = "windows", feature = "chromedriver", not(feature = "geckodriver")))] + #[cfg(all(target_os = "windows", feature = "chromedriver"))] { if let Ok(output) = std::process::Command::new("where") .arg("chromedriver") From 7c1781b3a5e347bf35bd2779773ead6bb5851d6e Mon Sep 17 00:00:00 2001 From: RedZapdos123 Date: Tue, 2 Jun 2026 13:25:43 +0530 Subject: [PATCH 3/3] chore: normalize plotly_static Cargo.toml eol Normalize plotly_static/Cargo.toml line endings to LF so the PR diff reflects the actual feature change instead of whole-file EOL churn. Signed-off-by: Mridankan Mandal --- plotly_static/Cargo.toml | 90 ++++++++++++++++++++-------------------- 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/plotly_static/Cargo.toml b/plotly_static/Cargo.toml index be3285e7..39b3b5f8 100644 --- a/plotly_static/Cargo.toml +++ b/plotly_static/Cargo.toml @@ -1,49 +1,49 @@ -[package] -name = "plotly_static" -version = "0.1.0" -description = "Export Plotly graphs to static images using WebDriver" -authors = ["Andrei Gherghescu andrei-ng@protonmail.com"] -license = "MIT" -workspace = ".." -homepage = "https://github.com/plotly/plotly.rs" -repository = "https://github.com/plotly/plotly.rs" -edition = "2021" -keywords = ["plotly", "static", "image", "export", "webdriver"] - -exclude = ["target/*"] - +[package] +name = "plotly_static" +version = "0.1.0" +description = "Export Plotly graphs to static images using WebDriver" +authors = ["Andrei Gherghescu andrei-ng@protonmail.com"] +license = "MIT" +workspace = ".." +homepage = "https://github.com/plotly/plotly.rs" +repository = "https://github.com/plotly/plotly.rs" +edition = "2021" +keywords = ["plotly", "static", "image", "export", "webdriver"] + +exclude = ["target/*"] + [features] webdriver_download = [] geckodriver = [] chromedriver = [] -# This is used for enabling extra debugging messages and debugging functionality -debug = [] - -[dependencies] -log = "0.4" -serde = { version = "1.0", features = ["derive"] } -rand = "0.10" -serde_json = "1.0" -base64 = "0.22" -fantoccini = "0.22" -tokio = { version = "1", features = ["full"] } -anyhow = "1.0" -urlencoding = "2" -reqwest = { version = "0.13", features = ["blocking"] } - -[dev-dependencies] -plotly_static = { path = "." } -ndarray = { version = "0.17" } -env_logger = "0.11" -clap = { version = "4.0", features = ["derive"] } - -[build-dependencies] -tokio = { version = "1", features = ["full"] } -anyhow = "1.0" -dirs = "6.0" -zip = "8.0" -webdriver-downloader = "0.16" - -# Needed for docs.rs to build the documentation -[package.metadata.docs.rs] -features = ["chromedriver"] +# This is used for enabling extra debugging messages and debugging functionality +debug = [] + +[dependencies] +log = "0.4" +serde = { version = "1.0", features = ["derive"] } +rand = "0.10" +serde_json = "1.0" +base64 = "0.22" +fantoccini = "0.22" +tokio = { version = "1", features = ["full"] } +anyhow = "1.0" +urlencoding = "2" +reqwest = { version = "0.13", features = ["blocking"] } + +[dev-dependencies] +plotly_static = { path = "." } +ndarray = { version = "0.17" } +env_logger = "0.11" +clap = { version = "4.0", features = ["derive"] } + +[build-dependencies] +tokio = { version = "1", features = ["full"] } +anyhow = "1.0" +dirs = "6.0" +zip = "8.0" +webdriver-downloader = "0.16" + +# Needed for docs.rs to build the documentation +[package.metadata.docs.rs] +features = ["chromedriver"]