fn main() {
println!("cargo:rerun-if-changed=src/");
println!("cargo:rerun-if-changed=static/css/input.css");
println!("cargo:rerun-if-changed=tailwind.config.js");
println!("cargo:rerun-if-env-changed=PATH");
#[cfg(target_os = "windows")]
println!("cargo:rerun-if-env-changed=PATHEXT");
let tailwind = find_tailwind_cli();
match &tailwind {
Some(path) => println!("cargo:rerun-if-changed={}", path.display()),
None => {
if let Some(expected) = expected_tailwind_path() {
println!("cargo:rerun-if-changed={}", expected.display());
}
}
}
let Some(tailwind) = tailwind else {
println!(
"cargo:warning=Tailwind CSS CLI not found — CSS will not be compiled. \
Run `autumn setup` or install tailwindcss manually."
);
return;
};
let status = std::process::Command::new(&tailwind)
.args([
"-i",
"static/css/input.css",
"-o",
"static/css/app.css",
"--content",
"src/**/*.rs",
"--minify",
])
.status()
.expect("Failed to run Tailwind CLI");
assert!(status.success(), "Tailwind CSS compilation failed");
}
fn find_tailwind_cli() -> Option<std::path::PathBuf> {
for target_dir in candidate_target_dirs() {
let local = target_dir.join("autumn").join(tailwind_bin_name());
if local.exists() {
return Some(local);
}
}
which("tailwindcss")
}
fn expected_tailwind_path() -> Option<std::path::PathBuf> {
Some(
candidate_target_dirs()
.into_iter()
.next()?
.join("autumn")
.join(tailwind_bin_name()),
)
}
fn tailwind_bin_name() -> &'static str {
if cfg!(windows) {
"tailwindcss.exe"
} else {
"tailwindcss"
}
}
fn candidate_target_dirs() -> Vec<std::path::PathBuf> {
let mut candidates = Vec::new();
if let Ok(dir) = std::env::var("CARGO_TARGET_DIR") {
let dir = std::path::PathBuf::from(dir);
if dir.is_absolute() {
candidates.push(dir);
}
}
if let Ok(out_dir) = std::env::var("OUT_DIR") {
let out_dir = std::path::PathBuf::from(out_dir);
candidates.extend(
[out_dir.ancestors().nth(4), out_dir.ancestors().nth(5)]
.into_iter()
.flatten()
.map(std::path::Path::to_path_buf),
);
}
candidates
}
fn which(binary: &str) -> Option<std::path::PathBuf> {
let path_var = std::env::var_os("PATH")?;
for dir in std::env::split_paths(&path_var) {
let candidate = dir.join(binary);
if candidate.exists() {
return Some(candidate);
}
#[cfg(target_os = "windows")]
{
let candidate_exe = dir.join(format!("{binary}.exe"));
if candidate_exe.exists() {
return Some(candidate_exe);
}
}
}
None
}