mirror of
https://github.com/uutils/tar.git
synced 2026-06-10 16:14:35 -07:00
tar: add -t/--list operation
Implement the list operation. Non-verbose (-t) prints one entry path per line. Verbose (-tv) prints permissions, owner/group, size, modification time, and path — matching GNU tar's ls-l style output. Adds conflict group so -c, -x, and -t are mutually exclusive. Pulls in chrono for timestamp formatting in verbose output. chrono is already in the workspace dependency set and will also be needed for date parsing when --newer=DATE is implemented. Point uucore/uutests at the coreutils git repo while we're iterating quickly on basic functionality.
This commit is contained in:
committed by
Daniel Hofstetter
parent
f85dddd20e
commit
06042058f9
Generated
+54
-106
@@ -73,7 +73,7 @@ version = "1.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9e231f6134f61b71076a3eab506c379d4f36122f2af15a9ff04415ea4c3339e2"
|
||||
dependencies = [
|
||||
"windows-sys",
|
||||
"windows-sys 0.60.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -84,7 +84,7 @@ checksum = "3e0633414522a32ffaac8ac6cc8f748e090c5717661fddeea04219e2344f5f2a"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"once_cell_polyfill",
|
||||
"windows-sys",
|
||||
"windows-sys 0.60.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -161,7 +161,7 @@ checksum = "6f8d983286843e49675a4b7a2d174efe136dc93a18d69130dd18198a6c167601"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cpufeatures 0.3.0",
|
||||
"rand_core 0.10.0",
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -287,16 +287,6 @@ dependencies = [
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ctor"
|
||||
version = "0.6.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "424e0138278faeb2b401f174ad17e715c829512d74f3d1e81eb43365c2e0590e"
|
||||
dependencies = [
|
||||
"ctor-proc-macro",
|
||||
"dtor 0.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ctor"
|
||||
version = "0.8.0"
|
||||
@@ -304,7 +294,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "352d39c2f7bef1d6ad73db6f5160efcaed66d94ef8c6c573a8410c00bf909a98"
|
||||
dependencies = [
|
||||
"ctor-proc-macro",
|
||||
"dtor 0.3.0",
|
||||
"dtor",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -365,16 +355,7 @@ dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"socket2",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dtor"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e58a0764cddb55ab28955347b45be00ade43d4d6f3ba4bf3dc354e4ec9432934"
|
||||
dependencies = [
|
||||
"dtor-proc-macro",
|
||||
"windows-sys 0.60.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -392,6 +373,12 @@ version = "0.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f678cf4a922c215c63e0de95eb1ff08a958a81d47e485cf9da1e27bf6305cfa5"
|
||||
|
||||
[[package]]
|
||||
name = "dunce"
|
||||
version = "1.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813"
|
||||
|
||||
[[package]]
|
||||
name = "equivalent"
|
||||
version = "1.0.2"
|
||||
@@ -405,7 +392,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys",
|
||||
"windows-sys 0.60.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -423,7 +410,7 @@ dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"libredox",
|
||||
"windows-sys",
|
||||
"windows-sys 0.60.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -526,7 +513,7 @@ dependencies = [
|
||||
"js-sys",
|
||||
"libc",
|
||||
"r-efi",
|
||||
"rand_core 0.10.0",
|
||||
"rand_core",
|
||||
"wasip2",
|
||||
"wasip3",
|
||||
"wasm-bindgen",
|
||||
@@ -662,7 +649,7 @@ dependencies = [
|
||||
"portable-atomic",
|
||||
"portable-atomic-util",
|
||||
"serde_core",
|
||||
"windows-sys",
|
||||
"windows-sys 0.60.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -788,9 +775,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nix"
|
||||
version = "0.30.1"
|
||||
version = "0.31.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6"
|
||||
checksum = "5d6d0705320c1e6ba1d912b5e37cf18071b6c2e9b7fa8215a1e8a7651966f5d3"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cfg-if",
|
||||
@@ -925,15 +912,6 @@ version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "efca4c95a19a79d1c98f791f10aebd5c1363b473244630bb7dbde1dc98455a24"
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9"
|
||||
dependencies = [
|
||||
"zerocopy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pretty_assertions"
|
||||
version = "1.4.1"
|
||||
@@ -978,16 +956,6 @@ version = "5.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.9.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1"
|
||||
dependencies = [
|
||||
"rand_chacha",
|
||||
"rand_core 0.9.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.10.0"
|
||||
@@ -996,26 +964,7 @@ checksum = "bc266eb313df6c5c09c1c7b1fbe2510961e5bcd3add930c1e31f7ed9da0feff8"
|
||||
dependencies = [
|
||||
"chacha20",
|
||||
"getrandom 0.4.1",
|
||||
"rand_core 0.10.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
|
||||
dependencies = [
|
||||
"ppv-lite86",
|
||||
"rand_core 0.9.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.9.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38"
|
||||
dependencies = [
|
||||
"getrandom 0.3.4",
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1093,7 +1042,7 @@ dependencies = [
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
"windows-sys",
|
||||
"windows-sys 0.60.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1216,7 +1165,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys",
|
||||
"windows-sys 0.60.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1261,12 +1210,12 @@ dependencies = [
|
||||
"clap",
|
||||
"clap_complete",
|
||||
"clap_mangen",
|
||||
"ctor 0.8.0",
|
||||
"ctor",
|
||||
"libc",
|
||||
"phf",
|
||||
"phf_codegen",
|
||||
"pretty_assertions",
|
||||
"rand 0.10.0",
|
||||
"rand",
|
||||
"regex",
|
||||
"rlimit",
|
||||
"tar",
|
||||
@@ -1289,7 +1238,7 @@ dependencies = [
|
||||
"getrandom 0.4.1",
|
||||
"once_cell",
|
||||
"rustix",
|
||||
"windows-sys",
|
||||
"windows-sys 0.60.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1299,7 +1248,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "60b8cb979cb11c32ce1603f8137b22262a9d131aaa5c37b5678025f22b8becd0"
|
||||
dependencies = [
|
||||
"rustix",
|
||||
"windows-sys",
|
||||
"windows-sys 0.60.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1452,6 +1401,7 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
|
||||
name = "uu_tar"
|
||||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"clap",
|
||||
"regex",
|
||||
"tar",
|
||||
@@ -1460,12 +1410,12 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "uucore"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a8038531f506a34ab4612b93f97d5f40759768cd34a83fd2af041b84fcbde474"
|
||||
version = "0.8.0"
|
||||
source = "git+https://github.com/uutils/coreutils#f6451c7d20bc65640e92ecdc368470577d7c9e2e"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"dns-lookup",
|
||||
"dunce",
|
||||
"fluent",
|
||||
"fluent-bundle",
|
||||
"fluent-syntax",
|
||||
@@ -1479,13 +1429,14 @@ dependencies = [
|
||||
"unic-langid",
|
||||
"uucore_procs",
|
||||
"wild",
|
||||
"winapi-util",
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "uucore_procs"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0f63e2d5083ff0983193a33e2d57fd271c7e3e3e7df8e46e8f471865647b2cbc"
|
||||
version = "0.8.0"
|
||||
source = "git+https://github.com/uutils/coreutils#f6451c7d20bc65640e92ecdc368470577d7c9e2e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -1493,15 +1444,14 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "uutests"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "25b8a1598ddd20230a5df59d642e2e5741b0b90038bde8684c984515f947fda5"
|
||||
version = "0.8.0"
|
||||
source = "git+https://github.com/uutils/coreutils#f6451c7d20bc65640e92ecdc368470577d7c9e2e"
|
||||
dependencies = [
|
||||
"ctor 0.6.3",
|
||||
"ctor",
|
||||
"libc",
|
||||
"nix",
|
||||
"pretty_assertions",
|
||||
"rand 0.9.2",
|
||||
"rand",
|
||||
"regex",
|
||||
"rlimit",
|
||||
"tempfile",
|
||||
@@ -1621,6 +1571,15 @@ dependencies = [
|
||||
"glob",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-util"
|
||||
version = "0.1.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22"
|
||||
dependencies = [
|
||||
"windows-sys 0.60.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-core"
|
||||
version = "0.62.2"
|
||||
@@ -1689,6 +1648,15 @@ dependencies = [
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.61.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc"
|
||||
dependencies = [
|
||||
"windows-link",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.53.5"
|
||||
@@ -1864,26 +1832,6 @@ version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049"
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy"
|
||||
version = "0.8.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0894878a5fa3edfd6da3f88c4805f4c8558e2b996227a3d864f47fe11e38282c"
|
||||
dependencies = [
|
||||
"zerocopy-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy-derive"
|
||||
version = "0.8.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerofrom"
|
||||
version = "0.1.6"
|
||||
|
||||
+2
-2
@@ -43,8 +43,8 @@ phf = "0.13.0"
|
||||
phf_codegen = "0.13.0"
|
||||
rand = { version = "0.10.0" }
|
||||
regex = "1.10.4"
|
||||
uucore = "0.7.0"
|
||||
uutests = "0.7.0"
|
||||
uucore = { git = "https://github.com/uutils/coreutils" }
|
||||
uutests = { git = "https://github.com/uutils/coreutils" }
|
||||
tar = "0.4"
|
||||
tempfile = "3.10.1"
|
||||
textwrap = { version = "0.16.1", features = ["terminal_size"] }
|
||||
|
||||
@@ -13,10 +13,11 @@ categories = ["command-line-utilities"]
|
||||
|
||||
|
||||
[dependencies]
|
||||
uucore = { workspace = true }
|
||||
uucore = { workspace = true, features = ["fs"] }
|
||||
clap = { workspace = true }
|
||||
regex = { workspace = true }
|
||||
tar = { workspace = true }
|
||||
chrono = { workspace = true }
|
||||
|
||||
[lib]
|
||||
path = "src/tar.rs"
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
// This file is part of the uutils tar package.
|
||||
//
|
||||
// For the full copyright and license information, please view the LICENSE
|
||||
// file that was distributed with this source code.
|
||||
|
||||
use crate::errors::TarError;
|
||||
use chrono::{TimeZone, Utc};
|
||||
use std::fs::File;
|
||||
use std::path::Path;
|
||||
use tar::Archive;
|
||||
use uucore::error::UResult;
|
||||
use uucore::fs::display_permissions_unix;
|
||||
|
||||
/// List the contents of a tar archive, printing one entry per line.
|
||||
pub fn list_archive(archive_path: &Path, verbose: bool) -> UResult<()> {
|
||||
let file: File =
|
||||
File::open(archive_path).map_err(|e| TarError::from_io_error(e, archive_path))?;
|
||||
let mut archive = Archive::new(file);
|
||||
|
||||
for entry_result in archive
|
||||
.entries()
|
||||
.map_err(|e| TarError::InvalidArchive(format!("Failed to read archive entries: {e}")))?
|
||||
{
|
||||
let entry = entry_result
|
||||
.map_err(|e| TarError::InvalidArchive(format!("Failed to read entry: {e}")))?;
|
||||
|
||||
if verbose {
|
||||
// Collect all header fields into owned values before borrowing entry for the path,
|
||||
// since both header() and path() require a borrow of entry.
|
||||
let (mode, entry_type, owner, group, size, mtime) = {
|
||||
let header = entry.header();
|
||||
(
|
||||
header.mode().unwrap_or(0),
|
||||
header.entry_type(),
|
||||
header
|
||||
.username()
|
||||
.ok()
|
||||
.flatten()
|
||||
.unwrap_or_default()
|
||||
.to_owned(),
|
||||
header
|
||||
.groupname()
|
||||
.ok()
|
||||
.flatten()
|
||||
.unwrap_or_default()
|
||||
.to_owned(),
|
||||
header.size().unwrap_or(0),
|
||||
header.mtime().unwrap_or(0),
|
||||
)
|
||||
};
|
||||
|
||||
let path = entry
|
||||
.path()
|
||||
.map_err(|e| TarError::InvalidArchive(format!("Failed to read entry path: {e}")))?;
|
||||
|
||||
let type_char = match entry_type {
|
||||
tar::EntryType::Directory => 'd',
|
||||
tar::EntryType::Symlink => 'l',
|
||||
tar::EntryType::Char => 'c',
|
||||
tar::EntryType::Block => 'b',
|
||||
tar::EntryType::Fifo => 'p',
|
||||
_ => '-',
|
||||
};
|
||||
// Tar headers store the type separately from the mode bits, so we get the
|
||||
// 9-character rwx string from uucore and prepend our own type character.
|
||||
let perm_str = display_permissions_unix(mode, false);
|
||||
let permissions = format!("{type_char}{perm_str}");
|
||||
|
||||
// TODO: GNU tar displays mtime in the user's local timezone; we
|
||||
// currently format in UTC. Convert to local time for compatibility.
|
||||
let dt: chrono::DateTime<Utc> = Utc
|
||||
.timestamp_opt(mtime as i64, 0)
|
||||
.single()
|
||||
.unwrap_or_else(Utc::now);
|
||||
let date_str = dt.format("%Y-%m-%d %H:%M");
|
||||
|
||||
println!(
|
||||
"{permissions} {owner}/{group} {size:>8} {date_str} {}",
|
||||
path.display()
|
||||
);
|
||||
} else {
|
||||
let path = entry
|
||||
.path()
|
||||
.map_err(|e| TarError::InvalidArchive(format!("Failed to read entry path: {e}")))?;
|
||||
|
||||
println!("{}", path.display());
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -5,3 +5,4 @@
|
||||
|
||||
pub mod create;
|
||||
pub mod extract;
|
||||
pub mod list;
|
||||
|
||||
+14
-5
@@ -12,7 +12,7 @@ use uucore::error::UResult;
|
||||
use uucore::format_usage;
|
||||
|
||||
const ABOUT: &str = "an archiving utility";
|
||||
const USAGE: &str = "tar key [FILE...]\n tar {-c|-x} [-v] -f ARCHIVE [FILE...]";
|
||||
const USAGE: &str = "tar key [FILE...]\n tar {-c|-t|-x} [-v] -f ARCHIVE [FILE...]";
|
||||
|
||||
/// Determines whether a string looks like a POSIX tar keystring.
|
||||
///
|
||||
@@ -162,10 +162,19 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||
return operations::create::create_archive(archive_path, &files, verbose);
|
||||
}
|
||||
|
||||
// Handle list operation
|
||||
if matches.get_flag("list") {
|
||||
let archive_path = matches.get_one::<PathBuf>("file").ok_or_else(|| {
|
||||
uucore::error::USimpleError::new(64, "option requires an argument -- 'f'")
|
||||
})?;
|
||||
|
||||
return operations::list::list_archive(archive_path, verbose);
|
||||
}
|
||||
|
||||
// If no operation specified, show error
|
||||
Err(uucore::error::USimpleError::new(
|
||||
2,
|
||||
"You must specify one of the '-c' or '-x' options",
|
||||
"You must specify one of the '-c', '-x', or '-t' options",
|
||||
))
|
||||
}
|
||||
|
||||
@@ -179,14 +188,14 @@ pub fn uu_app() -> Command {
|
||||
.disable_help_flag(true)
|
||||
.args([
|
||||
// Main operation modes
|
||||
arg!(-c --create "Create a new archive").conflicts_with("extract"),
|
||||
arg!(-c --create "Create a new archive").conflicts_with_all(["extract", "list"]),
|
||||
// arg!(-d --diff "Find differences between archive and file system").alias("compare"),
|
||||
// arg!(-r --append "Append files to end of archive"),
|
||||
// arg!(-t --list "List contents of archive"),
|
||||
arg!(-t --list "List contents of archive").conflicts_with_all(["create", "extract"]),
|
||||
// arg!(-u --update "Only append files newer than copy in archive"),
|
||||
arg!(-x --extract "Extract files from archive")
|
||||
.alias("get")
|
||||
.conflicts_with("create"),
|
||||
.conflicts_with_all(["create", "list"]),
|
||||
// Archive file
|
||||
arg!(-f --file <ARCHIVE> "Use archive file or device ARCHIVE")
|
||||
.value_parser(clap::value_parser!(PathBuf)),
|
||||
|
||||
@@ -657,3 +657,98 @@ fn test_posix_b_matches_dash_prefix_failure() {
|
||||
.code_is(64)
|
||||
.stderr_contains("unexpected argument '-b'");
|
||||
}
|
||||
|
||||
// List operation tests
|
||||
|
||||
#[test]
|
||||
fn test_list_single_file() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
at.write("file.txt", "test content");
|
||||
ucmd.args(&["-cf", "archive.tar", "file.txt"]).succeeds();
|
||||
|
||||
new_ucmd!()
|
||||
.args(&["-tf", "archive.tar"])
|
||||
.current_dir(at.as_string())
|
||||
.succeeds()
|
||||
.stdout_contains("file.txt");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_list_multiple_files() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
at.write("file1.txt", "content1");
|
||||
at.write("file2.txt", "content2");
|
||||
at.write("file3.txt", "content3");
|
||||
|
||||
ucmd.args(&["-cf", "archive.tar", "file1.txt", "file2.txt", "file3.txt"])
|
||||
.succeeds();
|
||||
|
||||
new_ucmd!()
|
||||
.args(&["-tf", "archive.tar"])
|
||||
.current_dir(at.as_string())
|
||||
.succeeds()
|
||||
.stdout_contains("file1.txt")
|
||||
.stdout_contains("file2.txt")
|
||||
.stdout_contains("file3.txt");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_list_directory() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
at.mkdir("testdir");
|
||||
at.write("testdir/file1.txt", "content1");
|
||||
at.mkdir("testdir/subdir");
|
||||
at.write("testdir/subdir/file2.txt", "content2");
|
||||
|
||||
ucmd.args(&["-cf", "archive.tar", "testdir"]).succeeds();
|
||||
|
||||
new_ucmd!()
|
||||
.args(&["-tf", "archive.tar"])
|
||||
.current_dir(at.as_string())
|
||||
.succeeds()
|
||||
.stdout_contains("testdir")
|
||||
.stdout_contains("testdir/file1.txt")
|
||||
.stdout_contains("testdir/subdir")
|
||||
.stdout_contains("testdir/subdir/file2.txt");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_list_verbose() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
at.write("file.txt", "content");
|
||||
ucmd.args(&["-cf", "archive.tar", "file.txt"]).succeeds();
|
||||
|
||||
new_ucmd!()
|
||||
.args(&["-tvf", "archive.tar"])
|
||||
.current_dir(at.as_string())
|
||||
.succeeds()
|
||||
.stdout_contains("file.txt")
|
||||
.stdout_contains("7 "); // verbose output includes file size; absent from plain -t listing
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_list_nonexistent_archive() {
|
||||
new_ucmd!()
|
||||
.args(&["-tf", "nonexistent.tar"])
|
||||
.fails()
|
||||
.code_is(2)
|
||||
.stderr_contains("nonexistent.tar");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_list_conflicts_with_create() {
|
||||
new_ucmd!()
|
||||
.args(&["-ctf", "archive.tar", "file.txt"])
|
||||
.fails()
|
||||
.code_is(2)
|
||||
.stderr_contains("cannot be used with");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_list_conflicts_with_extract() {
|
||||
new_ucmd!()
|
||||
.args(&["-xtf", "archive.tar"])
|
||||
.fails()
|
||||
.code_is(2)
|
||||
.stderr_contains("cannot be used with");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user