use clap::{Parser, Subcommand};
#[derive(Subcommand)]
pub enum Action {
Sync {
#[command(flatten)]
args: SyncArgs,
},
Completions {
#[arg(short, long, default_value = "bash", value_parser=clap::builder::PossibleValuesParser::new(["bash", "zsh", "fish", "pwsh", "powershell"]))]
shell: String,
},
PurgeUrl {
#[arg(name = "url")]
url: String,
#[arg(short, long)]
api_key: Option<String>,
},
PurgeZone {
#[arg(name = "pullzone")]
pullzone: u64,
#[arg(short, long)]
api_key: Option<String>,
#[arg(short, long)]
cache_tag: Option<String>,
},
}
#[derive(Parser)]
#[command(name = "thumper")]
#[command(arg_required_else_help = true)]
#[command(about = "Sync your files to bunny cdn storage zone")]
#[command(version = env!("CARGO_PKG_VERSION"))]
#[command(
long_about = "thumper is a tool for synchronizing files to bunny cdn storage zones
thumper can sync to subtrees of your storage zone, the entire storage zone, or selectively skip
parts of the tree. It can easily deploy a static site with a single command.
thumper refuses to sync if it looks like there's already an active sync job to the storage
zone. It places a lockfile into the storage zone during the sync to have rudimentary concurrency
control.
thumper aims to make the local_path and the path within the storage zone exactly equal. It will sync
HTML at the end, to ensure other assets like CSS are already updated by the time they sync."
)]
pub struct Cli {
#[command(subcommand)]
pub command: Action,
}
#[derive(Parser)]
pub struct SyncArgs {
#[arg(short, long, default_value = "storage.bunnycdn.com")]
pub endpoint: String,
#[arg(short, long)]
pub access_key: Option<String>,
#[arg(name = "local_path", required = true, num_args = 1)]
pub local_path: String,
#[arg(name = "storage_zone", required = true, num_args = 1)]
pub storage_zone: String,
#[arg(short, long, default_value = "/")]
pub path: String,
#[arg(long, default_value_t = false)]
pub dry_run: bool,
#[arg(short, long, default_value_t = false)]
pub force: bool,
#[arg(long, default_value = ".thumper.lock")]
pub lockfile: String,
#[arg(short, long)]
pub ignore: Vec<String>,
#[arg(short, long, default_value_t = false)]
pub verbose: bool,
#[arg(short, long)]
pub concurrency: Option<usize>,
}
#[cfg(test)]
mod tests {
use crate::cli::Cli;
use clap::CommandFactory;
use std::fs;
#[test]
fn render_help() {
let mut cli = Cli::command();
let help = cli.render_help().to_string();
fs::write("docs/src/help", help).unwrap();
}
#[test]
fn render_sync_help() {
let mut cli = Cli::command();
for subcommand in cli.get_subcommands_mut() {
if subcommand.get_name() == "sync" {
let help = subcommand
.render_help()
.to_string()
.replacen("sync", "thumper sync", 1);
fs::write("docs/src/synchelp", help).unwrap();
}
}
}
}