use clap::{CommandFactory, Parser, Subcommand};
use clap_complete::shells::Shell;
#[cfg(feature = "version")]
use shadow_rs::shadow;
#[cfg(feature = "version")]
shadow!(build);
#[derive(Parser, Clone, Debug)]
#[cfg_attr(
feature = "version",
command(version = format!(
"{} ({} {}), {}",
build::PKG_VERSION,
build::SHORT_COMMIT,
build::BUILD_TARGET,
build::RUST_VERSION
))
)]
#[cfg_attr(not(feature = "version"), command(version))]
#[command(
name = "s7cmd",
about = "Reliable, flexible, and fast command-line tool for Amazon S3",
arg_required_else_help = true,
// clap 4.6 has no per-subcommand help_heading in derive, so the grouped
// listing below is static. The order/names must match the `Cmd` enum
// variants — `tests/cli_help.rs::top_level_help_*` exercise the basics,
// but adding/renaming a subcommand requires a manual edit here.
help_template = "\
{about-with-newline}
{usage-heading} {usage}
Object Operations:
ls List S3 objects
cp Copy objects from/to S3
mv Move objects from/to S3 (copy then delete source)
rm Delete a single S3 object
sync Synchronize files between local and S3 (or S3 to S3)
clean Bulk-delete S3 objects
Object Metadata:
head-object Head an S3 object
get-object-tagging Get an S3 object's tagging
put-object-tagging Put tagging on an S3 object
delete-object-tagging Delete tagging from an S3 object
Bucket Operations:
create-bucket Create an S3 bucket
delete-bucket Delete an S3 bucket
head-bucket Head an S3 bucket
Bucket Tagging:
get-bucket-tagging Get a bucket's tagging
put-bucket-tagging Put tagging on a bucket
delete-bucket-tagging Delete tagging from a bucket
Bucket Policy:
get-bucket-policy Get a bucket's policy
put-bucket-policy Put a bucket policy
delete-bucket-policy Delete a bucket's policy
Bucket Versioning:
get-bucket-versioning Get a bucket's versioning configuration
put-bucket-versioning Put a bucket versioning configuration
Bucket Lifecycle:
get-bucket-lifecycle-configuration Get a bucket's lifecycle configuration
put-bucket-lifecycle-configuration Put a bucket lifecycle configuration
delete-bucket-lifecycle-configuration Delete a bucket's lifecycle configuration
Bucket Encryption:
get-bucket-encryption Get a bucket's encryption configuration
put-bucket-encryption Put a bucket encryption configuration
delete-bucket-encryption Delete a bucket's encryption configuration
Bucket CORS:
get-bucket-cors Get a bucket's CORS configuration
put-bucket-cors Put a bucket CORS configuration
delete-bucket-cors Delete a bucket's CORS configuration
Bucket Public Access Block:
get-public-access-block Get a bucket's public access block configuration
put-public-access-block Put a bucket public access block configuration
delete-public-access-block Delete a bucket's public access block configuration
Bucket Website:
get-bucket-website Get a bucket's website configuration
put-bucket-website Put a bucket website configuration
delete-bucket-website Delete a bucket's website configuration
Bucket Logging:
get-bucket-logging Get a bucket's logging configuration
put-bucket-logging Put a bucket logging configuration
Bucket Notification:
get-bucket-notification-configuration Get a bucket's notification configuration
put-bucket-notification-configuration Put a bucket notification configuration
Other:
help Print this message or the help of the given subcommand(s)
Options:
{options}{after-help}",
)]
pub struct Cli {
#[arg(long, value_enum, value_name = "SHELL", global = false)]
pub auto_complete_shell: Option<Shell>,
#[command(subcommand)]
pub command: Option<Cmd>,
}
#[derive(Subcommand, Clone, Debug)]
pub enum Cmd {
Ls(Box<s3ls_rs::CLIArgs>),
Cp(s3util_rs::config::args::CpArgs),
Mv(s3util_rs::config::args::MvArgs),
Rm(s3util_rs::config::args::RmArgs),
Sync(Box<s3sync::CLIArgs>),
Clean(Box<s3rm_rs::CLIArgs>),
HeadObject(s3util_rs::config::args::HeadObjectArgs),
GetObjectTagging(s3util_rs::config::args::GetObjectTaggingArgs),
PutObjectTagging(s3util_rs::config::args::PutObjectTaggingArgs),
DeleteObjectTagging(s3util_rs::config::args::DeleteObjectTaggingArgs),
CreateBucket(s3util_rs::config::args::CreateBucketArgs),
DeleteBucket(s3util_rs::config::args::DeleteBucketArgs),
HeadBucket(s3util_rs::config::args::HeadBucketArgs),
GetBucketTagging(s3util_rs::config::args::GetBucketTaggingArgs),
PutBucketTagging(s3util_rs::config::args::PutBucketTaggingArgs),
DeleteBucketTagging(s3util_rs::config::args::DeleteBucketTaggingArgs),
GetBucketPolicy(s3util_rs::config::args::GetBucketPolicyArgs),
PutBucketPolicy(s3util_rs::config::args::PutBucketPolicyArgs),
DeleteBucketPolicy(s3util_rs::config::args::DeleteBucketPolicyArgs),
GetBucketVersioning(s3util_rs::config::args::GetBucketVersioningArgs),
PutBucketVersioning(s3util_rs::config::args::PutBucketVersioningArgs),
GetBucketLifecycleConfiguration(s3util_rs::config::args::GetBucketLifecycleConfigurationArgs),
PutBucketLifecycleConfiguration(s3util_rs::config::args::PutBucketLifecycleConfigurationArgs),
DeleteBucketLifecycleConfiguration(
s3util_rs::config::args::DeleteBucketLifecycleConfigurationArgs,
),
GetBucketEncryption(s3util_rs::config::args::GetBucketEncryptionArgs),
PutBucketEncryption(s3util_rs::config::args::PutBucketEncryptionArgs),
DeleteBucketEncryption(s3util_rs::config::args::DeleteBucketEncryptionArgs),
GetBucketCors(s3util_rs::config::args::GetBucketCorsArgs),
PutBucketCors(s3util_rs::config::args::PutBucketCorsArgs),
DeleteBucketCors(s3util_rs::config::args::DeleteBucketCorsArgs),
GetPublicAccessBlock(s3util_rs::config::args::GetPublicAccessBlockArgs),
PutPublicAccessBlock(s3util_rs::config::args::PutPublicAccessBlockArgs),
DeletePublicAccessBlock(s3util_rs::config::args::DeletePublicAccessBlockArgs),
GetBucketWebsite(s3util_rs::config::args::GetBucketWebsiteArgs),
PutBucketWebsite(s3util_rs::config::args::PutBucketWebsiteArgs),
DeleteBucketWebsite(s3util_rs::config::args::DeleteBucketWebsiteArgs),
GetBucketLogging(s3util_rs::config::args::GetBucketLoggingArgs),
PutBucketLogging(s3util_rs::config::args::PutBucketLoggingArgs),
GetBucketNotificationConfiguration(
s3util_rs::config::args::GetBucketNotificationConfigurationArgs,
),
PutBucketNotificationConfiguration(
s3util_rs::config::args::PutBucketNotificationConfigurationArgs,
),
}
#[allow(dead_code)] pub fn cli_command() -> clap::Command {
let mut cmd = Cli::command();
let names: Vec<String> = cmd
.get_subcommands()
.map(|s| s.get_name().to_string())
.collect();
for name in names {
cmd = cmd.mut_subcommand(name, |sub| {
let has_flag = sub
.get_arguments()
.any(|a| a.get_id().as_str() == "auto_complete_shell");
if has_flag {
sub.mut_arg("auto_complete_shell", |a| {
a.hide(true).long(None::<&'static str>)
})
} else {
sub
}
});
}
cmd
}