use anyhow::Result;
use clap::CommandFactory;
use tracing::info;
use s3util_rs::config::ClientConfig;
use s3util_rs::config::args::put_bucket_versioning::PutBucketVersioningArgs;
use s3util_rs::storage::s3::api;
pub async fn run_put_bucket_versioning(
args: PutBucketVersioningArgs,
client_config: ClientConfig,
) -> Result<()> {
let bucket = args
.bucket_name()
.map_err(|e| anyhow::anyhow!("{}", e.trim_end()))?;
let status = args.versioning_status();
let client = client_config.create_client().await;
if args.dry_run {
info!(bucket = %bucket, status = %status.as_str(), "[dry-run] would put bucket versioning.");
return Ok(());
}
api::put_bucket_versioning(&client, &bucket, status.clone()).await?;
info!(bucket = %bucket, status = %status.as_str(), "Bucket versioning set.");
Ok(())
}
pub fn check_state_flag(args: &PutBucketVersioningArgs) -> Result<(), clap::Error> {
if !args.enabled && !args.suspended {
let mut cmd = PutBucketVersioningArgs::command();
return Err(cmd.error(
clap::error::ErrorKind::MissingRequiredArgument,
"one of --enabled or --suspended must be specified",
));
}
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
use clap::Parser;
fn parse(argv: &[&str]) -> PutBucketVersioningArgs {
PutBucketVersioningArgs::try_parse_from(argv).expect("args should parse")
}
#[test]
fn check_state_flag_rejects_neither_flag() {
let args = parse(&["put-bucket-versioning", "s3://b"]);
let err = check_state_flag(&args).expect_err("neither flag must be rejected");
assert_eq!(err.kind(), clap::error::ErrorKind::MissingRequiredArgument);
assert!(
err.to_string()
.contains("one of --enabled or --suspended must be specified")
);
}
#[test]
fn check_state_flag_accepts_enabled() {
let args = parse(&["put-bucket-versioning", "s3://b", "--enabled"]);
assert!(check_state_flag(&args).is_ok());
}
#[test]
fn check_state_flag_accepts_suspended() {
let args = parse(&["put-bucket-versioning", "s3://b", "--suspended"]);
assert!(check_state_flag(&args).is_ok());
}
}