docusaurus 0.0.0-alpha.0

Drop-in Docusaurus CLI with Rust-native config (docusaurus.config.rs)
Documentation
use std::path::PathBuf;
use std::process;

use clap::{Parser, Subcommand};
use docusaurus::{run_command, RunnerOptions};

#[derive(Parser)]
#[command(name = "docusaurus", about = "Docusaurus CLI with Rust-native config")]
struct Cli {
    #[command(subcommand)]
    command: Commands,
}

#[derive(Subcommand)]
enum Commands {
    Build {
        #[arg(default_value = ".")]
        site_dir: PathBuf,
        #[arg(long)]
        out_dir: Option<String>,
        #[arg(long, num_args = 1..)]
        locale: Vec<String>,
        #[arg(long)]
        dev: bool,
        #[arg(long)]
        bundle_analyzer: bool,
        #[arg(long = "no-minify")]
        no_minify: bool,
    },
    Start {
        #[arg(default_value = ".")]
        site_dir: PathBuf,
        #[arg(long)]
        port: Option<u16>,
        #[arg(long)]
        host: Option<String>,
        #[arg(long)]
        hot_only: bool,
        #[arg(long = "no-open")]
        no_open: bool,
    },
    Serve {
        #[arg(default_value = ".")]
        site_dir: PathBuf,
        #[arg(long)]
        port: Option<u16>,
        #[arg(long)]
        host: Option<String>,
        #[arg(long)]
        dir: Option<String>,
        #[arg(long)]
        build: bool,
        #[arg(long = "no-open")]
        no_open: bool,
    },
    Deploy {
        #[arg(default_value = ".")]
        site_dir: PathBuf,
    },
    Clear {
        #[arg(default_value = ".")]
        site_dir: PathBuf,
    },
    Swizzle {
        #[arg(default_value = ".")]
        site_dir: PathBuf,
        theme: Option<String>,
        component: Option<String>,
        #[arg(long)]
        eject: bool,
        #[arg(long)]
        wrap: bool,
        #[arg(long)]
        danger: bool,
        #[arg(long)]
        list: bool,
        #[arg(long)]
        typescript: bool,
    },
    WriteTranslations {
        #[arg(default_value = ".")]
        site_dir: PathBuf,
        #[arg(long)]
        locale: Option<String>,
    },
    WriteHeadingIds {
        #[arg(default_value = ".")]
        site_dir: PathBuf,
        content_paths: Vec<PathBuf>,
        #[arg(long)]
        maintain_case: bool,
        #[arg(long)]
        overwrite: bool,
    },
}

fn main() {
    let cli = Cli::parse();

    let result = dispatch(cli);
    if let Err(e) = result {
        eprintln!("error: {e}");
        process::exit(1);
    }
}

fn dispatch(cli: Cli) -> Result<(), docusaurus::DocusaurusError> {
    match cli.command {
        Commands::Build {
            site_dir,
            out_dir,
            locale,
            dev,
            bundle_analyzer,
            no_minify,
        } => {
            let cli_options = serde_json::json!({
                "outDir": out_dir,
                "locale": if locale.is_empty() { None } else { Some(locale) },
                "dev": dev,
                "bundleAnalyzer": bundle_analyzer,
                "minify": !no_minify,
            });
            run_command(
                "build",
                RunnerOptions {
                    site_dir,
                    cli_options,
                },
            )
        }
        Commands::Start {
            site_dir,
            port,
            host,
            hot_only,
            no_open,
        } => {
            let cli_options = serde_json::json!({
                "port": port,
                "host": host,
                "hotOnly": hot_only,
                "open": !no_open,
            });
            run_command(
                "start",
                RunnerOptions {
                    site_dir,
                    cli_options,
                },
            )
        }
        Commands::Serve {
            site_dir,
            port,
            host,
            dir,
            build,
            no_open,
        } => {
            let cli_options = serde_json::json!({
                "port": port,
                "host": host,
                "dir": dir,
                "build": build,
                "open": !no_open,
            });
            run_command(
                "serve",
                RunnerOptions {
                    site_dir,
                    cli_options,
                },
            )
        }
        Commands::Deploy { site_dir } => run_command(
            "deploy",
            RunnerOptions {
                site_dir,
                cli_options: serde_json::json!({}),
            },
        ),
        Commands::Clear { site_dir } => run_command(
            "clear",
            RunnerOptions {
                site_dir,
                cli_options: serde_json::json!({}),
            },
        ),
        Commands::Swizzle {
            site_dir,
            theme,
            component,
            eject,
            wrap,
            danger,
            list,
            typescript,
        } => {
            let cli_options = serde_json::json!({
                "theme": theme,
                "component": component,
                "eject": eject,
                "wrap": wrap,
                "danger": danger,
                "list": list,
                "typescript": typescript,
            });
            run_command(
                "swizzle",
                RunnerOptions {
                    site_dir,
                    cli_options,
                },
            )
        }
        Commands::WriteTranslations { site_dir, locale } => {
            let cli_options = serde_json::json!({ "locale": locale });
            run_command(
                "writeTranslations",
                RunnerOptions {
                    site_dir,
                    cli_options,
                },
            )
        }
        Commands::WriteHeadingIds {
            site_dir,
            content_paths,
            maintain_case,
            overwrite,
        } => {
            let paths: Vec<String> = content_paths
                .iter()
                .map(|p| p.display().to_string())
                .collect();
            let cli_options = serde_json::json!({
                "contentPaths": paths,
                "maintainCase": maintain_case,
                "overwrite": overwrite,
            });
            run_command(
                "writeHeadingIds",
                RunnerOptions {
                    site_dir,
                    cli_options,
                },
            )
        }
    }
}