mirror of
https://github.com/uutils/tar.git
synced 2026-06-10 16:14:35 -07:00
Add output of files to be included to archive if verbose flag passed (#62)
* Add output of files to be included to archive if verbose flag passed * Add test for verbose output * Fix test * Fix style
This commit is contained in:
@@ -4,8 +4,9 @@
|
||||
// file that was distributed with this source code.
|
||||
|
||||
use crate::errors::TarError;
|
||||
use std::fs::File;
|
||||
use std::path::Path;
|
||||
use std::collections::VecDeque;
|
||||
use std::fs::{self, File};
|
||||
use std::path::{self, Path, PathBuf};
|
||||
use tar::Builder;
|
||||
use uucore::error::UResult;
|
||||
|
||||
@@ -42,15 +43,27 @@ pub fn create_archive(archive_path: &Path, files: &[&Path], verbose: bool) -> UR
|
||||
|
||||
// Add each file or directory to the archive
|
||||
for &path in files {
|
||||
if verbose {
|
||||
println!("{}", path.display());
|
||||
}
|
||||
|
||||
// Check if path exists
|
||||
if !path.exists() {
|
||||
return Err(TarError::FileNotFound(path.display().to_string()).into());
|
||||
}
|
||||
|
||||
if verbose {
|
||||
let to_print = get_tree(path)?
|
||||
.iter()
|
||||
.map(|p| (p.is_dir(), p.display().to_string()))
|
||||
.map(|(is_dir, path)| {
|
||||
if is_dir {
|
||||
format!("{}{}", path, path::MAIN_SEPARATOR)
|
||||
} else {
|
||||
path
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n");
|
||||
println!("{to_print}");
|
||||
}
|
||||
|
||||
// If it's a directory, recursively add all contents
|
||||
if path.is_dir() {
|
||||
builder.append_dir_all(path, path).map_err(|e| {
|
||||
@@ -79,3 +92,21 @@ pub fn create_archive(archive_path: &Path, files: &[&Path], verbose: bool) -> UR
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn get_tree(path: &Path) -> Result<Vec<PathBuf>, std::io::Error> {
|
||||
let mut paths = Vec::new();
|
||||
let mut stack = VecDeque::new();
|
||||
stack.push_back(path.to_path_buf());
|
||||
|
||||
while let Some(current) = stack.pop_back() {
|
||||
paths.push(current.clone());
|
||||
if current.is_dir() {
|
||||
for entry in fs::read_dir(current)? {
|
||||
let child = entry?.path();
|
||||
stack.push_back(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(paths)
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
// For the full copyright and license information, please view the LICENSE
|
||||
// file that was distributed with this source code.
|
||||
|
||||
use std::path;
|
||||
|
||||
use uutests::{at_and_ucmd, new_ucmd};
|
||||
|
||||
// Basic CLI Tests
|
||||
@@ -30,6 +32,29 @@ fn test_version() {
|
||||
.stdout_contains("tar");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_verbose() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
|
||||
let separator = path::MAIN_SEPARATOR;
|
||||
let dir1_path = "dir1";
|
||||
let dir2_path = format!("{dir1_path}{separator}dir2");
|
||||
let file1_path = format!("{dir1_path}{separator}file1.txt");
|
||||
let file2_path = format!("{dir2_path}{separator}file2.txt");
|
||||
|
||||
at.mkdir(dir1_path);
|
||||
at.mkdir(&dir2_path);
|
||||
at.write(&file1_path, "test content 1");
|
||||
at.write(&file2_path, "test content 2");
|
||||
|
||||
ucmd.args(&["-cvf", "archive.tar", dir1_path])
|
||||
.succeeds()
|
||||
.stdout_contains(dir1_path)
|
||||
.stdout_contains(dir2_path)
|
||||
.stdout_contains(file1_path)
|
||||
.stdout_contains(file2_path);
|
||||
}
|
||||
|
||||
// Create operation tests
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user