use clap::{Parser, Subcommand};
use std::path::PathBuf;
use std::process::ExitCode;
include!("../build_support/driver_assembly.rs");
#[derive(Parser)]
#[command(name = "playwright-rs", version, about, long_about = None)]
struct Cli {
#[command(subcommand)]
cmd: Cmd,
}
#[derive(Subcommand)]
enum Cmd {
Install {
browsers: Vec<String>,
#[arg(long)]
with_deps: bool,
#[arg(long)]
driver_only: bool,
},
}
#[tokio::main]
async fn main() -> ExitCode {
let cli = Cli::parse();
match cli.cmd {
Cmd::Install {
browsers,
with_deps,
driver_only,
} => match run_install(browsers, with_deps, driver_only).await {
Ok(()) => ExitCode::SUCCESS,
Err(e) => {
eprintln!("playwright-rs: {e}");
ExitCode::FAILURE
}
},
}
}
async fn run_install(
browsers: Vec<String>,
with_deps: bool,
driver_only: bool,
) -> Result<(), Box<dyn std::error::Error>> {
let version = env!("PLAYWRIGHT_DRIVER_VERSION");
let platform = env!("PLAYWRIGHT_DRIVER_PLATFORM");
let driver_dir = ensure_driver_in_user_cache(version, platform)?;
eprintln!("Driver ready at: {}", driver_dir.display());
if driver_only {
return Ok(());
}
unsafe {
std::env::set_var("PLAYWRIGHT_DRIVER_PATH", &driver_dir);
}
let browser_refs: Vec<&str> = browsers.iter().map(String::as_str).collect();
let browsers_arg: Option<&[&str]> = if browser_refs.is_empty() {
None
} else {
Some(&browser_refs)
};
if with_deps {
playwright_rs::install_browsers_with_deps(browsers_arg).await?;
} else {
playwright_rs::install_browsers(browsers_arg).await?;
}
Ok(())
}
fn ensure_driver_in_user_cache(
version: &str,
platform: &str,
) -> Result<PathBuf, Box<dyn std::error::Error>> {
let cache_root = dirs::cache_dir().ok_or("could not determine user cache directory")?;
let driver_dir = cache_root
.join("playwright-rust")
.join(version)
.join(format!("playwright-{version}-{platform}"));
let cli_js = driver_dir.join("package").join("cli.js");
if cli_js.exists() {
return Ok(driver_dir);
}
eprintln!("Assembling driver {version} (Node {NODE_VERSION}) for {platform}...");
assemble_driver(&driver_dir, version, platform)?;
Ok(driver_dir)
}