use std::env;
use std::fs;
use std::path::PathBuf;
use clap::{CommandFactory, Parser, ValueEnum};
#[derive(Parser)]
#[command(name = "nrs")]
#[command(
author,
version,
about = "Fast interactive TUI for running npm scripts"
)]
#[command(
long_about = "nrs is a fast, interactive terminal user interface (TUI) for discovering \
and executing npm/yarn/pnpm/bun scripts defined in package.json files.\n\n\
Run without arguments to launch the interactive TUI. Use arrow keys to navigate, \
Enter to run a script, or press 1-9 for quick selection."
)]
struct Cli {
#[arg(value_name = "PATH")]
path: Option<PathBuf>,
#[arg(short = 'L', long = "last")]
last: bool,
#[arg(short, long)]
list: bool,
#[arg(short, long, value_name = "PATTERN")]
exclude: Vec<String>,
#[arg(short, long, value_name = "MODE", value_enum)]
sort: Option<SortMode>,
#[arg(short, long, value_name = "RUNNER", value_enum)]
runner: Option<Runner>,
#[arg(short, long, value_name = "ARGS", allow_hyphen_values = true)]
args: Option<String>,
#[arg(short = 'n', long = "script", value_name = "NAME")]
script: Option<String>,
#[arg(short, long)]
dry_run: bool,
#[arg(short, long, value_name = "PATH")]
config: Option<PathBuf>,
#[arg(long)]
no_config: bool,
#[arg(long)]
debug: bool,
#[arg(long, value_name = "SHELL", value_enum)]
completions: Option<Shell>,
}
#[derive(Clone, Copy, ValueEnum)]
enum SortMode {
Recent,
Alpha,
Category,
}
#[derive(Clone, Copy, ValueEnum)]
enum Runner {
Npm,
Yarn,
Pnpm,
Bun,
}
#[derive(Clone, Copy, ValueEnum)]
enum Shell {
Bash,
Zsh,
Fish,
Powershell,
Elvish,
}
fn main() {
let profile = env::var("PROFILE").unwrap_or_default();
if profile != "release" && env::var("NRS_GEN_MANPAGE").is_err() {
return;
}
let out_dir = match env::var_os("OUT_DIR") {
Some(dir) => PathBuf::from(dir),
None => return,
};
let cmd = Cli::command();
let man = clap_mangen::Man::new(cmd);
let mut buffer = Vec::new();
man.render(&mut buffer)
.expect("Failed to generate man page");
let man_path = out_dir.join("nrs.1");
fs::write(&man_path, buffer).expect("Failed to write man page");
let docs_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap()).join("docs");
if docs_dir.exists() {
let _ = fs::copy(&man_path, docs_dir.join("nrs.1"));
}
println!("cargo:rerun-if-changed=build.rs");
}