use std::path::{Path, PathBuf};
use std::process::{Command, Stdio};
use anyhow::{Context, Result, bail};
pub const INSTALL_HINT: &str = "install it with `cargo install dioxus-cli --version ^0.7 --locked`";
pub fn is_dioxus_app(app_dir: &Path) -> bool {
app_dir.join("Dioxus.toml").is_file()
}
pub fn dx_installed() -> bool {
Command::new("dx")
.arg("--version")
.stdout(Stdio::null())
.stderr(Stdio::null())
.status()
.is_ok_and(|status| status.success())
}
pub fn build_spa(
root: &Path,
target_dir: &Path,
app: &str,
base_path: Option<&str>,
release: bool,
) -> Result<PathBuf> {
if !dx_installed() {
bail!("`{app}` is a Dioxus app, but `dx` was not found; {INSTALL_HINT}");
}
let mut command = Command::new("dx");
command
.args(["build", "--platform", "web", "--package", app])
.current_dir(root);
if let Some(base_path) = base_path {
command.args(["--base-path", base_path.trim_start_matches('/')]);
}
if release {
command.arg("--release");
}
let status = command
.status()
.with_context(|| format!("failed to run `dx build` for {app}"))?;
if !status.success() {
bail!("`dx build` failed for {app}");
}
let profile = if release { "release" } else { "debug" };
let public = target_dir
.join("dx")
.join(app)
.join(profile)
.join("web")
.join("public");
if !public.join("index.html").is_file() {
bail!(
"`dx build` finished but {} has no index.html",
public.display()
);
}
Ok(public)
}