Skip to content

Commit 6011077

Browse files
committed
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 <xerontitan90@gmail.com>
1 parent ac7e8c8 commit 6011077

5 files changed

Lines changed: 71 additions & 73 deletions

File tree

‎plotly_static/Cargo.toml‎

Lines changed: 50 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,50 @@
1-
[package]
2-
name = "plotly_static"
3-
version = "0.1.0"
4-
description = "Export Plotly graphs to static images using WebDriver"
5-
authors = ["Andrei Gherghescu andrei-ng@protonmail.com"]
6-
license = "MIT"
7-
workspace = ".."
8-
homepage = "https://github.com/plotly/plotly.rs"
9-
repository = "https://github.com/plotly/plotly.rs"
10-
edition = "2021"
11-
keywords = ["plotly", "static", "image", "export", "webdriver"]
12-
13-
exclude = ["target/*"]
14-
15-
[features]
16-
webdriver_download = []
17-
geckodriver = []
18-
chromedriver = []
19-
# This is used for enabling extra debugging messages and debugging functionality
20-
debug = []
21-
22-
[dependencies]
23-
log = "0.4"
24-
serde = { version = "1.0", features = ["derive"] }
25-
rand = "0.10"
26-
serde_json = "1.0"
27-
base64 = "0.22"
28-
fantoccini = "0.22"
29-
tokio = { version = "1", features = ["full"] }
30-
anyhow = "1.0"
31-
urlencoding = "2"
32-
reqwest = { version = "0.13", features = ["blocking"] }
33-
34-
[dev-dependencies]
35-
plotly_static = { path = "." }
36-
ndarray = { version = "0.17" }
37-
env_logger = "0.11"
38-
clap = { version = "4.0", features = ["derive"] }
39-
40-
[build-dependencies]
41-
tokio = { version = "1", features = ["full"] }
42-
anyhow = "1.0"
43-
dirs = "6.0"
44-
zip = "8.0"
45-
webdriver-downloader = "0.16"
46-
47-
# Needed for docs.rs to build the documentation
48-
[package.metadata.docs.rs]
49-
features = ["chromedriver"]
1+
[package]
2+
name = "plotly_static"
3+
version = "0.1.0"
4+
description = "Export Plotly graphs to static images using WebDriver"
5+
authors = ["Andrei Gherghescu andrei-ng@protonmail.com"]
6+
license = "MIT"
7+
workspace = ".."
8+
homepage = "https://github.com/plotly/plotly.rs"
9+
repository = "https://github.com/plotly/plotly.rs"
10+
edition = "2021"
11+
keywords = ["plotly", "static", "image", "export", "webdriver"]
12+
13+
exclude = ["target/*"]
14+
15+
[features]
16+
default = ["chromedriver"]
17+
webdriver_download = []
18+
geckodriver = []
19+
chromedriver = []
20+
# This is used for enabling extra debugging messages and debugging functionality
21+
debug = []
22+
23+
[dependencies]
24+
log = "0.4"
25+
serde = { version = "1.0", features = ["derive"] }
26+
rand = "0.10"
27+
serde_json = "1.0"
28+
base64 = "0.22"
29+
fantoccini = "0.22"
30+
tokio = { version = "1", features = ["full"] }
31+
anyhow = "1.0"
32+
urlencoding = "2"
33+
reqwest = { version = "0.13", features = ["blocking"] }
34+
35+
[dev-dependencies]
36+
plotly_static = { path = "." }
37+
ndarray = { version = "0.17" }
38+
env_logger = "0.11"
39+
clap = { version = "4.0", features = ["derive"] }
40+
41+
[build-dependencies]
42+
tokio = { version = "1", features = ["full"] }
43+
anyhow = "1.0"
44+
dirs = "6.0"
45+
zip = "8.0"
46+
webdriver-downloader = "0.16"
47+
48+
# Needed for docs.rs to build the documentation
49+
[package.metadata.docs.rs]
50+
features = ["chromedriver"]

‎plotly_static/build.rs‎

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,6 @@ use anyhow::{anyhow, Context, Result};
88
use tokio::time::sleep;
99
use webdriver_downloader::prelude::*;
1010

11-
// Enforce that only one driver feature is enabled
12-
#[cfg(all(feature = "geckodriver", feature = "chromedriver"))]
13-
compile_error!("Only one of 'geckodriver' or 'chromedriver' features can be enabled at a time.");
14-
1511
// Enforce that at least one driver feature is enabled
1612
#[cfg(not(any(feature = "geckodriver", feature = "chromedriver")))]
1713
compile_error!("At least one of 'geckodriver' or 'chromedriver' features must be enabled.");
@@ -199,7 +195,7 @@ fn setup_driver(config: &WebdriverDownloadConfig) -> Result<()> {
199195
Ok(())
200196
}
201197

202-
#[cfg(feature = "chromedriver")]
198+
#[cfg(all(feature = "chromedriver", not(feature = "geckodriver")))]
203199
fn get_chrome_path() -> Result<PathBuf> {
204200
if let Ok(chrome_path) = env::var(BROWSER_BIN_PATH_ENV) {
205201
let path = PathBuf::from(&chrome_path);
@@ -292,6 +288,9 @@ async fn download(
292288
}
293289

294290
fn main() -> Result<()> {
291+
#[cfg(all(feature = "geckodriver", feature = "chromedriver"))]
292+
println!("cargo::warning=Both 'geckodriver' and 'chromedriver' features are enabled. 'geckodriver' will take priority.");
293+
295294
if cfg!(feature = "webdriver_download") {
296295
println!("cargo:rerun-if-changed=src/lib.rs");
297296
let webdriver_bin_dir = user_bin_dir();
@@ -300,7 +299,7 @@ fn main() -> Result<()> {
300299
webdriver_bin_dir.to_string_lossy()
301300
);
302301

303-
#[cfg(feature = "chromedriver")]
302+
#[cfg(all(feature = "chromedriver", not(feature = "geckodriver")))]
304303
{
305304
let config = WebdriverDownloadConfig {
306305
driver_name: CHROMEDRIVER_NAME,
@@ -323,7 +322,7 @@ fn main() -> Result<()> {
323322
println!("cargo::warning=No specific driver feature enabled, skipping driver setup");
324323
}
325324
} else {
326-
#[cfg(feature = "chromedriver")]
325+
#[cfg(all(feature = "chromedriver", not(feature = "geckodriver")))]
327326
{
328327
let msg = format!("'webdriver_download' feature disabled. Please install a '{CHROMEDRIVER_NAME}' version manually and make the environment variable 'WEBDRIVER_PATH' point to it.");
329328
println!("cargo::warning={msg}");

‎plotly_static/src/lib.rs‎

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -461,24 +461,20 @@ impl Default for StaticExporterBuilder {
461461
offline_mode: false,
462462
pdf_export_timeout: 150,
463463
webdriver_browser_caps: {
464-
#[cfg(feature = "chromedriver")]
464+
#[cfg(feature = "geckodriver")]
465465
{
466-
crate::webdriver::chrome_default_caps()
466+
crate::webdriver::firefox_default_caps()
467467
.into_iter()
468468
.map(|s| s.to_string())
469469
.collect()
470470
}
471-
#[cfg(feature = "geckodriver")]
471+
#[cfg(all(feature = "chromedriver", not(feature = "geckodriver")))]
472472
{
473-
crate::webdriver::firefox_default_caps()
473+
crate::webdriver::chrome_default_caps()
474474
.into_iter()
475475
.map(|s| s.to_string())
476476
.collect()
477477
}
478-
#[cfg(not(any(feature = "chromedriver", feature = "geckodriver")))]
479-
{
480-
Vec::new()
481-
}
482478
},
483479
}
484480
}
@@ -1129,7 +1125,7 @@ impl AsyncStaticExporter {
11291125
browser_opts.insert("args".to_string(), serde_json::json!(browser_args));
11301126

11311127
// Add Chrome binary capability if BROWSER_PATH is set
1132-
#[cfg(feature = "chromedriver")]
1128+
#[cfg(all(feature = "chromedriver", not(feature = "geckodriver")))]
11331129
if let Ok(chrome_path) = std::env::var("BROWSER_PATH") {
11341130
browser_opts.insert("binary".to_string(), serde_json::json!(chrome_path));
11351131
debug!("Added Chrome binary capability: {chrome_path}");
@@ -1610,7 +1606,7 @@ mod tests {
16101606
}
16111607

16121608
#[test]
1613-
#[cfg(feature = "chromedriver")]
1609+
#[cfg(all(feature = "chromedriver", not(feature = "geckodriver")))]
16141610
// Skip this test for geckodriver as it doesn't support multiple concurrent
16151611
// sessions on the same process as gracefully as chromedriver
16161612
fn test_webdriver_process_reuse() {
@@ -1675,7 +1671,7 @@ mod tests {
16751671
}
16761672
}
16771673

1678-
#[cfg(feature = "chromedriver")]
1674+
#[cfg(all(feature = "chromedriver", not(feature = "geckodriver")))]
16791675
mod chrome {
16801676
/// Returns the browser name for Chrome WebDriver.
16811677
///
@@ -1713,7 +1709,8 @@ mod firefox {
17131709
}
17141710
}
17151711

1716-
#[cfg(feature = "chromedriver")]
1712+
#[cfg(all(feature = "chromedriver", not(feature = "geckodriver")))]
17171713
use chrome::{get_browser_name, get_options_key};
17181714
#[cfg(feature = "geckodriver")]
17191715
use firefox::{get_browser_name, get_options_key};
1716+

‎plotly_static/src/template.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ pub(crate) fn image_export_js_script() -> String {
3939
}
4040

4141
pub(crate) fn pdf_export_js_script(timeout_ms: u32) -> String {
42-
let foreign_object_rendering = if cfg!(feature = "chromedriver") {
42+
let foreign_object_rendering = if cfg!(all(feature = "chromedriver", not(feature = "geckodriver"))) {
4343
"true"
4444
} else {
4545
"false"

‎plotly_static/src/webdriver.rs‎

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,16 @@ const WEBDRIVER_PATH_ENV: &str = "WEBDRIVER_PATH";
2626
#[cfg(feature = "geckodriver")]
2727
const WEBDRIVER_BIN: &str = "geckodriver";
2828

29-
#[cfg(feature = "chromedriver")]
29+
#[cfg(all(feature = "chromedriver", not(feature = "geckodriver")))]
3030
const WEBDRIVER_BIN: &str = "chromedriver";
3131

32+
3233
/// Default WebDriver port
3334
pub(crate) const WEBDRIVER_PORT: u32 = 4444;
3435
/// Default WebDriver URL
3536
pub(crate) const WEBDRIVER_URL: &str = "http://127.0.0.1";
3637

37-
#[cfg(all(feature = "chromedriver", not(target_os = "windows")))]
38+
#[cfg(all(feature = "chromedriver", not(feature = "geckodriver"), not(target_os = "windows")))]
3839
pub(crate) fn chrome_default_caps() -> Vec<&'static str> {
3940
vec![
4041
"--headless",
@@ -65,7 +66,7 @@ pub(crate) fn chrome_default_caps() -> Vec<&'static str> {
6566
]
6667
}
6768

68-
#[cfg(all(feature = "chromedriver", target_os = "windows"))]
69+
#[cfg(all(feature = "chromedriver", not(feature = "geckodriver"), target_os = "windows"))]
6970
pub(crate) fn chrome_default_caps() -> Vec<&'static str> {
7071
vec![
7172
"--headless=new",
@@ -555,7 +556,7 @@ impl WebDriver {
555556
}
556557

557558
// Check if chromedriver is in PATH (Windows-specific)
558-
#[cfg(all(target_os = "windows", feature = "chromedriver"))]
559+
#[cfg(all(target_os = "windows", feature = "chromedriver", not(feature = "geckodriver")))]
559560
{
560561
if let Ok(output) = std::process::Command::new("where")
561562
.arg("chromedriver")

0 commit comments

Comments
 (0)