diff --git a/Cargo.lock b/Cargo.lock index 7a835bb..16956fe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -73,7 +73,7 @@ version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e231f6134f61b71076a3eab506c379d4f36122f2af15a9ff04415ea4c3339e2" dependencies = [ - "windows-sys 0.60.2", + "windows-sys", ] [[package]] @@ -84,7 +84,7 @@ checksum = "3e0633414522a32ffaac8ac6cc8f748e090c5717661fddeea04219e2344f5f2a" dependencies = [ "anstyle", "once_cell_polyfill", - "windows-sys 0.60.2", + "windows-sys", ] [[package]] @@ -201,9 +201,9 @@ dependencies = [ [[package]] name = "clap_complete" -version = "4.5.61" +version = "4.5.62" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39615915e2ece2550c0149addac32fb5bd312c657f43845bb9088cb9c8a7c992" +checksum = "004eef6b14ce34759aa7de4aea3217e368f463f46a3ed3764ca4b5a4404003b4" dependencies = [ "clap", ] @@ -364,7 +364,7 @@ dependencies = [ "cfg-if", "libc", "socket2", - "windows-sys 0.60.2", + "windows-sys", ] [[package]] @@ -395,7 +395,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.59.0", + "windows-sys", ] [[package]] @@ -413,7 +413,7 @@ dependencies = [ "cfg-if", "libc", "libredox", - "windows-sys 0.60.2", + "windows-sys", ] [[package]] @@ -480,9 +480,9 @@ dependencies = [ [[package]] name = "generic-array" -version = "0.14.9" +version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bb6743198531e02858aeaea5398fcc883e71851fcbcb5a2f773e2fb6cb1edf2" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", @@ -597,24 +597,24 @@ checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" [[package]] name = "jiff" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be1f93b8b1eb69c77f24bbb0afdf66f54b632ee39af40ca21c4365a1d7347e49" +checksum = "49cce2b81f2098e7e3efc35bc2e0a6b7abec9d34128283d7a26fa8f32a6dbb35" dependencies = [ "jiff-static", "jiff-tzdb-platform", "log", "portable-atomic", "portable-atomic-util", - "serde", - "windows-sys 0.59.0", + "serde_core", + "windows-sys 0.61.2", ] [[package]] name = "jiff-static" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03343451ff899767262ec32146f6d559dd759fdadf42ff0e227c7c48f72594b4" +checksum = "980af8b43c3ad5d8d349ace167ec8170839f753a42d233ba19e08afe1850fa69" dependencies = [ "proc-macro2", "quote", @@ -702,9 +702,9 @@ checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" [[package]] name = "lzma-rust2" -version = "0.13.0" +version = "0.15.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c60a23ffb90d527e23192f1246b14746e2f7f071cb84476dd879071696c18a4a" +checksum = "48172246aa7c3ea28e423295dd1ca2589a24617cc4e588bb8cfe177cb2c54d95" dependencies = [ "crc", "sha2", @@ -998,15 +998,15 @@ checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" [[package]] name = "rustix" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" +checksum = "146c9e247ccc180c1f61615433868c99f3de3ae256a30a43b49f67c2d9171f34" dependencies = [ "bitflags", "errno", "libc", "linux-raw-sys", - "windows-sys 0.59.0", + "windows-sys", ] [[package]] @@ -1110,7 +1110,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881" dependencies = [ "libc", - "windows-sys 0.60.2", + "windows-sys", ] [[package]] @@ -1176,15 +1176,15 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.23.0" +version = "3.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16" +checksum = "655da9c7eb6305c55742045d5a8d2037996d61d8de95806335c7c86ce0f82e9c" dependencies = [ "fastrand", "getrandom", "once_cell", "rustix", - "windows-sys 0.59.0", + "windows-sys", ] [[package]] @@ -1194,7 +1194,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60b8cb979cb11c32ce1603f8137b22262a9d131aaa5c37b5678025f22b8becd0" dependencies = [ "rustix", - "windows-sys 0.60.2", + "windows-sys", ] [[package]] @@ -1335,6 +1335,7 @@ name = "uu_tar" version = "0.0.1" dependencies = [ "clap", + "jiff", "regex", "tar", "uucore", @@ -1525,38 +1526,13 @@ dependencies = [ "windows-link", ] -[[package]] -name = "windows-sys" -version = "0.59.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" -dependencies = [ - "windows-targets 0.52.6", -] - [[package]] name = "windows-sys" version = "0.60.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" dependencies = [ - "windows-targets 0.53.5", -] - -[[package]] -name = "windows-targets" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" -dependencies = [ - "windows_aarch64_gnullvm 0.52.6", - "windows_aarch64_msvc 0.52.6", - "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm 0.52.6", - "windows_i686_msvc 0.52.6", - "windows_x86_64_gnu 0.52.6", - "windows_x86_64_gnullvm 0.52.6", - "windows_x86_64_msvc 0.52.6", + "windows-targets", ] [[package]] @@ -1566,106 +1542,58 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" dependencies = [ "windows-link", - "windows_aarch64_gnullvm 0.53.1", - "windows_aarch64_msvc 0.53.1", - "windows_i686_gnu 0.53.1", - "windows_i686_gnullvm 0.53.1", - "windows_i686_msvc 0.53.1", - "windows_x86_64_gnu 0.53.1", - "windows_x86_64_gnullvm 0.53.1", - "windows_x86_64_msvc 0.53.1", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", ] -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" - [[package]] name = "windows_aarch64_gnullvm" version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" - [[package]] name = "windows_aarch64_msvc" version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" -[[package]] -name = "windows_i686_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" - [[package]] name = "windows_i686_gnu" version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" -[[package]] -name = "windows_i686_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" - [[package]] name = "windows_i686_gnullvm" version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" -[[package]] -name = "windows_i686_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" - [[package]] name = "windows_i686_msvc" version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" - [[package]] name = "windows_x86_64_gnu" version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" - [[package]] name = "windows_x86_64_gnullvm" version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" - [[package]] name = "windows_x86_64_msvc" version = "0.53.1" @@ -1752,9 +1680,9 @@ dependencies = [ [[package]] name = "zip" -version = "6.0.0" +version = "7.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb2a05c7c36fde6c09b08576c9f7fb4cda705990f73b58fe011abf7dfb24168b" +checksum = "bdd8a47718a4ee5fe78e07667cd36f3de80e7c2bfe727c7074245ffc7303c037" dependencies = [ "aes", "arbitrary", @@ -1763,6 +1691,7 @@ dependencies = [ "crc32fast", "deflate64", "flate2", + "generic-array", "getrandom", "hmac", "indexmap", diff --git a/Cargo.toml b/Cargo.toml index 7651872..9f6dd63 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -50,7 +50,8 @@ tar = "0.4" tempfile = "3.10.1" textwrap = { version = "0.16.1", features = ["terminal_size"] } xattr = "1.3.1" -zip = "6.0" +zip = "7.0" +jiff = "0.2.16" [dependencies] clap = { workspace = true } @@ -63,8 +64,9 @@ uutests = { workspace = true } uucore = { workspace = true } uuhelp_parser = { workspace = true, optional = true } zip = { workspace = true, optional = true } - tar = { optional = true, version = "0.0.1", package = "uu_tar", path = "src/uu/tar" } +jiff = { workspace = true } + [dev-dependencies] chrono = { workspace = true } diff --git a/fuzz/Cargo.lock b/fuzz/Cargo.lock index c6896e1..4ef90d5 100644 --- a/fuzz/Cargo.lock +++ b/fuzz/Cargo.lock @@ -183,9 +183,9 @@ checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" [[package]] name = "console" -version = "0.16.1" +version = "0.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b430743a6eb14e9764d4260d4c0d8123087d504eeb9c48f2b2a5e810dd369df4" +checksum = "03e45a4a8926227e4197636ba97a9fc9b00477e9f4bd711395687c5f0734bec4" dependencies = [ "encode_unicode", "libc", @@ -437,9 +437,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.9.4" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" +checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" [[package]] name = "log" @@ -669,15 +669,15 @@ checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" [[package]] name = "rustix" -version = "1.0.7" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266" +checksum = "146c9e247ccc180c1f61615433868c99f3de3ae256a30a43b49f67c2d9171f34" dependencies = [ "bitflags", "errno", "libc", "linux-raw-sys", - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] @@ -772,15 +772,15 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.23.0" +version = "3.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16" +checksum = "655da9c7eb6305c55742045d5a8d2037996d61d8de95806335c7c86ce0f82e9c" dependencies = [ "fastrand", "getrandom", "once_cell", "rustix", - "windows-sys 0.61.0", + "windows-sys 0.60.2", ] [[package]] diff --git a/src/uu/tar/Cargo.toml b/src/uu/tar/Cargo.toml index d6ed134..ebb06ab 100644 --- a/src/uu/tar/Cargo.toml +++ b/src/uu/tar/Cargo.toml @@ -17,6 +17,7 @@ uucore = { workspace = true } clap = { workspace = true } regex = { workspace = true } tar = { workspace = true } +jiff = { workspace = true } [lib] path = "src/tar.rs" diff --git a/src/uu/tar/src/operations/create.rs b/src/uu/tar/src/operations/create.rs index 4b296f8..d8caa27 100644 --- a/src/uu/tar/src/operations/create.rs +++ b/src/uu/tar/src/operations/create.rs @@ -4,12 +4,29 @@ // file that was distributed with this source code. use crate::errors::TarError; +use crate::operations::TarOperation; +use crate::options::{TarOption, TarParams}; use std::collections::VecDeque; use std::fs::{self, File}; use std::path::{self, Path, PathBuf}; use tar::Builder; use uucore::error::UResult; +pub struct Create; + +impl TarOperation for Create { + fn exec(&self, options: &TarParams) -> UResult<()> { + create_archive( + options.archive(), + options.files().as_slice(), + options + .options() + .iter() + .any(|x| matches!(x, TarOption::Verbose)), + ) + } +} + /// Create a tar archive from the specified files /// /// # Arguments @@ -24,7 +41,7 @@ use uucore::error::UResult; /// - The archive file cannot be created /// - Any input file cannot be read /// - Files cannot be added due to I/O or permission errors -pub fn create_archive(archive_path: &Path, files: &[&Path], verbose: bool) -> UResult<()> { +pub fn create_archive(archive_path: &Path, files: &[PathBuf], verbose: bool) -> UResult<()> { // Create the output file let file = File::create(archive_path).map_err(|e| { TarError::TarOperationError(format!( @@ -37,12 +54,8 @@ pub fn create_archive(archive_path: &Path, files: &[&Path], verbose: bool) -> UR // Create Builder instance let mut builder = Builder::new(file); - if verbose { - println!("Creating archive: {}", archive_path.display()); - } - // Add each file or directory to the archive - for &path in files { + for path in files { // Check if path exists if !path.exists() { return Err(TarError::FileNotFound(path.display().to_string()).into()); diff --git a/src/uu/tar/src/operations/extract.rs b/src/uu/tar/src/operations/extract.rs index 2668009..c283d93 100644 --- a/src/uu/tar/src/operations/extract.rs +++ b/src/uu/tar/src/operations/extract.rs @@ -4,11 +4,27 @@ // file that was distributed with this source code. use crate::errors::TarError; +use crate::operations::operation::TarOperation; +use crate::options::options::{TarOption, TarParams}; use std::fs::File; use std::path::Path; use tar::Archive; use uucore::error::UResult; +pub(crate) struct Extract; + +impl TarOperation for Extract { + fn exec(&self, options: &TarParams) -> UResult<()> { + extract_archive( + options.archive(), + options + .options() + .iter() + .any(|x| matches!(x, TarOption::Verbose)), + ) + } +} + /// Extract files from a tar archive /// /// # Arguments diff --git a/src/uu/tar/src/operations/mod.rs b/src/uu/tar/src/operations/mod.rs index b11efb7..911ab1f 100644 --- a/src/uu/tar/src/operations/mod.rs +++ b/src/uu/tar/src/operations/mod.rs @@ -5,3 +5,9 @@ pub mod create; pub mod extract; +pub mod operation; + +pub(crate) use self::create::Create; +pub(crate) use self::extract::Extract; +pub(crate) use self::operation::OperationKind; +pub use self::operation::TarOperation; diff --git a/src/uu/tar/src/operations/operation.rs b/src/uu/tar/src/operations/operation.rs new file mode 100644 index 0000000..e66042e --- /dev/null +++ b/src/uu/tar/src/operations/operation.rs @@ -0,0 +1,58 @@ +use crate::errors::TarError; +use crate::operations::Create; +use crate::operations::Extract; +use crate::options::TarParams; +use uucore::error::UResult; + +/// The [`OperationKind`] Enum representation of Acdtrux arguments which is +/// later leveraged as selector for enum dispatch by the [`TarOperation`] +/// trait +pub enum OperationKind { + Concatenate, + Create, + Diff, + List, + Append, + Update, + Extract, +} + +impl TryFrom<&str> for OperationKind { + type Error = TarError; + fn try_from(value: &str) -> Result { + match value { + "concate" => Ok(Self::Concatenate), + "create" => Ok(Self::Create), + "diff" => Ok(Self::Diff), + "list" => Ok(Self::List), + "append" => Ok(Self::Append), + "update" => Ok(Self::Update), + "extract" => Ok(Self::Extract), + _ => Err(TarError::TarOperationError(format!( + "Invalid operation selected: {}", + value + ))), + } + } +} + +impl TarOperation for OperationKind { + fn exec(&self, options: &TarParams) -> UResult<()> { + match self { + Self::List => unimplemented!(), + Self::Create => Create.exec(options), + Self::Diff => unimplemented!(), + Self::Append => unimplemented!(), + Self::Update => unimplemented!(), + Self::Extract => Extract.exec(options), + Self::Concatenate => unimplemented!(), + } + } +} + +/// [`TarOperation`] allows enum dispatch by enforcing the impl of the +/// trait to create the functionality to perform the operation requested via +/// the command line arg for this execution of tar +pub trait TarOperation { + fn exec(&self, options: &TarParams) -> UResult<()>; +} diff --git a/src/uu/tar/src/options/mod.rs b/src/uu/tar/src/options/mod.rs new file mode 100644 index 0000000..af8caf6 --- /dev/null +++ b/src/uu/tar/src/options/mod.rs @@ -0,0 +1,6 @@ +// re-exported to remove the redundant level of inception in +// the module tree +#[allow(clippy::module_inception)] +pub mod options; +pub use crate::options::options::TarOption; +pub use crate::options::options::TarParams; diff --git a/src/uu/tar/src/options/options.rs b/src/uu/tar/src/options/options.rs new file mode 100644 index 0000000..8f4ab59 --- /dev/null +++ b/src/uu/tar/src/options/options.rs @@ -0,0 +1,92 @@ +use crate::errors::TarError; +use crate::operations::OperationKind; +use clap::ArgMatches; +use std::path::PathBuf; +use uucore::error::UResult; + +/// [`TarParams`] Holds common information that is parsed from +/// command line arguments. That changes the current execution of +/// tar. +#[allow(dead_code)] +#[derive(Default)] +pub struct TarParams { + archive: PathBuf, + files: Vec, + options: Vec, +} + +impl From<&ArgMatches> for TarParams { + fn from(matches: &ArgMatches) -> TarParams { + let mut ops = Self::default(); + + // -v --verbose + if matches.get_flag("verbose") { + ops.options_mut().push(TarOption::Verbose); + } + + // [FILES]... + if let Some(files) = matches.get_many::("files") { + ops.files = files.map(|x| x.to_owned()).collect(); + } + + // -f --file + if let Some(a) = matches.get_one::("file") { + ops.archive = a.to_owned(); + } + + ops + } +} + +impl TarParams { + /// Convence method that parses the [`ArgMatches`] + /// processed by clap into [`TarParams`] and selects + /// the appropriate [`OperationKind`] for execution given back to the caller in a + /// tuple of ([`OperationKind`], [`TarParams`]) + pub fn with_operation(matches: &ArgMatches) -> UResult<(OperationKind, Self)> { + if matches.get_flag("create") { + Ok((OperationKind::Create, Self::from(matches))) + } else if matches.get_flag("extract") { + Ok((OperationKind::Extract, Self::from(matches))) + } else { + // TODO: update messaging + Err(Box::new(TarError::TarOperationError( + "Error processing: Operations".to_string(), + ))) + } + } +} + +#[allow(dead_code)] +impl TarParams { + pub fn files(&self) -> &Vec { + &self.files + } + pub fn files_mut(&mut self) -> &mut Vec { + &mut self.files + } + pub fn archive(&self) -> &PathBuf { + &self.archive + } + pub fn archive_mut(&mut self) -> &mut PathBuf { + &mut self.archive + } + pub fn options(&self) -> &Vec { + &self.options + } + pub fn options_mut(&mut self) -> &mut Vec { + &mut self.options + } +} + +/// [`TarOption`] Enum of avaliable tar options for later use +/// by [`TarOperation`] impls, eg. List, Create, Delete +#[allow(dead_code)] +pub enum TarOption { + AbsoluteNames, + ACLs, + AfterDate, + Anchored, + AtimePreserve { arg: String }, + Verbose, +} diff --git a/src/uu/tar/src/tar.rs b/src/uu/tar/src/tar.rs index 4db1bd5..b7d14bc 100644 --- a/src/uu/tar/src/tar.rs +++ b/src/uu/tar/src/tar.rs @@ -5,9 +5,12 @@ pub mod errors; mod operations; +mod options; use clap::{arg, crate_version, ArgAction, Command}; -use std::path::{Path, PathBuf}; +use operations::operation::TarOperation; +use options::TarParams; +use std::path::PathBuf; use uucore::error::UResult; use uucore::format_usage; @@ -33,43 +36,9 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { let matches = uu_app().try_get_matches_from(args_to_parse)?; - let verbose = matches.get_flag("verbose"); + let (op, options) = TarParams::with_operation(&matches)?; - // Handle extract operation - if matches.get_flag("extract") { - let archive_path = matches.get_one::("file").ok_or_else(|| { - uucore::error::USimpleError::new(1, "option requires an argument -- 'f'") - })?; - - return operations::extract::extract_archive(archive_path, verbose); - } - - // Handle create operation - if matches.get_flag("create") { - let archive_path = matches.get_one::("file").ok_or_else(|| { - uucore::error::USimpleError::new(1, "option requires an argument -- 'f'") - })?; - - let files: Vec<&Path> = matches - .get_many::("files") - .map(|v| v.map(|p| p.as_path()).collect()) - .unwrap_or_default(); - - if files.is_empty() { - return Err(uucore::error::USimpleError::new( - 1, - "Cowardly refusing to create an empty archive", - )); - } - - return operations::create::create_archive(archive_path, &files, verbose); - } - - // If no operation specified, show error - Err(uucore::error::USimpleError::new( - 1, - "You must specify one of the '-c' or '-x' options", - )) + op.exec(&options) } #[allow(clippy::cognitive_complexity)]