use std::path::PathBuf;
use clap::{Parser, Subcommand};
#[derive(Debug, Parser)]
#[command(
name = "bookyard",
version,
about = "Build and edit a local bookshelf for multiple mdBook projects."
)]
pub struct Cli {
#[command(subcommand)]
command: Command,
}
#[derive(Debug, Subcommand)]
pub enum Command {
#[command(about = "Create a bookyard.toml shelf config in the current directory.")]
Init {
#[arg(long, default_value = "Bookyard", help = "Shelf title written to bookyard.toml.")]
title: String,
#[arg(long, help = "Replace an existing bookyard.toml.")]
force: bool,
},
#[command(about = "Add an existing mdBook to the shelf.")]
Add {
#[arg(help = "Path to an existing mdBook directory.")]
source: PathBuf,
#[arg(long, help = "Logical folder path inside the shelf.")]
folder: String,
#[arg(long, help = "Book title stored in the shelf config.")]
title: Option<String>,
#[arg(long, help = "Stable book id used in generated URLs.")]
id: Option<String>,
#[arg(long = "tag", help = "Tag to attach to the book; repeat for multiple tags.")]
tags: Vec<String>,
},
#[command(about = "Create a new mdBook and add it to the shelf.")]
New {
#[arg(help = "Path where the new mdBook will be created.")]
source: PathBuf,
#[arg(long, help = "Logical folder path inside the shelf.")]
folder: String,
#[arg(long, help = "Book title for book.toml and the shelf config.")]
title: Option<String>,
#[arg(long, help = "Stable book id used in generated URLs.")]
id: Option<String>,
#[arg(long = "tag", help = "Tag to attach to the book; repeat for multiple tags.")]
tags: Vec<String>,
#[arg(long, help = "Replace generated files if they already exist.")]
force: bool,
},
#[command(about = "Build the bookshelf site.")]
Build {
#[arg(long, hide = true, help = "Skip mdBook builds and only render the shelf.")]
no_mdbook: bool,
},
#[command(about = "Serve the generated shelf, optionally with the local editor.")]
Serve {
#[arg(long, default_value = "127.0.0.1", help = "Host interface to bind.")]
host: String,
#[arg(long, default_value_t = 3000, help = "Port to listen on.")]
port: u16,
#[arg(long, help = "Enable the local config editor at /__bookyard/edit.")]
edit: bool,
},
#[command(about = "Check the local Bookyard configuration.")]
Doctor,
}
pub async fn run() -> anyhow::Result<()> {
match Cli::parse().command {
Command::Init { title, force } => crate::commands::init::run(&title, force),
Command::Add {
source,
folder,
title,
id,
tags,
} => crate::commands::add::run(source, folder, title, id, tags),
Command::New {
source,
folder,
title,
id,
tags,
force,
} => crate::commands::new::run(source, folder, title, id, tags, force),
Command::Build { no_mdbook } => crate::commands::build::run(no_mdbook),
Command::Serve { host, port, edit } => crate::commands::serve::run(host, port, edit).await,
Command::Doctor => crate::commands::doctor::run(),
}
}