diff --git a/build.rs b/build.rs index 3266995..0d99eb1 100644 --- a/build.rs +++ b/build.rs @@ -1,22 +1,55 @@ use clap::{CommandFactory, ValueEnum}; use clap_complete::{Shell, generate_to}; -use std::{env, io::Error}; +use std::{env, ffi::OsString, fs, io::Error, path::PathBuf}; include!("src/cli/mod.rs"); -fn main() -> Result<(), Error> { - let outdir = env::var_os("SHELL_COMPLETIONS_DIR").or_else(|| env::var_os("OUT_DIR")); +fn shell_name(shell: Shell) -> String { + shell + .to_possible_value() + .map(|v| v.get_name().to_owned()) + .unwrap_or_default() +} - let Some(outdir) = outdir else { - return Ok(()); - }; +fn non_empty(name: &str) -> Option { + env::var_os(name).filter(|v| !v.is_empty()) +} + +fn install_dir(shell: Shell) -> Option<(PathBuf, bool)> { + let per_shell = format!("SHELL_COMPLETIONS_DIR_{}", shell_name(shell).to_uppercase()); + + if let Some(dir) = non_empty(&per_shell).or_else(|| non_empty("SHELL_COMPLETIONS_DIR")) { + return Some((PathBuf::from(dir), true)); + } + non_empty("OUT_DIR").map(|dir| (PathBuf::from(dir), false)) +} + +fn main() -> Result<(), Error> { + println!("cargo::rerun-if-env-changed=SHELL_COMPLETIONS_DIR"); + for shell in Shell::value_variants() { + println!( + "cargo::rerun-if-env-changed=SHELL_COMPLETIONS_DIR_{}", + shell_name(*shell).to_uppercase() + ); + } let mut cmd = ahab::Ahab::command(); for shell in Shell::value_variants() { - let path = generate_to(*shell, &mut cmd, env!("CARGO_PKG_NAME"), &outdir)?; + let Some((dir, requested)) = install_dir(*shell) else { + continue; + }; - println!("cargo:warning=completion file is generated: {path:?}"); + fs::create_dir_all(&dir)?; + let path = generate_to(*shell, &mut cmd, env!("CARGO_PKG_NAME"), &dir)?; + + if requested { + println!( + "cargo::warning=installed {} completion: {}", + shell_name(*shell), + path.display() + ); + } } Ok(())