Output format added + verbose
This commit is contained in:
parent
7e0efdb5b7
commit
f37acd3b9b
|
@ -1,18 +0,0 @@
|
||||||
pub enum ErrorLevel {
|
|
||||||
Log,
|
|
||||||
Notice,
|
|
||||||
Warning,
|
|
||||||
Error,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn log(message: &str, code: i32, level: ErrorLevel, verbose: u8) {
|
|
||||||
if verbose == 0 {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
match level {
|
|
||||||
ErrorLevel::Error => panic!("[ERROR] {} (Code: {})", message, code),
|
|
||||||
ErrorLevel::Warning => eprintln!("[WARNING] {} (Code: {})", message, code),
|
|
||||||
ErrorLevel::Notice => eprintln!("[NOTICE] {}", message),
|
|
||||||
_ => println!("{}", message)
|
|
||||||
};
|
|
||||||
}
|
|
175
src/main.rs
175
src/main.rs
|
@ -1,9 +1,10 @@
|
||||||
use crate::options::{CommandLineArgs, OverwritePolicy};
|
use crate::options::{CommandLineArgs, OutputFormat, OverwritePolicy};
|
||||||
use crate::scan_files::{get_file_mime_type, scan_files};
|
use crate::scan_files::{get_file_mime_type, scan_files};
|
||||||
use caesium::compress_in_memory;
|
|
||||||
use caesium::parameters::CSParameters;
|
use caesium::parameters::CSParameters;
|
||||||
|
use caesium::{compress_in_memory, compress_to_size_in_memory, convert_in_memory, SupportedFileTypes};
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use filetime::{set_file_times, FileTime};
|
use filetime::{set_file_times, FileTime};
|
||||||
|
use human_bytes::human_bytes;
|
||||||
use indicatif::{ParallelProgressIterator, ProgressBar, ProgressDrawTarget, ProgressStyle};
|
use indicatif::{ParallelProgressIterator, ProgressBar, ProgressDrawTarget, ProgressStyle};
|
||||||
use rayon::iter::IntoParallelRefIterator;
|
use rayon::iter::IntoParallelRefIterator;
|
||||||
use rayon::iter::ParallelIterator;
|
use rayon::iter::ParallelIterator;
|
||||||
|
@ -11,15 +12,15 @@ use std::error::Error;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{BufReader, Read, Write};
|
use std::io::{BufReader, Read, Write};
|
||||||
use std::num::NonZero;
|
use std::num::NonZero;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{absolute, Path, PathBuf};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use std::{fs, io};
|
use std::{fs, io};
|
||||||
use human_bytes::human_bytes;
|
use std::ffi::OsString;
|
||||||
|
|
||||||
mod logger;
|
|
||||||
mod options;
|
mod options;
|
||||||
mod scan_files;
|
mod scan_files;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
enum CompressionStatus {
|
enum CompressionStatus {
|
||||||
Success,
|
Success,
|
||||||
Skipped,
|
Skipped,
|
||||||
|
@ -101,7 +102,7 @@ fn main() {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let output_full_path = match compute_output_full_path(
|
let (output_directory, filename) = match compute_output_full_path(
|
||||||
output_directory.to_path_buf(),
|
output_directory.to_path_buf(),
|
||||||
input_file.to_path_buf(),
|
input_file.to_path_buf(),
|
||||||
base_path.to_path_buf(),
|
base_path.to_path_buf(),
|
||||||
|
@ -114,17 +115,48 @@ fn main() {
|
||||||
return compression_result;
|
return compression_result;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
if !output_directory.exists() {
|
||||||
|
match fs::create_dir_all(&output_directory) {
|
||||||
|
Ok(_) => {}
|
||||||
|
Err(_) => {
|
||||||
|
compression_result.message = "Error creating output directory".to_string();
|
||||||
|
return compression_result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let output_full_path = output_directory.join(filename);
|
||||||
|
|
||||||
if args.dry_run {
|
if args.dry_run {
|
||||||
compression_result.status = CompressionStatus::Success;
|
compression_result.status = CompressionStatus::Success;
|
||||||
return compression_result;
|
return compression_result;
|
||||||
};
|
};
|
||||||
|
|
||||||
let compression_parameters = build_compression_parameters(&args, input_file, needs_resize);
|
let mut compression_parameters = build_compression_parameters(&args, input_file, needs_resize);
|
||||||
|
let input_file_buffer = match read_file_to_vec(input_file) {
|
||||||
|
Ok(b) => b,
|
||||||
|
Err(_) => {
|
||||||
|
compression_result.message = "Error reading input file".to_string();
|
||||||
|
return compression_result;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let compression = if args.compression.max_size.is_some() {
|
||||||
|
compress_to_size_in_memory(
|
||||||
|
input_file_buffer,
|
||||||
|
&mut compression_parameters,
|
||||||
|
args.compression.max_size.unwrap() as usize,
|
||||||
|
true,
|
||||||
|
)
|
||||||
|
} else if args.format != OutputFormat::Original {
|
||||||
|
convert_in_memory(
|
||||||
|
input_file_buffer,
|
||||||
|
&compression_parameters,
|
||||||
|
map_supported_formats(args.format),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
compress_in_memory(input_file_buffer, &compression_parameters)
|
||||||
|
};
|
||||||
|
|
||||||
let compressed_image =
|
let compressed_image = match compression {
|
||||||
match compress_in_memory(read_file_to_vec(input_file).unwrap(), &compression_parameters) {
|
|
||||||
//TODO: handle error
|
|
||||||
Ok(v) => v,
|
Ok(v) => v,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
compression_result.message = format!("Error compressing file: {}", e);
|
compression_result.message = format!("Error compressing file: {}", e);
|
||||||
|
@ -136,7 +168,7 @@ fn main() {
|
||||||
|
|
||||||
if output_full_path.exists() {
|
if output_full_path.exists() {
|
||||||
match args.overwrite {
|
match args.overwrite {
|
||||||
OverwritePolicy::None => {
|
OverwritePolicy::Never => {
|
||||||
compression_result.status = CompressionStatus::Skipped;
|
compression_result.status = CompressionStatus::Skipped;
|
||||||
compression_result.compressed_size = original_file_size;
|
compression_result.compressed_size = original_file_size;
|
||||||
compression_result.message = "File already exists, skipped due overwrite policy".to_string();
|
compression_result.message = "File already exists, skipped due overwrite policy".to_string();
|
||||||
|
@ -207,7 +239,27 @@ fn write_recap_message(compression_results: &[CompressionResult], verbose: u8) {
|
||||||
match result.status {
|
match result.status {
|
||||||
CompressionStatus::Skipped => total_skipped += 1,
|
CompressionStatus::Skipped => total_skipped += 1,
|
||||||
CompressionStatus::Error => total_errors += 1,
|
CompressionStatus::Error => total_errors += 1,
|
||||||
_ => total_success += 1
|
_ => total_success += 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
if verbose > 1 {
|
||||||
|
if verbose < 3 && matches!(result.status, CompressionStatus::Success) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
println!(
|
||||||
|
"[{:?}] {} -> {}\n{} -> {} [{:.2}%]",
|
||||||
|
result.status,
|
||||||
|
result.original_path,
|
||||||
|
result.output_path,
|
||||||
|
human_bytes(result.original_size as f64),
|
||||||
|
human_bytes(result.compressed_size as f64),
|
||||||
|
(result.compressed_size as f64 - result.original_size as f64) * 100.0 / result.original_size as f64
|
||||||
|
);
|
||||||
|
|
||||||
|
if !result.message.is_empty() {
|
||||||
|
println!("{}", result.message);
|
||||||
|
}
|
||||||
|
println!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -215,16 +267,28 @@ fn write_recap_message(compression_results: &[CompressionResult], verbose: u8) {
|
||||||
let total_saved_percent = total_saved / total_original_size as f64 * 100.0;
|
let total_saved_percent = total_saved / total_original_size as f64 * 100.0;
|
||||||
|
|
||||||
if verbose > 0 {
|
if verbose > 0 {
|
||||||
println!("Total files: {}", total_files);
|
println!("Total files: {}\nSuccess: {}\nSkipped: {}\nErrors: {}\nOriginal size: {}\nCompressed size: {}\nSaved: {} ({:.2}%)",
|
||||||
println!("Total success: {}", total_success);
|
total_files,
|
||||||
println!("Total skipped: {}", total_skipped);
|
total_success,
|
||||||
println!("Total errors: {}", total_errors);
|
total_skipped,
|
||||||
println!("Total original size: {}", human_bytes(total_original_size as f64));
|
total_errors,
|
||||||
println!("Total compressed size: {}", human_bytes(total_compressed_size as f64));
|
human_bytes(total_original_size as f64),
|
||||||
println!("Total saved: {:.2} bytes ({:.2}%)", human_bytes(total_saved), total_saved_percent);
|
human_bytes(total_compressed_size as f64),
|
||||||
|
human_bytes(total_saved),
|
||||||
|
total_saved_percent * -1.0
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn map_supported_formats(format: OutputFormat) -> SupportedFileTypes {
|
||||||
|
match format {
|
||||||
|
OutputFormat::Jpeg => SupportedFileTypes::Jpeg,
|
||||||
|
OutputFormat::Png => SupportedFileTypes::Png,
|
||||||
|
OutputFormat::Webp => SupportedFileTypes::WebP,
|
||||||
|
OutputFormat::Tiff => SupportedFileTypes::Tiff,
|
||||||
|
_ => SupportedFileTypes::Unkn,
|
||||||
|
}
|
||||||
|
}
|
||||||
fn get_parallelism_count(requested_threads: u32, available_threads: usize) -> usize {
|
fn get_parallelism_count(requested_threads: u32, available_threads: usize) -> usize {
|
||||||
if requested_threads > 0 {
|
if requested_threads > 0 {
|
||||||
std::cmp::min(available_threads, requested_threads as usize)
|
std::cmp::min(available_threads, requested_threads as usize)
|
||||||
|
@ -293,7 +357,7 @@ fn compute_output_full_path(
|
||||||
base_directory: PathBuf,
|
base_directory: PathBuf,
|
||||||
keep_structure: bool,
|
keep_structure: bool,
|
||||||
suffix: &str,
|
suffix: &str,
|
||||||
) -> Option<PathBuf> {
|
) -> Option<(PathBuf, OsString)> {
|
||||||
let extension = input_file_path.extension().unwrap_or_default().to_os_string();
|
let extension = input_file_path.extension().unwrap_or_default().to_os_string();
|
||||||
let base_name = input_file_path.file_stem().unwrap_or_default().to_os_string();
|
let base_name = input_file_path.file_stem().unwrap_or_default().to_os_string();
|
||||||
let mut output_file_name = base_name;
|
let mut output_file_name = base_name;
|
||||||
|
@ -304,7 +368,7 @@ fn compute_output_full_path(
|
||||||
}
|
}
|
||||||
|
|
||||||
if keep_structure {
|
if keep_structure {
|
||||||
let parent = match input_file_path.parent()?.canonicalize() {
|
let parent = match absolute(input_file_path.parent()?) {
|
||||||
Ok(p) => p,
|
Ok(p) => p,
|
||||||
Err(_) => return None,
|
Err(_) => return None,
|
||||||
};
|
};
|
||||||
|
@ -314,11 +378,9 @@ fn compute_output_full_path(
|
||||||
Err(_) => return None,
|
Err(_) => return None,
|
||||||
};
|
};
|
||||||
let full_output_directory = output_directory.join(output_path_prefix);
|
let full_output_directory = output_directory.join(output_path_prefix);
|
||||||
fs::create_dir_all(&full_output_directory).ok()?; // TODO I don't like that the creation is done inside this function because the name is a bit obscure
|
Some((full_output_directory, output_file_name))
|
||||||
Some(full_output_directory.join(output_file_name))
|
|
||||||
} else {
|
} else {
|
||||||
fs::create_dir_all(&output_directory).ok()?; // TODO I don't like that the creation is done inside this function because the name is a bit obscure
|
Some((output_directory, output_file_name))
|
||||||
Some(output_directory.join(output_file_name))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -402,6 +464,7 @@ mod tests {
|
||||||
assert_eq!(result, 0);
|
assert_eq!(result, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(target_os = "windows"))]
|
||||||
#[test]
|
#[test]
|
||||||
fn test_compute_output_full_path() {
|
fn test_compute_output_full_path() {
|
||||||
let output_directory = PathBuf::from("/output");
|
let output_directory = PathBuf::from("/output");
|
||||||
|
@ -417,7 +480,7 @@ mod tests {
|
||||||
"_suffix",
|
"_suffix",
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert_eq!(result, Path::new("/output/folder/test_suffix.jpg"));
|
assert_eq!(result, (Path::new("/output/folder").to_path_buf(), "test_suffix.jpg".into()));
|
||||||
|
|
||||||
// Test case 2: keep_structure = false
|
// Test case 2: keep_structure = false
|
||||||
let result = compute_output_full_path(
|
let result = compute_output_full_path(
|
||||||
|
@ -428,7 +491,7 @@ mod tests {
|
||||||
"_suffix",
|
"_suffix",
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert_eq!(result, Path::new("/output/test_suffix.jpg"));
|
assert_eq!(result, (Path::new("/output").to_path_buf(), "test_suffix.jpg".into()));
|
||||||
|
|
||||||
// Test case 3: input file without extension
|
// Test case 3: input file without extension
|
||||||
let input_file_path = PathBuf::from("/base/folder/test");
|
let input_file_path = PathBuf::from("/base/folder/test");
|
||||||
|
@ -440,7 +503,7 @@ mod tests {
|
||||||
"_suffix",
|
"_suffix",
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert_eq!(result, Path::new("/output/test_suffix"));
|
assert_eq!(result, (Path::new("/output").to_path_buf(), "test_suffix".into()));
|
||||||
|
|
||||||
// Test case 4: input file with different base directory
|
// Test case 4: input file with different base directory
|
||||||
let input_file_path = PathBuf::from("/different_base/folder/test.jpg");
|
let input_file_path = PathBuf::from("/different_base/folder/test.jpg");
|
||||||
|
@ -452,6 +515,60 @@ mod tests {
|
||||||
"_suffix",
|
"_suffix",
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert_eq!(result, Path::new("/output/test_suffix.jpg"));
|
assert_eq!(result, (Path::new("/output").to_path_buf(), "test_suffix.jpg".into()));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
#[test]
|
||||||
|
fn test_compute_output_full_path() {
|
||||||
|
let output_directory = PathBuf::from(r"C:\output");
|
||||||
|
let base_directory = PathBuf::from(r"C:\base");
|
||||||
|
|
||||||
|
// Test case 1: keep_structure = true
|
||||||
|
let input_file_path = PathBuf::from(r"C:\base\folder\test.jpg");
|
||||||
|
let result = compute_output_full_path(
|
||||||
|
output_directory.clone(),
|
||||||
|
input_file_path.clone(),
|
||||||
|
base_directory.clone(),
|
||||||
|
true,
|
||||||
|
"_suffix",
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
assert_eq!(result, (Path::new(r"C:\output\folder").to_path_buf(), "test_suffix.jpg".into()));
|
||||||
|
|
||||||
|
// Test case 2: keep_structure = false
|
||||||
|
let result = compute_output_full_path(
|
||||||
|
output_directory.clone(),
|
||||||
|
input_file_path.clone(),
|
||||||
|
base_directory.clone(),
|
||||||
|
false,
|
||||||
|
"_suffix",
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
assert_eq!(result, (Path::new(r"C:\output").to_path_buf(), "test_suffix.jpg".into()));
|
||||||
|
|
||||||
|
// Test case 3: input file without extension
|
||||||
|
let input_file_path = PathBuf::from(r"C:\base\folder\test");
|
||||||
|
let result = compute_output_full_path(
|
||||||
|
output_directory.clone(),
|
||||||
|
input_file_path.clone(),
|
||||||
|
base_directory.clone(),
|
||||||
|
false,
|
||||||
|
"_suffix",
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
assert_eq!(result, (Path::new(r"C:\output").to_path_buf(), "test_suffix".into()));
|
||||||
|
|
||||||
|
// Test case 4: input file with different base directory
|
||||||
|
let input_file_path = PathBuf::from(r"C:\different_base\folder\test.jpg");
|
||||||
|
let result = compute_output_full_path(
|
||||||
|
output_directory.clone(),
|
||||||
|
input_file_path.clone(),
|
||||||
|
base_directory.clone(),
|
||||||
|
false,
|
||||||
|
"_suffix",
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
assert_eq!(result, (Path::new(r"C:\output").to_path_buf(), "test_suffix.jpg".into()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,11 +6,20 @@ pub enum OverwritePolicy {
|
||||||
/// Always overwrite
|
/// Always overwrite
|
||||||
All,
|
All,
|
||||||
/// Never overwrite
|
/// Never overwrite
|
||||||
None,
|
Never,
|
||||||
/// Overwrite only if the file to be overwritten is bigger
|
/// Overwrite only if the file to be overwritten is bigger
|
||||||
Bigger
|
Bigger
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ValueEnum, Debug)]
|
||||||
|
pub enum OutputFormat {
|
||||||
|
Jpeg,
|
||||||
|
Png,
|
||||||
|
Webp,
|
||||||
|
Tiff,
|
||||||
|
Original,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Parser, Debug)]
|
#[derive(Parser, Debug)]
|
||||||
#[command(version, about, long_about = None)]
|
#[command(version, about, long_about = None)]
|
||||||
pub struct CommandLineArgs {
|
pub struct CommandLineArgs {
|
||||||
|
@ -23,6 +32,10 @@ pub struct CommandLineArgs {
|
||||||
#[command(flatten)]
|
#[command(flatten)]
|
||||||
pub output_destination: OutputDestination,
|
pub output_destination: OutputDestination,
|
||||||
|
|
||||||
|
/// convert to the selected output format, or keep the original
|
||||||
|
#[arg(long, value_enum, default_value = "original")]
|
||||||
|
pub format: OutputFormat,
|
||||||
|
|
||||||
/// select level for PNG optimization, between [0-6]
|
/// select level for PNG optimization, between [0-6]
|
||||||
#[arg(long, default_value = "3")]
|
#[arg(long, default_value = "3")]
|
||||||
pub png_opt_level: u8,
|
pub png_opt_level: u8,
|
||||||
|
@ -59,14 +72,14 @@ pub struct CommandLineArgs {
|
||||||
#[arg(long, default_value = "0")]
|
#[arg(long, default_value = "0")]
|
||||||
pub threads: u32,
|
pub threads: u32,
|
||||||
|
|
||||||
/// suppress all output
|
|
||||||
#[arg(short = 'Q', long, group = "verbosity")]
|
|
||||||
pub quiet: bool,
|
|
||||||
|
|
||||||
/// overwrite policy
|
/// overwrite policy
|
||||||
#[arg(short = 'O', long, value_enum, default_value = "all")]
|
#[arg(short = 'O', long, value_enum, default_value = "all")]
|
||||||
pub overwrite: OverwritePolicy,
|
pub overwrite: OverwritePolicy,
|
||||||
|
|
||||||
|
/// suppress all output
|
||||||
|
#[arg(short = 'Q', long, group = "verbosity")]
|
||||||
|
pub quiet: bool,
|
||||||
|
|
||||||
/// select how much output you want to see, 0 is equal to -Q, --quiet
|
/// select how much output you want to see, 0 is equal to -Q, --quiet
|
||||||
#[arg(long, default_value = "1", group = "verbosity")]
|
#[arg(long, default_value = "1", group = "verbosity")]
|
||||||
pub verbose: u8,
|
pub verbose: u8,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{absolute, Path, PathBuf};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use indicatif::{ProgressBar, ProgressDrawTarget, ProgressIterator};
|
use indicatif::{ProgressBar, ProgressDrawTarget, ProgressIterator};
|
||||||
|
@ -16,10 +16,7 @@ fn is_filetype_supported(path: &Path) -> bool {
|
||||||
|
|
||||||
pub fn get_file_mime_type(path: &Path) -> Option<String> {
|
pub fn get_file_mime_type(path: &Path) -> Option<String> {
|
||||||
match infer::get_from_path(path) {
|
match infer::get_from_path(path) {
|
||||||
Ok(v) => match v {
|
Ok(v) => v.map(|ft| ft.mime_type().to_string()),
|
||||||
None => None,
|
|
||||||
Some(ft) => Some(ft.mime_type().to_string()),
|
|
||||||
},
|
|
||||||
Err(_) => None,
|
Err(_) => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,7 +25,7 @@ fn is_valid(entry: &Path) -> bool {
|
||||||
entry.exists() && entry.is_file() && is_filetype_supported(entry)
|
entry.exists() && entry.is_file() && is_filetype_supported(entry)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn scan_files(args: &Vec<String>, recursive: bool, quiet: bool) -> (PathBuf, Vec<PathBuf>) {
|
pub fn scan_files(args: &[String], recursive: bool, quiet: bool) -> (PathBuf, Vec<PathBuf>) {
|
||||||
if args.is_empty() {
|
if args.is_empty() {
|
||||||
return (PathBuf::new(), vec![]);
|
return (PathBuf::new(), vec![]);
|
||||||
}
|
}
|
||||||
|
@ -37,7 +34,7 @@ pub fn scan_files(args: &Vec<String>, recursive: bool, quiet: bool) -> (PathBuf,
|
||||||
|
|
||||||
let progress_bar = init_progress_bar(quiet);
|
let progress_bar = init_progress_bar(quiet);
|
||||||
|
|
||||||
for path in args.into_iter().progress_with(progress_bar) {
|
for path in args.iter().progress_with(progress_bar) {
|
||||||
let input = PathBuf::from(path);
|
let input = PathBuf::from(path);
|
||||||
if input.exists() && input.is_dir() {
|
if input.exists() && input.is_dir() {
|
||||||
let mut walk_dir = WalkDir::new(input);
|
let mut walk_dir = WalkDir::new(input);
|
||||||
|
@ -59,7 +56,7 @@ pub fn scan_files(args: &Vec<String>, recursive: bool, quiet: bool) -> (PathBuf,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn canonicalize_and_push(path: &Path, mut base_path: PathBuf, files: &mut Vec<PathBuf>) -> PathBuf {
|
fn canonicalize_and_push(path: &Path, mut base_path: PathBuf, files: &mut Vec<PathBuf>) -> PathBuf {
|
||||||
if let Ok(ap) = path.canonicalize() {
|
if let Ok(ap) = absolute(path) {
|
||||||
base_path = compute_base_folder(&base_path, &ap);
|
base_path = compute_base_folder(&base_path, &ap);
|
||||||
files.push(ap);
|
files.push(ap);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue