use std::path::{Path, PathBuf};
use std::process::Command;
use anyhow::{Context, Result, bail};
pub fn find(program: &str, install_hint: &str) -> Result<PathBuf> {
which::which(program).with_context(|| format!("`{program}` not found on PATH. {install_hint}"))
}
pub fn warn_on_dx_mismatch(dx: &Path, dioxus_version: &str) -> Result<()> {
let output = Command::new(dx)
.arg("--version")
.output()
.context("failed to run `dx --version`")?;
let text = String::from_utf8_lossy(&output.stdout);
let dx_version = text.split_whitespace().nth(1).unwrap_or_default();
if !same_minor(dx_version, dioxus_version) {
eprintln!(
"warning: dx is {dx_version} but the project uses dioxus {dioxus_version}. \
Install the matching CLI with `cargo install dioxus-cli --version {dioxus_version} --locked`."
);
}
Ok(())
}
pub fn dx_bundle(dx: &Path, root: &Path, package: Option<&str>) -> Result<()> {
let mut args = vec!["bundle", "--web", "--release"];
if let Some(package) = package {
args.extend(["--package", package]);
}
run(dx, &args, root)
}
pub fn vercel_deploy(root: &Path, prod: bool, project: Option<&str>) -> Result<()> {
let vercel = find(
"vercel",
"Install it with `npm i -g vercel`, then run `vercel login`.",
)?;
let mut args = vec!["deploy", "--prebuilt"];
if prod {
args.push("--prod");
}
if let Some(project) = project {
args.extend(["--yes", "--project", project, "--create-if-missing"]);
}
run(&vercel, &args, root)
}
fn run(program: &Path, args: &[&str], dir: &Path) -> Result<()> {
let name = program.file_stem().unwrap_or_default().to_string_lossy();
println!("> {name} {}", args.join(" "));
let status = Command::new(program)
.args(args)
.current_dir(dir)
.status()
.with_context(|| format!("failed to start `{name}`"))?;
if !status.success() {
bail!("`{name} {}` failed ({status})", args.join(" "));
}
Ok(())
}
fn same_minor(a: &str, b: &str) -> bool {
!a.is_empty() && a.split('.').take(2).eq(b.split('.').take(2))
}
#[cfg(test)]
mod tests {
use super::same_minor;
#[test]
fn matching_minor_versions() {
assert!(same_minor("0.7.10", "0.7.10"));
assert!(same_minor("0.7.3", "0.7.10"));
assert!(same_minor("0.8.0-alpha.3", "0.8.1"));
}
#[test]
fn mismatched_or_unknown_versions() {
assert!(!same_minor("0.6.3", "0.7.10"));
assert!(!same_minor("0.8.0-alpha.3", "0.7.10"));
assert!(!same_minor("", "0.7.10"));
}
}