this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at tangled-ci 145 lines 4.6 kB view raw
1pub mod backends; 2mod job; 3pub mod progress; 4#[cfg(test)] 5pub mod test_utils; 6pub mod utils; 7 8use backends::*; 9use clap::{CommandFactory, Parser, Subcommand}; 10use clap_complete::Shell; 11use job::{Action, get_job}; 12use utils::*; 13 14/// A compression multi-tool 15#[derive(Parser, Debug)] 16#[command(author, version, about, long_about = None)] 17struct CmprssArgs { 18 /// Format 19 #[command(subcommand)] 20 format: Option<Format>, 21 22 // Base arguments for the non-subcommand behavior 23 #[clap(flatten)] 24 pub base_args: CommonArgs, 25} 26 27#[derive(Subcommand, Debug)] 28enum Format { 29 /// tar archive format 30 Tar(TarArgs), 31 32 /// gzip compression 33 #[clap(visible_alias = "gz")] 34 Gzip(GzipArgs), 35 36 /// xz compression 37 Xz(XzArgs), 38 39 /// bzip2 compression 40 #[clap(visible_alias = "bz2")] 41 Bzip2(Bzip2Args), 42 43 /// zip archive format 44 Zip(ZipArgs), 45 46 /// zstd compression 47 #[clap(visible_alias = "zst")] 48 Zstd(ZstdArgs), 49 50 /// lz4 compression 51 Lz4(Lz4Args), 52 53 /// brotli compression 54 #[clap(visible_alias = "br")] 55 Brotli(BrotliArgs), 56 57 /// snappy framed compression 58 #[clap(visible_alias = "sz")] 59 Snappy(SnappyArgs), 60 61 /// lzma (legacy LZMA1) compression 62 Lzma(LzmaArgs), 63 64 /// 7-Zip archive format 65 #[clap(name = "7z", visible_alias = "sevenz")] 66 SevenZ(SevenZArgs), 67 68 /// Print a shell completion script to stdout. 69 #[clap(hide = true)] 70 Completions { 71 /// Shell to generate completions for. 72 #[arg(value_enum)] 73 shell: Shell, 74 }, 75 76 /// Print the cmprss(1) man page (in troff format) to stdout. 77 #[clap(hide = true)] 78 Manpage, 79} 80 81/// If the first positional arg looks like a dotted format string (e.g. 82/// `tar.gz`, `tgz`) and isn't an existing path on disk, remove it from 83/// `io_list` and return the equivalent compressor chain. This gives the 84/// compound formats the same ergonomic treatment as the `tar` subcommand 85/// without cluttering `--help` with every permutation. 86fn take_format_prefix(io_list: &mut Vec<String>) -> Option<Box<dyn Compressor>> { 87 let first = io_list.first()?; 88 if std::path::Path::new(first).exists() { 89 return None; 90 } 91 let chain = chain_from_format_str(first)?; 92 let format = first.clone(); 93 io_list.remove(0); 94 Some(Box::new(Pipeline::with_format(chain, format))) 95} 96 97fn write_completions(shell: Shell) -> Result { 98 let mut cmd = CmprssArgs::command(); 99 clap_complete::generate(shell, &mut cmd, "cmprss", &mut std::io::stdout()); 100 Ok(()) 101} 102 103fn write_manpage() -> Result { 104 let cmd = CmprssArgs::command(); 105 clap_mangen::Man::new(cmd).render(&mut std::io::stdout())?; 106 Ok(()) 107} 108 109fn command(compressor: Option<Box<dyn Compressor>>, args: &CommonArgs) -> Result { 110 let job = get_job(compressor, args)?; 111 match job.action { 112 Action::Compress => job.compressor.compress(job.input, job.output), 113 Action::Extract => job.compressor.extract(job.input, job.output), 114 Action::List => job.compressor.list(job.input), 115 Action::Append => job.compressor.append(job.input, job.output), 116 } 117} 118 119fn main() { 120 let args = CmprssArgs::parse(); 121 match args.format { 122 Some(Format::Tar(a)) => command(Some(Box::new(Tar::new(&a))), &a.common_args), 123 Some(Format::Gzip(a)) => command(Some(Box::new(Gzip::new(&a))), &a.common_args), 124 Some(Format::Xz(a)) => command(Some(Box::new(Xz::new(&a))), &a.common_args), 125 Some(Format::Bzip2(a)) => command(Some(Box::new(Bzip2::new(&a))), &a.common_args), 126 Some(Format::Zip(a)) => command(Some(Box::new(Zip::new(&a))), &a.common_args), 127 Some(Format::Zstd(a)) => command(Some(Box::new(Zstd::new(&a))), &a.common_args), 128 Some(Format::Lz4(a)) => command(Some(Box::new(Lz4::new(&a))), &a.common_args), 129 Some(Format::Brotli(a)) => command(Some(Box::new(Brotli::new(&a))), &a.common_args), 130 Some(Format::Snappy(a)) => command(Some(Box::new(Snappy::new(&a))), &a.common_args), 131 Some(Format::Lzma(a)) => command(Some(Box::new(Lzma::new(&a))), &a.common_args), 132 Some(Format::SevenZ(a)) => command(Some(Box::new(SevenZ::new(&a))), &a.common_args), 133 Some(Format::Completions { shell }) => write_completions(shell), 134 Some(Format::Manpage) => write_manpage(), 135 None => { 136 let mut base_args = args.base_args; 137 let compressor = take_format_prefix(&mut base_args.io_list); 138 command(compressor, &base_args) 139 } 140 } 141 .unwrap_or_else(|e| { 142 eprintln!("ERROR(cmprss): {}", e); 143 std::process::exit(1); 144 }); 145}