agama/rust/xtask/src/main.rs
Imobach González Sosa 534a7d15dd
Automatic clippy fixes
2026-02-24 06:48:30 +00:00

111 lines
3.6 KiB
Rust

use std::{env, path::PathBuf};
mod tasks {
use std::{fs::File, io::Write, path::Path};
use agama_cli::Cli;
use agama_server::web::docs::{
ApiDocBuilder, ConfigApiDocBuilder, MiscApiDocBuilder, ProfileApiDocBuilder,
};
use clap::CommandFactory;
use clap_complete::aot;
use clap_markdown::MarkdownOptions;
use crate::create_output_dir;
/// Generate auto-completion snippets for common shells.
pub fn generate_completions() -> std::io::Result<()> {
let out_dir = create_output_dir("shell")?;
let mut cmd = Cli::command();
clap_complete::generate_to(aot::Bash, &mut cmd, "agama", &out_dir)?;
clap_complete::generate_to(aot::Fish, &mut cmd, "agama", &out_dir)?;
clap_complete::generate_to(aot::Zsh, &mut cmd, "agama", &out_dir)?;
println!("Generate shell completions at {}.", out_dir.display());
Ok(())
}
const GENERATED: &str =
"---\nNOTE: This documentation is generated. Run `cargo xtask markdown` to update it.\n";
/// Generate Agama's CLI documentation in markdown format.
pub fn generate_markdown() -> std::io::Result<()> {
let out_dir = create_output_dir("markdown")?;
let options = MarkdownOptions::new()
.title("Command-line reference".to_string())
.show_footer(false);
let markdown = clap_markdown::help_markdown_custom::<Cli>(&options);
let filename = out_dir.join("agama.md");
let mut file = File::create(&filename)?;
file.write_all(markdown.as_bytes())?;
file.write_all(GENERATED.as_bytes())?;
println!("Generate Markdown documentation at {}.", filename.display());
Ok(())
}
/// Generate Agama's CLI man pages.
pub fn generate_manpages() -> std::io::Result<()> {
let out_dir = create_output_dir("man")?;
let cmd = Cli::command();
clap_mangen::generate_to(cmd, &out_dir)?;
println!("Generate manpages documentation at {}.", out_dir.display());
Ok(())
}
/// Generate Agama's OpenAPI specification.
pub fn generate_openapi() -> std::io::Result<()> {
let out_dir = create_output_dir("openapi")?;
write_openapi(ConfigApiDocBuilder {}, out_dir.join("config.json"))?;
write_openapi(MiscApiDocBuilder {}, out_dir.join("misc.json"))?;
write_openapi(ProfileApiDocBuilder {}, out_dir.join("profile.json"))?;
println!(
"Generate the OpenAPI specification at {}.",
out_dir.display()
);
Ok(())
}
fn write_openapi<T, P: AsRef<Path>>(builder: T, path: P) -> std::io::Result<()>
where
T: ApiDocBuilder,
{
let openapi = builder.build().to_pretty_json()?;
let mut file = File::create(path)?;
file.write_all(openapi.as_bytes())?;
Ok(())
}
}
fn create_output_dir(name: &str) -> std::io::Result<PathBuf> {
let out_dir = std::env::var_os("OUT_DIR")
.map(PathBuf::from)
.unwrap_or(PathBuf::from("out"))
.join(name);
std::fs::create_dir_all(&out_dir)?;
Ok(out_dir)
}
fn main() -> std::io::Result<()> {
let Some(task) = env::args().nth(1) else {
eprintln!("You must specify a xtask");
std::process::exit(1);
};
match task.as_str() {
"completions" => tasks::generate_completions(),
"markdown" => tasks::generate_markdown(),
"manpages" => tasks::generate_manpages(),
"openapi" => tasks::generate_openapi(),
other => {
eprintln!("Unknown task '{}'", other);
std::process::exit(1);
}
}
}